MCP and API

Chat with Claude or ChatGPT, or send a prompt from your own code. Everything you make also shows up in Easymotion Studio.

Last updated: October 8, 2026

MCP

Connect Easymotion to Claude or ChatGPT and make motion graphics by chatting. Ask for an animated chart, a map, a logo reveal or a UI animation, then change it in plain words.

  • Make a new motion from a prompt, or start from a ready-made template.
  • Change it as many times as you like: new text, colours, numbers, timing.
  • Add files: images, logos, data, PDFs.
  • See a preview of each version right in the chat, and get a video file when you ask for it.

Connecting is part of the paid plans. Anyone can read this guide. Easymotion uses an open standard called MCP (Model Context Protocol), so you add it like any other connector.

The Easymotion connector URL is:

url
https://studio-be.easymotion.io/mcp

Connect Claude

  1. In claude.ai or the Claude desktop app, go to Customize → Connectors.
  2. Click +, then Add custom connector. Name it Easymotion and paste the connector URL above.
  3. Click Add, then Connect. Sign in with your Easymotion account and click Allow.
  4. In a chat, make sure Easymotion is turned on (the + button → Connectors), then ask Claude to make a motion.

On a Claude Team or Enterprise plan, an owner adds the connector in Organization settings → Connectors. Then each person clicks Connect and signs in with their own Easymotion account.

Claude Code

bash
claude mcp add --transport http easymotion https://studio-be.easymotion.io/mcp

Then run /mcp in Claude Code and choose Easymotion to sign in.

Connect ChatGPT

  1. In ChatGPT on the web, open Settings and turn on Developer mode.
  2. Go to Plugins, click +, then Add custom MCP server.
  3. Name it Easymotion, paste the connector URL above, and choose OAuth.
  4. Click I understand and want to continue, then Create as a plugin. Sign in with your Easymotion account and click Allow.
  5. In a chat, type @Easymotion and ask for a motion.

Custom connectors need a paid ChatGPT plan and work on chatgpt.com, not the mobile app. On Business and Enterprise, an admin may need to allow developer mode. ChatGPT changes its menus often; if a step looks different, search ChatGPT's help for "custom MCP server".

Other apps

Any app that supports remote MCP servers with sign-in (OAuth) can use the same connector URL — for example Cursor, VS Code or Codex. Add a remote or HTTP MCP server with the URL above and sign in with your Easymotion account when the app asks.

What to ask

Talk to it like you would in Studio. Some examples:

  • "Make a 9:16 animated bar chart of our Q3 revenue: EU 40, US 35, APAC 25."
  • "Find a template for a product launch and change the headline to 'Meet Nova'."
  • "Make the bars blue and the animation slower."
  • "Animate our logo" — and share the logo file or link.
  • "Export it as a 4K MP4" when you are happy with it.

Sometimes Easymotion asks a question first, for example which years a chart should show. Just answer in the chat. Questions use no credits.

Adding files

AppHow to add a file
ChatGPTAttach the image or file to your message. ChatGPT passes it to Easymotion.
ClaudeShare a public link to the file, or ask Claude for an upload link, open it, and pick the file. Claude can't pass files from the chat to connectors yet.
Claude Code, Cursor, CodexPoint to the file on your computer. The app uploads it.
Any appPaste small CSV data or SVG logo code straight into the chat.

Say how to use an image: as a style to copy, or as a picture to place in the motion (like your logo). Your plan's file limits are the same as in Studio.

Previews and video files

Writing a motion takes 2–4 minutes. When it is ready, you get a storyboard image in the chat: six frames from the animation, so you (and the AI) can see it without waiting for a video. Watch the full animation with the Studio link.

Video files are rendered only when you ask, because rendering takes 1–3 minutes. Ask for MP4, MOV or GIF; you get a download link that keeps working (MOV files are deleted after 14 days). 4K and 60 fps need Plus or Pro.

Credits and limits

  • Making or changing a motion with a prompt uses credits, the same as in Studio.
  • Starting from a template, quick changes to text, colours, numbers and fonts, and video files use no credits.
  • Up to 2 motions generating at once, and up to 30 generations per hour (shared with the API).

Disconnect

Remove or disconnect Easymotion in the app's connector or plugin settings. Your motions stay in Easymotion Studio.

API

The Easymotion API makes motion graphics videos from a prompt. You send a prompt, Easymotion writes the motion, then renders it as a video file. This takes a few minutes, so you start a generation, check on it, and download the video when it is ready.

  • Base URL: https://studio-be.easymotion.io/v1
  • Requests and responses are JSON.
  • Generations use your Easymotion credits, the same as in Studio. Rendering the video costs no extra credits.

Get an API key

The API is part of the paid plans. Anyone can read these docs.

  1. Open Easymotion Studio.
  2. Click your profile picture, then MCP / API.
  3. Open the API tab and click Create key. Give it a name you will recognise, like the app that will use it.
  4. Copy the key. It is shown only once.

