# DevReel > DevReel turns code into short animated videos. A video is a script: a list of code steps, and each step animates in from the one before it. AI agents make them through an MCP server or a plain HTTP API; cloud renders use the account's credits. People can make the same videos by hand at https://devreel.dev/editor, where browser export is free. ## Connect - MCP server: `https://devreel.dev/mcp` (Streamable HTTP, no sessions; MCP 2026-07-28 and 2025-03-26 to 2025-11-25). Every request needs a sign-in or an API key. - With sign-in (no key to copy): add `https://devreel.dev/mcp` as a custom connector in claude.ai or ChatGPT, or run `claude mcp add --transport http devreel https://devreel.dev/mcp` in Claude Code. The app opens a DevReel page where the account owner chooses Allow. DevReel is an OAuth 2.1 server for this (PKCE S256, client metadata documents or dynamic registration); discovery starts at `https://devreel.dev/.well-known/oauth-protected-resource/mcp`. - With an API key: get one at https://devreel.dev/dashboard/api (any plan). It starts with `fk_live_` and is shown once. Send it as a header: `Authorization: Bearer fk_live_...` - Claude Code: `claude mcp add --transport http devreel https://devreel.dev/mcp --header "Authorization: Bearer fk_live_..."` - Cursor (`.cursor/mcp.json` or `~/.cursor/mcp.json`): `{"mcpServers":{"devreel":{"url":"https://devreel.dev/mcp","headers":{"Authorization":"Bearer fk_live_..."}}}}` - Programs without MCP use the HTTP API below with a key. ## Tools - `list_options`: every allowed value, the limits, the defaults, what credits cost and a complete example. Free. Call it once before the first script. - `check_script`: checks a script without rendering it. Returns every problem, or the video's length, text size and exact credit cost. Free, instant, and counted toward no limit. - `release_script`: turns a software release into a ready launch-video script. Give `url` (a public GitHub release or repository; a repository alone means its latest release), or `notes` (the release notes as a markdown list) with `name` and `version`. Optional: `shape`, `look` (midnight, neon, ocean), `install` (a command for its own card) and `link`. Free, renders nothing, and the script comes back already checked. Pass it to `make_video` as it is, or edit it first. - `preview`: renders one step as a 720p still and returns the picture. Costs 0.125 credit and counts as one render toward the daily limits. `step` picks the step (0 is the first); by default it shows the step with the most lines. - `make_video`: renders an MP4 or GIF, waits up to about 50 seconds, and returns a link to watch it and a link to the file. If it is still rendering, call `video_status` with its id. - `video_status`: status and links for a render. A bad script comes back listing its problems (up to 20 at once) with fixes, for example `steps[0].animation: "morf" is not an animation. Did you mean "morph"?`. Fix the script and try again. ## Workflow 1. Call `list_options` once. 2. Write the script. 3. Call `check_script` until it says the script is valid. It is free. 4. If the look matters, call `preview` on the busiest step to see colours and spacing. 5. Call `make_video`, then give the user the watch link. For a release or changelog video, skip steps 2 and 3: call `release_script`, then `make_video` with the script it returns. ## A script ```json { "shape": "16:9", "theme": "dracula", "language": "typescript", "windowTitle": "retry.ts", "background": { "type": "gradient", "colors": ["#0f172a", "#312e81"], "angle": 135 }, "steps": [ { "code": "async function load(url: string) {\n return fetch(url);\n}", "seconds": 1.5 }, { "code": "async function load(url: string, tries = 3) {\n for (let i = 0; i < tries; i++) {\n const res = await fetch(url);\n if (res.ok) return res;\n }\n throw new Error(`Failed after ${tries} tries`);\n}", "animation": "morph", "animationSeconds": 0.8, "seconds": 3 } ] } ``` Only `steps` is required. Everything else has a default: - `steps[]`: 1 to 40 steps. Each is `{ code, seconds, animation, animationSeconds, language, theme }`, or just a string of code. - `code`: the code on screen in this step. `""` gives an empty window, handy before typing code in. Tabs become two spaces. - `seconds`: how long the step stays on screen once it has arrived, 0.5 to 25. Default 2. - `animation`: how this step arrives from the step before it. Default `morph`; `instant` is a hard cut. Ignored on the first step unless the video loops. - `animationSeconds`: how long the arrival takes, 0.1 to 5. Default 0.5. - `language`, `theme`: this step only, for example the same idea in two languages. - `shape`: `16:9` (default), `1:1` or `9:16`. - `theme`: vsDark (default), dracula, monokai, atomDark, nightOwlLight, duotoneLight, oceanicNext, shadesOfPurple, synthwave84. (`githubDark` is refused for now: its plain code comes out dark grey on a black window.) - `language`: javascript (default), typescript, jsx, tsx, python, rust, go, sql, html, css, json, java, cpp, bash, markdown. - `window`: macos (default), chrome, glass, terminal, blueprint, brutalist, none. `corners`: rounded or sharp. `windowTitle`: the title bar text, usually a file name. - `font`: Fira Code (default) and 35 more monospace fonts (see `list_options`). `fontWeight`: 300 to 700. - `fontSize`: leave it out. DevReel picks the largest size up to 32 that fits the biggest step and sizes the window around the code. A step too big to read is refused with the limit for its shape. - `lineHeight` (default 1.5), `padding` (default 24), `lineNumbers` (default true). - `background`: a hex colour, or `{ "type": "gradient", "colors", "angle", "style": "linear" | "radial" }`, `{ "type": "pattern", "pattern", "color", "backgroundColor", "opacity", "scale" }` or `{ "type": "shader", "shader", "colors", "speed", "intensity" }`. The default is the moving `gradient-mesh` shader. - `loop`: the last step animates back into the first. Default false. - `format`: `mp4` (default) or `gif`. `resolution`: `720p`, `1080p` (default) or `2160p`. `fps`: default 30, GIF 15. - Limits: 60 seconds in total (steps plus animations), 5,000 characters and 200 lines per step. - Characters: the video fonts draw Latin letters, digits, keyboard symbols and common punctuation (curly quotes, dashes, bullets, the up and down arrows, the euro sign). Anything else, such as emoji, check marks, box drawing, Greek letters or side arrows, is refused because it would show as an empty box. Write `->` and `OK` instead. ## What makes a good DevReel - One idea per step. Add a line, rename a variable, wrap code in a function. The viewer should see exactly what changed. - Build up. Start small, or with an empty first step and the `type` animation, and end on the finished code. - Give the last step 3 to 4 seconds so people can read it. A small change needs 1 to 1.5 seconds, a new block 2 to 3. - Keep steps small enough to read: about 15 lines of up to 60 characters on 16:9, 12 lines of 40 on 1:1, and 22 lines of 35 on 9:16. DevReel fits the text, but more code means smaller text. - Pick animations by what changed: - `morph` (default): unchanged code stays or glides to its new place and new code fades in. Best when most of the code stays. - For a complete rewrite, use `fade`, `blur`, `dissolve` or `reveal`. With `morph`, the letters of a rewrite fly across each other halfway through. - `type`: new code writes itself out left to right. Give it 1 to 1.6 seconds. - Calm arrivals: `fade`, `focus`, `reveal`. Directional ones: `rise`, `slide`, `flow`, `wipe`, `sweep`. - Loud ones for a single punchline: `glitch`, `matrix`, `scatter`, `split`, `pop`. Once per video is plenty. - `list_options` has all 46. - Choose the shape for where it will be posted: `16:9` for YouTube, docs and slides; `1:1` for X and LinkedIn feeds; `9:16` for Reels, TikTok and Shorts. Use `gif` with `loop: true` for READMEs and chat. A GIF uses 9 render units and an MP4 1, so make a GIF only when one is wanted. - A file name in `windowTitle` makes it feel real. - Dark themes suit most videos. With `nightOwlLight` or `duotoneLight`, use a light background such as `"#e2e8f0"`. - Two dark gradient colours at a 135 angle is a safe background. Shaders move, and patterns work best at low opacity. ## HTTP API Base URL `https://devreel.dev/api/v1`. Send the key as `Authorization: Bearer fk_live_...`. - `GET /options`: the same content as `list_options`. No key needed. - `POST /check`: body is a script as JSON. Returns `{ "valid": false, "problems": [...] }` or `{ "valid": true, "video": { durationSeconds, fontSize, credits, previewCredits, ... } }`. No key needed, nothing is rendered. - `POST /release-script`: body is `{ "url" }` or `{ "notes", "name", "version" }`, plus optional `shape`, `look`, `install` and `link`. Returns `{ script, summary, check }`: a checked script for a launch video of that release, ready for `POST /renders`. No key needed, nothing is rendered. People can do the same at https://devreel.dev/release. - `POST /renders`: body is a script as JSON. Returns `202 { render, credits }`. Add an `Idempotency-Key` header (up to 200 characters) to retry safely: the same key with the same script returns the same render instead of charging twice. - `GET /renders/{id}`: `{ render }`. Poll every few seconds until `status` is `succeeded`, `failed` or `canceled`. Other statuses are `queued`, `running` and `processing`. - `GET /renders/{id}/output`: the file, with the same key. - `POST /renders/{id}/cancel`: cancels a render that has not finished. A render looks like `{ id, status, format, resolution, fps, durationSeconds, credits, createdAt, completedAt, downloadUrl, downloadExpiresAt, pageUrl, failureReason }`. `pageUrl` opens it in DevReel, where the owner can watch and download it. Errors look like `{ "error": { "code", "message", "retryable", "details" } }`. `invalid_script` lists the problems in `details`. Other codes include `missing_api_key`, `invalid_api_key`, `insufficient_credits`, `render_in_progress`, `api_render_limit` and `rate_limited` (both with a `retry-after` header), `api_capacity_reached`, `idempotency_conflict`, `not_ready` and `expired`. ## Credits and limits - 1 credit renders 1 minute of 1080p video at 30 fps. 720p costs half, 2160p four times, and frame rates above 30 up to twice as much. - Every render rounds up to the next 15 seconds, so a 10-second 1080p video costs 0.25 credit and a preview costs 0.125. - One cloud render at a time per account. - Renders through the API or an AI tool are counted in render units: a video or a preview uses 1, a GIF 9. Each account gets 10 units in any 24 hours, and all of them together share a monthly slice of DevReel's cloud capacity. The error says when the render can start. `check_script` is never limited. - The account's plan also limits cloud renders per rolling 24 hours: 3 on Free, 50 on Plus, 200 on Pro, 1,000 on Studio. On Free, use `check_script` instead of `preview`. - Plans and credit packs: https://devreel.dev/#pricing