---
title: Use Claude Motion with invideo
description: Bring a Claude Motion animation into invideo as an MP4, then cut it with footage, a voice and music on a timeline your agent edits.
---
It depends on what the video needs. Claude Motion makes short animations inside Claude from text, charts, shapes and images, and each animation is code, so you change one word, number or timing and the rest stays. invideo adds the video around the animation: real footage, a voiceover, music, captions, and a timeline where your agent and you edit together.

Make the chart or the animated explainer in Claude Motion. Build the video that holds it in invideo.

## When to use both

Use both when the animation is one part of a longer video. Common cases:

- **A launch or release video.** An animated chart sits between product footage and a closing card.
- **A narrated explainer.** The animation needs a voiceover, music and captions.
- **A report for a team.** The numbers animate in Claude Motion, and the video goes to a team with the speaker on camera.
- **Many cuts from one animation.** One animation goes into a 16:9 video and a 9:16 short, one branch each.

## Hand-off: from Claude Motion into invideo

In Claude, open the animation, click **Export** and choose **MP4**. That file is what crosses into invideo. Your agent brings it in one of two ways.

**With `add_media`.** This works for any agent that holds the MP4:

- **A public link.** `add_media` with `media_url`.
- **A file on your computer.** `start_upload` with the `file_name`, a PUT of the bytes to the `upload_url`, then `add_media` with the `upload_id`. In a terminal, `invideo asset upload <project-url> <file>`.
- **A file in a chat app.** You drag the file into the chat. It arrives through `file` on `add_media`.

Each file becomes a sequence in the project, with its own sequence URL. On a timeline's URL, `add_media` also puts it in that timeline's media bin.

**With `import-claude-motion-from-url`.** This is the official hand-off that Anthropic built with invideo: when you send a Claude Motion animation to invideo from Claude, Claude calls this tool on the invideo MCP server. It takes these fields:

- **`url`**: the MP4's URL. It expires fast, so the server fetches it at once.
- **`download_token`**: the access token for the file, given apart from the URL. The caller passes it through as it is.
- **`title`**: a suggested title for the imported video. Optional.
- **`claude_design_project_id`**: a stable id for the video, the same on every re-send. Send it again with the same id to update an import instead of making a new one. Optional.

The tool takes no project URL; Claude fills the fields itself. You do not call it by hand. When your agent has the MP4 file itself, use `add_media`.

Then the agent builds the video around the animation:

- **Footage.** Your clips through `add_media`, or stock from `search_library` in `stock_video`.
- **Voice.** `elevenlabs_text_to_speech.elevenlabs_tts_v4` with `generate`, with a voice from `search_library`.
- **Music.** `search_library` in `stock_music`.
- **Captions.** `media` `audio.transcript` on the voice, then `add_captions`.

## Hand-off: from invideo to Claude Motion

Claude Motion makes animations from what you give Claude: text, charts, shapes and images. To use a frame from your invideo video there, your agent runs `export` with `format` `video`, `mode` `image` and `still_at`. You add that image to Claude.

To change the animation itself, change it in Claude Motion, export a new MP4, and bring it in again. The agent swaps it in with `place_media` and `mode` `replace`, so the clip keeps its place and length.

## Steps

Edits and exports are free. Generation and transcripts cost credits. Paid stock costs a small credit charge, or one of your workspace's iStock licenses. Your agent runs a dry run first and tells you the price before it spends anything.

Your agent runs a dry run first. For any call that costs 1 credit or more, it tells you the price and waits for your yes. A call under 1 credit runs without asking, and your agent tells you what it cost.