Keep your key secret, like a password: anyone who has it can use your credits. Call the API from your server, never from a website or app that runs in the browser. You can have up to 5 keys. Delete a key in the same place; it stops working within a minute.

Authentication

Send your key in the Authorization header with every request:

http
Authorization: Bearer em_live_…

If your tool can't set that header, send X-API-Key: em_live_… instead. You can also send X-EM-Email with your account email. When you do, a request whose email does not match the key's account is refused.

Quick start

1. Create a generation. It answers in a few seconds with an id.

curl
curl -X POST https://studio-be.easymotion.io/v1/generations \
  -H "Authorization: Bearer $EASYMOTION_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Bar chart of Q3 revenue: EU 40, US 35, APAC 25", "aspect_ratio": "16:9"}'

2. Check it every 10–15 seconds until status is completed. Writing the motion takes 2–4 minutes, then the video renders for 1–3 minutes.

curl
curl https://studio-be.easymotion.io/v1/generations/gen_… \
  -H "Authorization: Bearer $EASYMOTION_API_KEY"

3. Download the video. video.url in the response works for one hour. This link always works with your key:

curl
curl -L -o motion.mp4 https://studio-be.easymotion.io/v1/generations/gen_…/video \
  -H "Authorization: Bearer $EASYMOTION_API_KEY"

The same in JavaScript (Node.js 18 or newer)

javascript
const API = "https://studio-be.easymotion.io/v1";
const headers = {
  Authorization: `Bearer ${process.env.EASYMOTION_API_KEY}`,
  "Content-Type": "application/json",
};

// 1. Start a generation
let generation = await fetch(`${API}/generations`, {
  method: "POST",
  headers,
  body: JSON.stringify({ prompt: "Bar chart of Q3 revenue: EU 40, US 35, APAC 25" }),
}).then((res) => res.json());
if (!generation.id) throw new Error(generation.error.message);

// 2. Check every 15 seconds until it is done
while (["generating", "rendering"].includes(generation.status)) {
  await new Promise((resolve) => setTimeout(resolve, 15000));
  generation = await fetch(`${API}/generations/${generation.id}`, { headers }).then((res) => res.json());
}

// 3. Use the result
if (generation.status === "completed") console.log(generation.video.url);
else console.log(generation.status, generation.question || generation.error);

Statuses

Every generation has one of these statuses:

StatusMeaning
generatingEasymotion is writing the motion. progress shows how far it is.
needs_inputEasymotion asked a question (question). No credits were used. See Change a motion or answer a question.
renderingThe motion is ready and the video file is rendering.
completedThe video is ready in video. With "export": false, the motion is ready in Studio and there is no file.
failedSee error.code and error.message. Credits held for a failed generation are returned.

Create a generation

POST /generations

FieldTypeWhat it does
promptstring, requiredWhat to make, or what to change. Up to 2,000 characters. Put data in attachments, not in the prompt.
session_idstringContinue an earlier motion, or answer its question. Leave it out for a new motion.
aspect_ratio16:9 9:16 1:1 4:5Default 16:9 for new motions. Follow-ups keep the motion's shape unless you set it.
exportobject or falseThe video file to render. Default {"format": "mp4", "fps": 30, "resolution": "fhd"}. Formats mp4 mov gif, fps 30 60, resolution fhd 4k (4K and 60 fps need Plus or Pro). false makes the motion without a video file.
attachmentsarrayUp to 6 files: images, logos, data, PDFs, video references. See Attachments.
metadataobjectUp to 20 of your own text values, for example your order ID. Returned as they are.

Example request

json
{
  "prompt": "Bar chart of Q3 revenue: EU 40, US 35, APAC 25",
  "aspect_ratio": "9:16",
  "export": { "format": "mp4", "fps": 30, "resolution": "fhd" },
  "metadata": { "order_id": "A-1042" }
}

Example response

json
{
  "id": "gen_6f1c2a9b8e7d4c3b2a1f0e9d",
  "object": "generation",
  "status": "generating",
  "session_id": "6702f1c2a9b8e7d4c3b2a1f0",
  "version": null,
  "title": "Q3 revenue by region",
  "prompt": "Bar chart of Q3 revenue: EU 40, US 35, APAC 25",
  "aspect_ratio": "9:16",
  "export": { "format": "mp4", "fps": 30, "resolution": "fhd" },
  "studio_url": "https://studio.easymotion.io/s/6702f1c2a9b8e7d4c3b2a1f0",
  "progress": { "phase": "generating", "percent": 35, "message": "Generating motion...", "estimated_seconds": 180 },
  "metadata": { "order_id": "A-1042" },
  "created_at": "2026-10-08T10:00:00.000Z",
  "updated_at": "2026-10-08T10:00:04.000Z",
  "completed_at": null
}

Attachments

