> ## Documentation Index
> Fetch the complete documentation index at: https://www.tella.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tella Motion

> Build animated titles, shapes and motion graphics in a Tella video from the MCP server or the REST API: 16 tools, each with an endpoint under /v1/motion, that edit a document a clip, overlay or b-roll plays live.

Tella Motion lets an agent or a script build motion graphics in a Tella video: animated titles, shapes, charts, lower thirds, transitions and effects. You build them in a **Tella Motion document** with the same commands the Tella Motion editor uses, and the video plays the document as a clip, an overlay or b-roll. Every MCP tool has a REST endpoint under `/v1/motion` that takes the same arguments.

> **[Commands](https://www.tella.com/docs/mcp-tools/motion-commands.md)**
>
> Every command and op a batch takes, with fields and examples.

> **[Properties, easing and fonts](https://www.tella.com/docs/mcp-tools/motion-values.md)**
>
> Property names and units, easing curves, blend modes and fonts.

> **[Effects](https://www.tella.com/docs/mcp-tools/motion-effects.md)**
>
> All effect kinds and their parameters.

## MCP tools and REST endpoints

| MCP tool | REST endpoint | What it does |
| - | - | - |
| [`list_motion_documents`](#list_motion_documents) | `GET /v1/motion/documents?storyId=` | A video's documents you can edit, or yours that no video plays yet |
| [`create_motion_document`](#create_motion_document) | `POST /v1/motion/documents` | A blank document for an overlay or b-roll, or one of your own to place later |
| [`create_clip`](#create_clip) | `POST /v1/motion/clips` | A Tella Motion clip at the end of a video, or a new video, with its document |
| [`duplicate_motion_document`](#duplicate_motion_document) | `POST /v1/motion/documents/{id}/duplicate` | A copy of a document, optionally edited |
| [`get_motion_document`](#get_motion_document) | `GET /v1/motion/documents/{id}` | The canvas, node outline, compositions and `seq` |
| [`inspect_motion_node`](#inspect_motion_node) | `GET /v1/motion/documents/{id}/nodes/raw?path=` | One node's stored fields |
| [`inspect_motion_node_properties`](#inspect_motion_node_properties) | `GET /v1/motion/documents/{id}/nodes?path=&at=` | A node's properties, keys, effects and style |
| [`inspect_motion_composition`](#inspect_motion_composition) | `GET /v1/motion/documents/{id}/compositions/{compositionId}` | A composition and the instances that play it |
| [`download_motion_document`](#download_motion_document) | `GET /v1/motion/documents/{id}/download` | The whole stored document |
| [`get_motion_schema`](#get_motion_schema) | `GET /v1/motion/schema?schema=&type=` | JSON Schemas of the document and of every edit |
| [`apply_motion_editor_commands`](#apply_motion_editor_commands) | `POST /v1/motion/documents/{id}/commands` | Apply a batch of edits as one transaction |
| [`get_motion_frame`](#get_motion_frame) | `GET /v1/motion/documents/{id}/thumbnail?format=jpg` | A rendered frame of the document on its own |
| [`get_motion_preview`](#get_motion_preview) | `GET /v1/motion/documents/{id}/thumbnail?format=mp4` | An MP4 preview of the document on its own, with its sound |
| [`list_motion_media`](#list_motion_media) | `GET /v1/motion/documents/{id}/media` | The videos, sounds and images in a document |
| [`list_motion_fonts`](#list_motion_fonts) | `GET /v1/motion/fonts` | The fonts a title can use |
| [`list_motion_effects`](#list_motion_effects) | `GET /v1/motion/effects` | The effect kinds `addEffect` takes |

REST requests use your API key as a bearer token (see [Authentication](https://www.tella.com/docs/authentication.md)). The full request and response shapes are under **Tella Motion** in the API reference.

## How a Tella Motion document works

A document is a timeline of **nodes** on a **canvas**:

* **Canvas**: a size in pixels, a frame rate and a length. A new document is as large as the video and 10 seconds long. Change it with the `canvas.set` op, or shrink an overlay to its content with `fitCanvas`.
* **Nodes**: titles (text), shapes, paths, media (video and images), audio, groups, sequences (nodes that play one after another, like clips on a track) and composition instances. Each node has an `id`, a start and a duration, and paints over the nodes before it.
* **Compositions**: reusable sub-timelines. An instance plays one; editing a composition changes every instance.
* **Clocks**: a node's times are on the clock of the composition it sits in. For nodes on the canvas, that is the document's own time from 0.
* **Revision**: every saved batch increases the document's `seq`. Pass the `seq` you read as `baseRevision` and a batch is refused if someone changed the document since, in the editor or through the API.

Document IDs start with `ffd_`. Node IDs are unique in the document, so commands name a node by its ID alone.

## Units

| Value | In commands | In ops |
| - | - | - |
| Time | seconds, e.g. `1.5` | ticks (`timeline.canvas.ticksPerSecond`) or `{"seconds": 1.5}` |
| Position and size | pixels on the canvas | pixels |
| Rotation | degrees, clockwise | degrees |
| Opacity, scale, brightness, pan | fractions: `0.5` is half, `2` doubles | as stored |
| Volume | decibels | linear gain or `{"db": -6}` |
| Colour | `#rrggbb` (shapes also `#rrggbbaa`) | `{"r", "g", "b", "a"}` from 0 to 1 |

## Show a document in a video

A video plays a document in one of three ways. Each plays it live: an edit to the document shows in the video at once, so you can time it to the speech where it plays and keep refining it.

| As | How (MCP) | How (REST) |
| - | - | - |
| **A clip** of its own, at the end of the video | `create_clip` with `type: "motion"` | `POST /v1/motion/clips` |
| **An overlay** on top of a clip | `create_motion_document`, then [`add_overlay`](https://www.tella.com/docs/mcp-tools/overlays) with `motionDocumentId` | `POST /v1/motion/documents`, then `POST /v1/videos/{id}/clips/{clipId}/overlays` with `motionDocumentId` |
| **B-roll** in place of a clip's screen or camera | `create_motion_document`, then [`add_layout`](https://www.tella.com/docs/mcp-tools/layouts) or `update_layout` with `media: {"type": "motion", "documentId": "ffd_…"}` | `POST /v1/motion/documents`, then the clip's layouts endpoint with the same `media` |

In [`apply_video_edits`](https://www.tella.com/docs/mcp-tools/batch-edits), `add_media_overlay` also takes `motionDocumentId`. Reading a clip's overlays or layouts back reports Tella Motion media as `type: "motion"` with its document's ID (`motionDocumentId` on overlays, `media.documentId` on layouts).

Tella Motion media in the media library is a frozen snapshot: placing it makes a new document of the video's.

### Draft a document before it is in a video

Leave out `videoId` in `create_motion_document` and the document is yours, in no video yet. Build it as usual, then place it with `create_clip` (`documentId`), `add_overlay` (`motionDocumentId`) or a layout's motion media. The first video you place it in takes it over, and it keeps its ID. From then on it belongs to that video like any other document, and no other video can use it. A copy keeps its document's owner, so to use a draft in more than one video, copy it with `duplicate_motion_document` **before** you place it, then place each copy in its own video.

To turn it into a video of its own, call `create_clip` with `documentId` and no `videoId`. It makes a new video as large as the document's canvas, with one clip that plays it.

> [!NOTE]
>
> A document no video plays yet has no page in Tella. To see it, use [`get_motion_frame`](#get_motion_frame) or [`get_motion_preview`](#get_motion_preview), which render the document on its own.

## Build a title card, step by step

This builds an animated intro title as a clip of its own. The same steps work for an overlay or b-roll once you have its document.

**1. Add a Tella Motion clip.** It plays a blank document of its own.

```json MCP: create_clip theme={"system"}
{"videoId": "vid_abc123", "type": "motion", "name": "Intro title"}
```

```bash REST theme={"system"}
curl -X POST https://api.tella.com/v1/motion/clips \
  -H "Authorization: Bearer $TELLA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"videoId": "vid_abc123", "name": "Intro title"}'
```

The response has the clip's `clipId` and its `document`, whose `id` (`ffd_…`) the next calls use.

**2. Read the document** with `get_motion_document` (`GET /v1/motion/documents/{id}`) for its canvas size and `seq`.

**3. Apply a batch of edits.** This sets the length, adds a background, a title and a subtitle, animates them in and adds a glow, as one transaction:

```json MCP: apply_motion_editor_commands theme={"system"}
{
  "documentId": "ffd_abc123",
  "baseRevision": 0,
  "commands": [
    {"type": "canvas.set", "canvas": {"duration": {"seconds": 4}}},
    {"type": "addShape", "nodeId": "bg", "start": 0, "duration": 4, "shape": "fill", "color": "#0f172a"},
    {"type": "addTitle", "nodeId": "title", "start": 0.2, "duration": 3.8, "text": "Quarterly update",
     "box": {"x": 160, "y": 420, "width": 1600}, "font": "inter", "fontSize": 120, "weight": 700, "color": "#ffffff"},
    {"type": "setTextAnimation", "node": "title", "phase": "in", "preset": "rise", "unit": "word"},
    {"type": "addTitle", "nodeId": "subtitle", "start": 0.8, "duration": 3.2, "text": "Revenue up 40%",
     "box": {"x": 160, "y": 580, "width": 1600}, "fontSize": 56, "weight": 400, "color": "#94a3b8"},
    {"type": "animate", "node": "subtitle", "in": {"kind": "slideUp", "duration": 0.5, "easing": "easeOutCubic"}},
    {"type": "addEffect", "node": "title", "kind": "glow", "params": {"radius": 30, "intensity": 0.8}}
  ]
}
```

```bash REST theme={"system"}
curl -X POST https://api.tella.com/v1/motion/documents/ffd_abc123/commands \
  -H "Authorization: Bearer $TELLA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "baseRevision": 0,
    "commands": [
      {"type": "canvas.set", "canvas": {"duration": {"seconds": 4}}},
      {"type": "addShape", "nodeId": "bg", "start": 0, "duration": 4, "shape": "fill", "color": "#0f172a"},
      {"type": "addTitle", "nodeId": "title", "start": 0.2, "duration": 3.8, "text": "Quarterly update",
       "box": {"x": 160, "y": 420, "width": 1600}, "font": "inter", "fontSize": 120, "weight": 700, "color": "#ffffff"},
      {"type": "setTextAnimation", "node": "title", "phase": "in", "preset": "rise", "unit": "word"},
      {"type": "addTitle", "nodeId": "subtitle", "start": 0.8, "duration": 3.2, "text": "Revenue up 40%",
       "box": {"x": 160, "y": 580, "width": 1600}, "fontSize": 56, "weight": 400, "color": "#94a3b8"},
      {"type": "animate", "node": "subtitle", "in": {"kind": "slideUp", "duration": 0.5, "easing": "easeOutCubic"}},
      {"type": "addEffect", "node": "title", "kind": "glow", "params": {"radius": 30, "intensity": 0.8}}
    ]
  }'
```

**4. Check the result** by looking at a frame: [`get_motion_frame`](#get_motion_frame) with the document's ID and a `startTimeMs` (REST: `GET /v1/motion/documents/{id}/thumbnail?startTimeMs=1500`). To see it as the video shows it, with its layout and the clip it plays on, use [`get_clip_frame`](https://www.tella.com/docs/mcp-tools/clips#get_clip_frame) with the clip's ID (REST: `GET /v1/videos/{id}/clips/{clipId}/thumbnail?startTimeMs=1500`).

**5. Reuse the design.** `duplicate_motion_document` copies it and can change the copy in the same call, e.g. `[{"type": "setTitle", "node": "title", "text": "Pricing"}]`, for the next section's title.

## Apply a batch of edits

`apply_motion_editor_commands` (REST: `POST /v1/motion/documents/{id}/commands`) takes 1 to 256 items, applied in order as one transaction and one undo step: nothing applies unless everything does. Each item is either:

* **A command**, the editor's own actions, with a camelCase `type`: titles, shapes, paths and media; split, trim, ripple delete, speed and transitions; In/Out animations, keyframes and easing on any property; effects, masks and track mattes; groups; time remapping; wiggle and loop expressions; per-character, word or line text animation; curves and bindings; fades and ducking. Commands keep the editor's conventions, so the result stays editable in the editor like a hand edit.
* **An op**, what the document stores, with a dotted `type`: `node.patch` for any field, `node.insert`, `node.move`, `canvas.set`, assets, compositions and more. Ops take raw render timeline values.

Prefer a command for anything the editor does, and use ops for the rest. [Tella Motion commands](https://www.tella.com/docs/mcp-tools/motion-commands.md) lists all of them with their fields and an example each.

* **Name nodes yourself** with `nodeId` when you add them, so later items in the same batch can refer to them. Left out, an ID is generated and returned in `affected.created`.
* **Check without saving** with `dryRun: true`.
* **Guard a batch** with an `expect` item: it fails the batch when a node or a property's value is not what you expect.
* **Get exact schemas** from `get_motion_schema` with `schema: "edits"` and a `type`, e.g. `addTitle` or `node.patch` (REST: `GET /v1/motion/schema?schema=edits&type=addTitle`). Without `type` it returns every edit (about 180 KB).

### The batch result

The title card batch above returns:

```json theme={"system"}
{
  "ok": true,
  "dryRun": false,
  "changed": true,
  "seq": 1,
  "affected": {"created": ["bg", "title", "subtitle", "glow"], "updated": [], "deleted": []},
  "ops": 18
}
```

`seq` is the new revision to pass as the next `baseRevision`. A `notes` array appears when an edit applied with an adjustment worth knowing, such as a font drawing the nearest weight it has, or the rectangle to place an overlay at after `fitCanvas`.

## Errors

A failed call returns `{"ok": false, "error": {"code", "message"}}`. For a batch, the message starts with the failing item's index (`command 3: …`) and nothing is applied. Over REST, errors use the API's standard error body and these statuses:

| Code | REST status | What to do |
| - | - | - |
| `document.not_found` | 404 | The ID is wrong or you can't edit that document. List them with `list_motion_documents`. |
| `revision.conflict` | 409 | The document changed since you read it. Read it again and rebuild the batch from the new `seq`. |
| `document.unavailable`, `room.timeout` | 503 | Retry after a moment. |
| `command.invalid` | 400 | An item doesn't match its schema; the message names the field. Check it with `get_motion_schema`. |
| `node.not_found`, `node.locked`, `property.unknown`, `property.animated` and other codes | 400 | The message says what is wrong, e.g. `property.animated`: the property has keys, so pass `at`. |

## Tella Motion clips

A Tella Motion clip plays its document instead of a recording, so it has no layouts, cuts, zooms or transcript, and the tools that edit those refuse it. `update_clip` renames it, `reorder_clip` moves it and `delete_clip` removes it; what it shows is edited on its document. The clip lasts as long as its document's canvas.

Overlays still work on top of it: the [overlay](https://www.tella.com/docs/mcp-tools/overlays.md), [text overlay](https://www.tella.com/docs/mcp-tools/text-overlays.md) and [sound effect](https://www.tella.com/docs/mcp-tools/sound-effects.md) tools (and their `apply_video_edits` operations) accept a Tella Motion clip. Their times are on the clip's own clock, from the start of its document, and they draw above the document. `list_motion_documents` lists a clip's document with the clip's ID as its `sceneID`.

## list\_motion\_documents

`GET /v1/motion/documents?storyId=vid_…`. Returns `documents`, newest first: the video's Tella Motion clips' documents and the documents its overlays and b-roll play. Without `storyId`, your documents that no video plays yet. Each has its `id`, `name`, `scope` (`story` for a video's, `user` for yours), `ownerID` (the video, or you) and, for a clip's document, `sceneID` (the clip).

**storyId** `string`

The video (`vid_…`) whose documents to list. Leave it out for your documents that no video plays yet.

## create\_motion\_document

`POST /v1/motion/documents`, returns 201 with `document`. Its canvas is as large as the video unless sized (1920×1080 without a video), and 10 s long; the `canvas.set` op changes that. It is not put in the media library.

**videoId** `string`

The video (`vid_…`) that owns the document. Leave it out for a document of your own that no video plays yet: the first video it is placed in takes it over.

**name** `string` *required*

What it shows, e.g. `Lower third`.

**width** `number`

Canvas width in pixels, 16–7680.

**height** `number`

Canvas height in pixels, 16–7680.

## create\_clip

`POST /v1/motion/clips` (no `type`: it always adds a Tella Motion clip), returns 201. The clip lasts as long as its document and appears in the open editor at once. To add a clip from a recording or an uploaded file, use `upload_clip`.

**videoId** `string`

The video (`vid_…`) to add the clip to. Required unless you pass `documentId`; leave it out with `documentId` to make a new video.

**type** `enum\<string\>` *required*

`motion`, the only type so far. MCP only.

**name** `string` *required*

The clip's name, e.g. `Intro title`, and the new video's when there is no `videoId`.

**documentId** `string`

A document of yours that no video plays yet (`ffd_…`), for the clip to play instead of a blank one. The video takes it over. Without `videoId`, it makes a new video as large as the document's canvas.

Returns the new clip's `clipId` and its `document`, and, when it made a new video, its `videoId` and `editUrl`.

## duplicate\_motion\_document

`POST /v1/motion/documents/{id}/duplicate`, returns 201. The copy has the same owner (a video's stays that video's, one of yours that no video plays yet stays yours) and is independent: later edits to either do not reach the other. Returns the copy as `document` and, with `commands`, the batch's result as `applied`.

**documentId** `string` *required*

The document to copy (`ffd_…`). In the REST path.

**name** `string` *required*

The copy's name, e.g. `Topic title: Pricing`.

**commands** `array`

1–256 edits to run on the copy, as `apply_motion_editor_commands` takes them, e.g. `setTitle` on its title node.

## get\_motion\_document

`GET /v1/motion/documents/{id}`. The canvas, the outline of its nodes (IDs, types, windows in seconds, what they show, paint order, transitions), its compositions and assets, the editor's names, colours, mute, solo and locks, and `seq`.

**documentId** `string` *required*

The document (`ffd_…`).

## inspect\_motion\_node

`GET /v1/motion/documents/{id}/nodes/raw?path=…`. One node with every stored field, its window, the composition it sits in, and for an instance the outline of the composition it plays. Use it before a `node.patch`.

**documentId** `string` *required*

The document (`ffd_…`).

**path** `string` *required*

The node's ID (or path) from the document's outline, e.g. `title`.

## inspect\_motion\_node\_properties

`GET /v1/motion/documents/{id}/nodes?path=…&at=…`. A node as the editor's inspector shows it at a time: every animatable property with its unit, range, value and keys (with their IDs, times, values and easing), its effect stack and expressions, its style (blend, flips, shadow), title or shape settings, and audio fades. Read a node this way before changing its look, animation or sound.

**documentId** `string` *required*

The document (`ffd_…`).

**path** `string` *required*

The node's ID (or path).

**at** `number`

Seconds on the node's composition clock. Defaults to the node's start.

## inspect\_motion\_composition

`GET /v1/motion/documents/{id}/compositions/{compositionId}`. Editing a composition changes every instance that plays it.

**documentId** `string` *required*

The document (`ffd_…`).

**compositionId** `string` *required*

The composition asset's ID.

## download\_motion\_document

`GET /v1/motion/documents/{id}/download`. The whole stored document (`formatVersion`, `name`, `timeline` with every node, composition and asset, and `editor` state) and its `seq`. It is large: save it and pull out what you need with a tool such as `jq`. Its shape is `get_motion_schema` with `schema: "document"`. Times are ticks (`timeline.canvas.ticksPerSecond`).

**documentId** `string` *required*

The document (`ffd_…`).

## get\_motion\_schema

`GET /v1/motion/schema?schema=…&type=…`. JSON Schemas, generated from the same code that validates edits.

**schema** `enum\<string\>` *required*

`edits`: one item of an `apply_motion_editor_commands` batch, every command and op (about 180 KB; select one with `jq '.oneOf[] | select(.properties.type.const == "addTitle")'`), or with `type` that one edit's small, self-contained schema. `document`: a document as `download_motion_document` returns it (about 160 KB).

**type** `string`

With `edits`: one op or command, e.g. `node.patch` or `addTitle`.

## apply\_motion\_editor\_commands

`POST /v1/motion/documents/{id}/commands`. See [Apply a batch of edits](#apply-a-batch-of-edits) and [Tella Motion commands](https://www.tella.com/docs/mcp-tools/motion-commands.md).

**documentId** `string` *required*

The document (`ffd_…`). In the REST path.

**commands** `array` *required*

1–256 commands and ops, each with a `type`.

**baseRevision** `integer`

The `seq` you read. The batch is refused (REST: 409) if the document has changed since.

**dryRun** `boolean`

Check the batch without saving it.

## get\_motion\_frame

`GET /v1/motion/documents/{id}/thumbnail`. A rendered frame of the document on its own, at a time on its own clock, for any document you can edit, also one no video plays yet. For `jpg`, `png` or `webp`, returns inline image content plus a signed URL; for `gif`, the signed URL only. To see the document as a video shows it (its layout, other clips), use [`get_clip_frame`](https://www.tella.com/docs/mcp-tools/clips#get_clip_frame).

Over REST it returns a 302 redirect to the signed URL, or `{"url"}` with `?response=json`, like `GET /v1/videos/{id}/thumbnail`. Every edit to the document gets a new render. Both tools refuse a document that plays media you can't access with `forbidden` (REST: 403).

**documentId** `string` *required*

The document (`ffd_…`). In the REST path.

**format** `enum\<string\>`

`jpg` (default), `png`, `webp`, or `gif`

**startTimeMs** `integer`

The frame's time in ms from the document's start (default 0). At or past its end, its last frame.

**durationMs** `integer`

Duration in ms when `format` is `gif`

**width** `integer`

Output width in pixels (range 1–1920, default 320). Omit `height` to keep the canvas's aspect ratio.

**height** `integer`

Output height in pixels (range 1–1920). Derived from the canvas's aspect ratio when omitted.

## get\_motion\_preview

`GET /v1/motion/documents/{id}/thumbnail?format=mp4`. An MP4 preview of the document on its own, with its sound, for any document you can edit, also one no video plays yet. It returns a signed `url` and waits for the render as [`get_clip_preview`](https://www.tella.com/docs/mcp-tools/clips#get_clip_preview) does: `status: "ready"` means the URL downloads immediately, and `status: "rendering"` means call again with the same arguments to keep waiting, for about 3 minutes in total.

**documentId** `string` *required*

The document (`ffd_…`). In the REST path.

**startTimeMs** `integer`

Preview start in ms from the document's start (default 0)

**durationMs** `integer`

Preview duration in ms (default 5000, range 500–30000)

**fps** `integer`

`1`, `2`, `5`, `10`, or `30` (default 30)

**width** `integer`

Output width in pixels (range 1–1920, default 320). Omit `height` to keep the canvas's aspect ratio.

**height** `integer`

Output height in pixels (range 1–1920). Derived from the canvas's aspect ratio when omitted.

## list\_motion\_media

`GET /v1/motion/documents/{id}/media`. Each item has the `mediaId` the `addMedia` command places.

To place a photo, video or sound that isn't in the document yet, pass `addMedia` its `sourceId` instead: a source from `create_source`, a chat attachment or a library item's. Tella reads from the upload whether it is an image, a video or a sound and adds it as one.

**documentId** `string` *required*

The document (`ffd_…`).

## list\_motion\_fonts

`GET /v1/motion/fonts`. No parameters. Each font comes with its `slug`, its `family` and the weights it can draw as `weights: {min, max}`. The list is also in [Properties, easing and fonts](https://www.tella.com/docs/mcp-tools/motion-values.md#fonts).

A title takes any weight from 100 (thin) to 900 (black) in `addTitle` and `setTitle`. When the font can't draw that weight (a family that tops out at 700, or one that ships as a single weight), the edit still applies, draws the nearest weight the font has, and returns a note saying which weight it draws.

## list\_motion\_effects

`GET /v1/motion/effects?kind=…&preset=…`. Without parameters, each effect kind comes with its parameters' names, types, ranges, units and defaults, and its presets by name and description. `presetsKeep` names the parameters no preset sets: they keep their value when a preset is applied or switched, and a preset sets every other one. The list is also in [Tella Motion effects](https://www.tella.com/docs/mcp-tools/motion-effects.md).

`addEffect` and `setEffect` apply a preset by name, with any `params` you pass on top. To see the values a preset sets, pass `kind`, and `preset` for one of them.

**kind** `string`

One effect kind, e.g. `fx.liquidGlass`. The response is `effect`: that kind, with each preset's values where they differ from the kind's defaults.

**preset** `string`

With `kind`: one of its presets, e.g. `regularLight`. The response's `effect.params` is every value it sets.


## Related topics

- [Create motion graphics with Tella Motion](https://www.tella.com/docs/help/editing/tella-motion.md)
- [Tella Motion commands](https://www.tella.com/docs/mcp-tools/motion-commands.md)
- [Tella Motion effects](https://www.tella.com/docs/mcp-tools/motion-effects.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.