<Steps>
<Step title="Bring the animation in">
The agent calls `add_media` with the MP4. Expected result: a sequence URL for the animation.
</Step>
<Step title="Make a timeline on a branch">
The agent calls `new_timeline`, then makes a branch with `timeline_history`. Expected result: a timeline URL on a branch.
</Step>
<Step title="Place footage and the animation">
The agent calls `edit_timeline` with `place_media` for each clip and the animation. Expected result: a new `state_token`.
</Step>
<Step title="Pick and price the voice">
The agent runs `find_models` with the voice-over in words, picks one, and reads its inputs with `get_model`. A good pick is `elevenlabs_text_to_speech.elevenlabs_tts_v4`. The agent can search for others with `find_models`. It picks a `voice_id` with `search_library`, calls `generate` with `dry_run: true` and the real inputs, and tells you the price. Expected result: a price and no charge.
</Step>
<Step title="Make the voice">
The agent calls `generate` with `max_credits` set to that price and an `idempotency_key`. Expected result: a thread URL, then a sequence URL when the voice lands. The agent reads that URL with `read`, and never calls `generate` again to check.
</Step>
<Step title="Place the voice and music">
The agent places the voice and a music clip from `search_library` with `place_media`. Expected result: a voice clip and a music clip under the picture.
</Step>
<Step title="Check, then export">
The agent runs `check_timeline` and `capture` at the animation's start and end, then `export`. Expected result: an export card with status `completed`.
</Step>
</Steps>

To swap in a new version of the animation, the agent sends this op. The fence is the bare list of ops that `--operations @ops.json` takes:

```json
[
  {
    "op": "place_media",
    "asset": "<sequence-url>",
    "track": "V1",
    "at_f": 0,
    "source_start_seconds": 0,
    "source_end_seconds": 12,
    "mode": "replace",
    "replace_clip": "c4",
    "linked_audio": false
  }
]
```

`<sequence-url>` is the `url` that `add_media` returns for the new MP4. `c4` is the old animation's clip id, from `get_timeline`.

The voice from a terminal:

```bash
invideo agent register <project-url> --name <name>
export INVIDEO_AS=<name>
invideo gen models <project-url> --query "voice-over from a script"
invideo gen model <project-url> \
  --model elevenlabs_text_to_speech.elevenlabs_tts_v4
invideo library search <project-url> \
  --library elevenlabs_text_to_speech_voices --query "calm"
invideo gen run <page-url> \
  --model elevenlabs_text_to_speech.elevenlabs_tts_v4 --dry-run \
  -i prompt=@script.txt -i voice_id=<voice-id>
invideo gen run <page-url> \
  --model elevenlabs_text_to_speech.elevenlabs_tts_v4 \
  -i prompt=@script.txt -i voice_id=<voice-id> \
  --max-credits <price> --idempotency-key voice-1
```

`<project-url>` comes from `invideo project new` or `list_projects`. `<name>` is the name you choose in `invideo agent register`. `<page-url>` is a page that `invideo notebook show <project-url>` lists. `<price>` is the price the dry run returns. `<voice-id>` is an `id` that `invideo library search` returns.

## When to stay in Claude Motion

Stay in Claude Motion when the animation is the whole video. A chart, a report or a short walkthrough that needs no footage, voice or music is done when you click **Export**.

Move to invideo when the animation is one part of a video with other media, sound and a person reviewing the cut.

## If something goes wrong

| Symptom | Fix |
| --- | --- |
| `add_media` with `media_url` is refused | The link must be public. Download the file, then upload it with `start_upload` and `add_media` with the `upload_id`. |
| A re-sent animation makes a second video instead of updating the first | Send it with the same `claude_design_project_id` as the first import. |
| `get_model` or `generate` refuses the model as not found | Models retire. Run `find_models` with the job in words, use the best match, and tell the person which model you used. |
| Avoid: call `generate` again to check on a run | Instead: read the thread or sequence URL with `read`. A second `generate` starts a second paid run. |

## Related

- [When to use Claude Motion vs invideo](/compare/claude-motion)
- [Turn release notes or a changelog into a video every week](/how-to/training/release-notes-to-video)
- [Voice a script or narrate a course](/how-to/training/voice-a-script-or-narrate-a-course)
- [Check your video before you say it is done](/how-to/check-your-video)
- [invideo for AI agents](/agents)