Add up to 6 files to a generation. Each attachment has one of these:

FieldWhat it is
urlA public link to the file.
data_base64The file itself, base64-encoded. Also send filename and content_type. Up to 25 MB.
csvCSV text for a chart or table, up to 200 KB.
svgSVG markup of a logo or icon, up to 512 KB.

Tell Easymotion how to use a file with use_as:

use_asMeaning
style_referenceCopy the look of this image.
image_assetPlace this image in the motion. Add a description, like "our logo, top-left".
logo_svgAnimate this SVG logo.
dataUse this sheet (CSV or XLSX) as chart data.
documentUse this PDF as a brief.
video_referenceCopy the motion style of this clip. Needs duration_seconds (60 or less).

PNG, JPG and WebP images need use_as. For other files it is worked out from the file type. Your plan's file limits are the same as in Studio.

json
{
  "prompt": "Animated sales report in our brand style, our logo top-left",
  "attachments": [
    { "url": "https://example.com/brand-style.png", "use_as": "style_reference" },
    { "url": "https://example.com/logo.png", "use_as": "image_asset", "description": "our logo" },
    { "csv": "month,sales\nJan,120\nFeb,180\nMar,240" }
  ]
}

Change a motion or answer a question

Each generation is one message in a motion's conversation, like a chat message in Studio. To change a motion, create a new generation with its session_id and the change as the prompt. You get a new version and a new video. Earlier versions stay in Studio.

json
{
  "session_id": "6702f1c2a9b8e7d4c3b2a1f0",
  "prompt": "Make the bars blue and the animation slower"
}

When the status is needs_input, Easymotion asked a question instead of making the motion — for example, which years a chart should show. No credits were used. Answer the same way: a new generation with the same session_id and your answer as the prompt.

Get a generation

GET /generations/{id} returns the generation. When status is completed, it has a video:

json
"video": {
  "format": "mp4",
  "fps": 30,
  "resolution": "fhd",
  "url": "https://…",
  "url_expires_at": "2026-10-08T11:05:00.000Z",
  "download_url": "https://studio-be.easymotion.io/v1/generations/gen_6f1c2a9b8e7d4c3b2a1f0e9d/video",
  "file_size_bytes": 4823910,
  "duration_seconds": 12.5
}
FieldMeaning
urlDownload link for the file. Works for one hour (url_expires_at).
download_urlA stable link. With your key it redirects to a fresh download link, so you can store it. It works for 90 days after the generation was created.
deleted_afterMOV files only: when the file is deleted. MP4 and GIF files are kept.

GET /generations/{id}/video is the same as download_url: it redirects to the file. Use curl -L or follow redirects in your HTTP client.

Other endpoints

EndpointWhat it does
GET /generationsYour generations, newest first. limit (up to 100), before, session_id.
GET /accountYour plan, credits left, generations running, and plan limits.

For the next page of a list, pass the created_at of the last item as before. Lists don't include download links; get one generation for those.

Errors

Errors use normal HTTP status codes and this shape:

json
{ "error": { "code": "INSUFFICIENT_CREDITS", "message": "Not enough credits for this motion." } }
StatusCodeWhat to do
400INVALID_REQUEST, INVALID_JSONFix the request. error.details lists each field.
401INVALID_API_KEYCheck the key. It may have been deleted.
402INSUFFICIENT_CREDITSAdd credits or upgrade your plan.
403PAID_PLAN_REQUIRED, PLAN_EXPORT_UPGRADE_REQUIREDYour plan doesn't include this. Upgrade on the pricing page.
404NOT_FOUNDThe generation or session_id is not in your account.
409ALREADY_GENERATING, NOT_READYWait for the motion's current generation, or for the video to finish.
422ATTACHMENT_FAILED, IDEMPOTENCY_KEY_REUSEDA file could not be used (error.details says why; nothing was generated and no files were kept), or the Idempotency-Key was already used with a different body.
429TOO_MANY_IN_FLIGHT, RATE_LIMITEDWait and try again. Retry-After says how many seconds.

Limits and retries

  • Up to 3 generations running at once.
  • Up to 30 generations and 3,600 other requests per hour. These limits are shared with Claude and ChatGPT.
  • Prompts up to 2,000 characters, up to 6 attachments, files up to 25 MB.

Safe retries: send an Idempotency-Key header with a unique value, like your order ID. If the same key comes again with the same body, you get the first generation back instead of a new one, so a retry after a timeout never charges you twice. Reusing a key with a different body returns 422 IDEMPOTENCY_KEY_REUSED. If a request fails (for example a file is rejected), none of its files are kept, so you can fix it and send it again.

OpenAPI

A machine-readable description of the API is at https://studio-be.easymotion.io/v1/openapi.json. Import it into Postman or Insomnia, or give it to an AI coding assistant.

Prefer chatting? Connect Claude or ChatGPT with the same account.