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

# Run Agent

> Execute an agent workflow on videos or run generation-only workflows.

Execute an agent workflow. Supports standard video-input workflows and generation-only workflows such as AI Avatar, Video Generation, Audio Generation, and Image Generation.

## Canonical input model

Treat `video_inputs` as the canonical run input shape:

* `video_inputs[]` entries map assets to a specific `Video Input` tile (`agent_node_id`)
* each entry accepts one or more sources: `video_ids`, `node_render_ids`, `video_urls`
* optional `input_clip_start_ms` / `input_clip_end_ms` fields can limit the source range used for a run

Top-level fields (`video_ids`, `node_render_ids`, `video_urls`) are shorthand for single-input runs.

## Single-input shorthand

If your runnable graph has one `Video Input` tile, you can send top-level input arrays without specifying `agent_node_id`.

```bash theme={null}
curl -X POST "https://api.mosaic.so/agent/[agent_id]/run" \
  -H "Authorization: Bearer mk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "video_urls": [
      "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ],
    "callback_url": "https://your-webhook.com/callback"
  }'
```

Example using `video_ids` (from the [Uploads API](/api/asset-management/upload-flow)):

```json theme={null}
{
  "video_ids": [
    "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
  ],
  "callback_url": "https://your-webhook.com/callback"
}
```

Example using `node_render_ids` (from previous run outputs):

```json theme={null}
{
  "node_render_ids": [
    "7ba7b810-9dad-11d1-80b4-00c04fd430c8"
  ],
  "callback_url": "https://your-webhook.com/callback"
}
```

## Multi-input workflows

If your agent has multiple runnable `Video Input` tiles, you must use `video_inputs` and provide an entry for each runnable input tile.

In that mode, do not also send top-level input arrays.

You can get each `agent_node_id` from `GET /agent/[agent_id]` or from the Mosaic editor's API info panel for that tile.

```bash theme={null}
curl -X POST "https://api.mosaic.so/agent/[agent_id]/run" \
  -H "Authorization: Bearer mk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "video_inputs": [
      {
        "agent_node_id": "11111111-1111-1111-1111-111111111111",
        "video_ids": ["aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"]
      },
      {
        "agent_node_id": "22222222-2222-2222-2222-222222222222",
        "video_urls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"]
      }
    ],
    "callback_url": "https://your-webhook.com/callback"
  }'
```

## Generation-Only Workflows

For workflows starting with generation nodes and no Video Input node, no video inputs should be provided. These agents generate media based on the parameters configured in the agent, or on `update_params` you pass at run time.

Generation node type IDs:

| Node             | Node type ID                           | Docs                                                 |
| ---------------- | -------------------------------------- | ---------------------------------------------------- |
| AI Avatar        | `b3b4c9e2-2a47-4fa9-8ce8-0c1fa1d7b6ef` | [AI Avatar](/tiles/ai-avatar#api-info)               |
| Video Generation | `a2eb3ec2-da7a-4f97-94d2-a9a537548522` | [Video Generation](/tiles/video-generation#api-info) |
| Audio Generation | `14687f30-5fd0-468f-8239-2784d83df95b` | [Audio Generation](/tiles/audio-generation#api-info) |
| Image Generation | `18b998a0-2ea7-4676-a5d3-3ae6c8ac0b72` | [Image Generation](/tiles/image-generation#api-info) |

To create a generation-only agent, use [Create Agent](/api/agents/post-agent-create), then add one of these nodes with [Update Agent](/api/agents/post-agent-update). Run that agent without `video_inputs`, `video_ids`, `video_urls`, or `node_render_ids`.

```bash theme={null}
curl -X POST "https://api.mosaic.so/agent/[agent_id]/run" \
  -H "Authorization: Bearer mk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "callback_url": "https://your-webhook.com/callback",
    "update_params": {
      "NODE_ID": {
        "prompt": "A cinematic product teaser with dramatic lighting"
      }
    }
  }'
```

For AI Avatar, create an avatar first with [`POST /avatar-profiles/create`](/api/avatar-profiles/create-avatar-profile), then pass the avatar ID into the avatar node:

```json theme={null}
{
  "callback_url": "https://your-webhook.com/callback",
  "update_params": {
    "AI_AVATAR_AGENT_NODE_ID": {
      "avatar_profile_id": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
      "video_model": "seedance-2-fast",
      "single_take": false,
      "script": "Here is the exact script the avatar should say."
    }
  }
}
```

Video Generation example:

```json theme={null}
{
  "callback_url": "https://your-webhook.com/callback",
  "update_params": {
    "VIDEO_GENERATION_AGENT_NODE_ID": {
      "prompt": "A cinematic product teaser with dramatic lighting",
      "model": "seedance-2",
      "resolution": "1080p",
      "duration": "8",
      "aspect_ratio": "16:9"
    }
  }
}
```

Use `model: "seedance-2"` and `resolution: "4k"` for 4K output. 4K resolution is billed at 2x normal Seedance.

Audio Generation example:

```json theme={null}
{
  "callback_url": "https://your-webhook.com/callback",
  "update_params": {
    "AUDIO_GENERATION_AGENT_NODE_ID": {
      "mode": "music",
      "music_prompt": "Upbeat electronic background music for a product launch",
      "music_length_ms": 30000
    }
  }
}
```

Image Generation example:

```json theme={null}
{
  "callback_url": "https://your-webhook.com/callback",
  "update_params": {
    "IMAGE_GENERATION_AGENT_NODE_ID": {
      "prompt": "A clean hero image of a modern video editing workspace",
      "image_size": "landscape_4_3",
      "quality": "high"
    }
  }
}
```

## Parameters

| Field                 | Type      | Required    | Description                                                                                                                                                                                                                                              |
| --------------------- | --------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `video_inputs`        | object\[] | Conditional | Canonical per-tile input mapping. Each entry must include `agent_node_id` plus at least one of `video_ids`, `node_render_ids`, `video_urls`, or `mimir_assets`. Required for multi-input runs.                                                           |
| `video_ids`           | string\[] | Conditional | Top-level shorthand for single-input runs. Video UUIDs from the Uploads API (or existing workspace video assets).                                                                                                                                        |
| `node_render_ids`     | string\[] | Conditional | Top-level shorthand for single-input runs. Render IDs from prior run outputs (`GET /agent_run/{run_id}` -> `outputs[].id`) or run webhooks.                                                                                                              |
| `video_urls`          | string\[] | Conditional | Top-level shorthand for single-input runs. Video URLs to ingest (YouTube and signed URLs).                                                                                                                                                               |
| `input_clip_start_ms` | integer   |             | Optional start offset applied to all top-level input arrays. Can be sent by itself (trim from this offset to the end) or with `input_clip_end_ms`.                                                                                                       |
| `input_clip_end_ms`   | integer   |             | Optional end offset applied to all top-level input arrays. Can be sent by itself (trim from `0` to this offset) or with `input_clip_start_ms`. For URL inputs, Mosaic cuts the downloaded asset before uploading it to the run.                          |
| `video_id_inputs`     | object\[] | Conditional | Per-item form for existing uploaded videos. Each object accepts `id`, `input_clip_start_ms`, and `input_clip_end_ms`.                                                                                                                                    |
| `node_render_inputs`  | object\[] | Conditional | Per-item form for previous render outputs. Each object accepts `id`, `input_clip_start_ms`, and `input_clip_end_ms`.                                                                                                                                     |
| `video_url_inputs`    | object\[] | Conditional | Per-item form for external/signed URLs. Each object accepts `url`, `input_clip_start_ms`, and `input_clip_end_ms`.                                                                                                                                       |
| `youtube_url_inputs`  | object\[] | Conditional | Per-item form for YouTube URLs. Each object accepts `url`, `input_clip_start_ms`, and `input_clip_end_ms`.                                                                                                                                               |
| `mimir_assets`        | object\[] | Conditional | Mimir assets to ingest. Each object has `id` (Mimir item UUID), optional `artifact` (`highres`, `proxy`, or `auto`; defaults to `highres`), and optional `input_clip_start_ms` / `input_clip_end_ms`. Requires a [Mimir connection](#mimir-integration). |
| `callback_url`        | string    |             | Optional webhook URL for status updates                                                                                                                                                                                                                  |
| `update_params`       | object    |             | Optional parameters to override node parameters in the agent workflow. Keys must be valid `agent_node_id` values from the runnable graph.                                                                                                                |
| `ignore_nodes`        | string\[] |             | Optional list of `agent_node_id` values to bypass for this run. Mosaic removes each ignored node from the runtime graph and rewires incoming edges directly to its downstream nodes.                                                                     |

Input rules:

* Use **either** top-level input arrays **or** `video_inputs` (not both in the same request).
* If the runnable graph has multiple `Video Input` tiles, provide one `video_inputs` entry for each runnable input tile.
* `node_render_ids` are valid video inputs (top-level shorthand for single-input runs, or per-entry in `video_inputs`).
* `mimir_assets` can be combined with other input types in the same entry.
* If you need different start/end ranges for different inputs, use `video_id_inputs`, `node_render_inputs`, `video_url_inputs`, or `youtube_url_inputs` instead of the plain string arrays.
* `input_clip_start_ms` and `input_clip_end_ms` are independent optional fields; if both are provided, `input_clip_end_ms` must be greater than `input_clip_start_ms`.

ID source rules:

* `video_ids` come from the [Uploads API](/api/asset-management/upload-flow).
* `node_render_ids` come from previous run outputs (`GET /agent_run/{run_id}` -> `outputs[].id`) or run webhooks.

## Input Clipping

You can run an agent on a segment of a source video by passing millisecond offsets. This is useful when you only want the first part of a long video or when billing should match the portion actually processed.

Top-level clipping applies the same range to every top-level input:

```json theme={null}
{
  "youtube_urls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
  "input_clip_start_ms": 0,
  "input_clip_end_ms": 1200000,
  "callback_url": "https://your-webhook.com/callback"
}
```

For URL inputs, Mosaic cuts the downloaded file before it is uploaded as the run input. For existing `video_ids` and `node_render_ids`, Mosaic creates a clipped timeline/render input for the requested range.

You can also send only one side of the range:

`input_clip_start_ms` only (trim from start offset to end of source):

```json theme={null}
{
  "video_urls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
  "input_clip_start_ms": 45000,
  "callback_url": "https://your-webhook.com/callback"
}
```

`input_clip_end_ms` only (trim from `0` to end offset):

```json theme={null}
{
  "video_urls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
  "input_clip_end_ms": 90000,
  "callback_url": "https://your-webhook.com/callback"
}
```

Use the object input forms when each source needs its own range:

```json theme={null}
{
  "video_inputs": [
    {
      "agent_node_id": "11111111-1111-1111-1111-111111111111",
      "youtube_url_inputs": [
        {
          "url": "https://www.youtube.com/watch?v=VIDEO_ONE",
          "input_clip_start_ms": 0,
          "input_clip_end_ms": 900000
        },
        {
          "url": "https://www.youtube.com/watch?v=VIDEO_TWO",
          "input_clip_start_ms": 30000,
          "input_clip_end_ms": 630000
        }
      ],
      "node_render_inputs": [
        {
          "id": "7ba7b810-9dad-11d1-80b4-00c04fd430c8",
          "input_clip_start_ms": 0,
          "input_clip_end_ms": 600000
        }
      ],
      "mimir_assets": [
        {
          "id": "b60d57d2-4b12-a80c-6f14-c5eefaa91460",
          "artifact": "highres",
          "input_clip_start_ms": 120000,
          "input_clip_end_ms": 720000
        }
      ]
    }
  ],
  "callback_url": "https://your-webhook.com/callback"
}
```

## Video URL Requirements & Limits

The `video_urls` field supports two types of URLs:

**YouTube URLs:**

* Supports standard YouTube video URLs (e.g., `https://www.youtube.com/watch?v=VIDEO_ID`)
* **Maximum duration**: 5 hours per video
* The system automatically validates the video exists and checks duration before processing

**Signed URLs (HTTP/HTTPS):**

* Must be HTTP or HTTPS URLs pointing to video files
* **Maximum file size**: 5 GB per video
* **Maximum duration**: 5 hours per video

## Modifying Node Parameters

You can override specific parameters for any node in your agent workflow using the `update_params` field. This allows you to dynamically change behavior (like clip duration, prompt text, or number of clips) at runtime.

To find the correct parameters:

1. Open your agent in the [Mosaic Dashboard](https://edit.mosaic.so)
2. Click the settings menu on the node you want to modify
3. Scroll down to the **API info** dropdown
4. Open the dropdown to find the `Agent node ID`
5. Click **Copy params** to get the JSON structure

The copied JSON will look like this, where the key is the **agent\_node\_id** (UUID) and the value object contains the parameters you can override:

```json theme={null}
{
  "bf750792-a2e9-48c2-9d39-24f892772f6a": {
    "num_clips": 10,
    "min_duration": 30,
    "max_duration": 120
  }
}
```

Pass this entire object as the `update_params` value in your API request.

### `update_params` validation behavior

Mosaic validates `update_params` before creating the run:

* Unknown `agent_node_id` keys return `400`
* Invalid parameter types/values return `400`
* Protected/system nodes (for example Video Input/Destination/trigger nodes) cannot be overridden with `update_params`

If validation fails, the run is **not** created.

## Bypassing Nodes at Runtime

Use `ignore_nodes` to skip one or more nodes for a single run without editing the saved agent template.

For each ignored node:

* Incoming connections to the node are rewired to its downstream nodes
* The ignored node is removed from the runtime DAG for that run only
* The template itself is unchanged

```json theme={null}
{
  "video_urls": ["https://youtube.com/watch?v=..."],
  "ignore_nodes": [
    "8cbfd03e-6e85-4f3d-b4b9-8de0b5bfb6a4"
  ],
  "update_params": {
    "35a12345-6789-abcd-ef01-234567890abc": {
      "audio_id": "your-uploaded-audio-uuid"
    }
  }
}
```

## Uploading Media for Node Parameters

Some nodes accept **images**, **audio**, or **videos** as parameters. To set these programmatically, use the [Uploads API](/api/asset-management/upload-flow) to upload your files and get their UUIDs:

```json theme={null}
{
  "video_urls": ["https://youtube.com/watch?v=..."],
  "update_params": {
    "35a12345-6789-abcd-ef01-234567890abc": {
      "audio_id": "your-uploaded-audio-uuid"
    },
    "76b23456-7890-efab-cd12-345678901bcd": {
      "image_id": "your-uploaded-image-uuid"
    }
  }
}
```

See the [Upload Flow](/api/asset-management/upload-flow) for the complete upload process.

## Chaining Runs with `node_render_ids`

You can feed outputs from a previous run directly into another run by passing render IDs returned in webhooks or from `GET /agent_run/[run_id]` (`outputs[].id`).

Single-input shorthand:

```bash theme={null}
curl -X POST "https://api.mosaic.so/agent/[agent_id]/run" \
  -H "Authorization: Bearer mk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "node_render_ids": [
      "7ba7b810-9dad-11d1-80b4-00c04fd430c8",
      "8cbfd03e-6e85-4f3d-b4b9-8de0b5bfb6a4"
    ],
    "callback_url": "https://your-webhook.com/callback"
  }'
```

Canonical `video_inputs` form:

```bash theme={null}
curl -X POST "https://api.mosaic.so/agent/[agent_id]/run" \
  -H "Authorization: Bearer mk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "video_inputs": [
      {
        "agent_node_id": "11111111-1111-1111-1111-111111111111",
        "node_render_ids": [
          "7ba7b810-9dad-11d1-80b4-00c04fd430c8"
        ]
      }
    ],
    "callback_url": "https://your-webhook.com/callback"
  }'
```

## Mimir Integration

Mosaic can ingest video directly from [Mimir](https://mimir.mjoll.no) using `mimir_assets`. This downloads the video from your Mimir instance, stores Mimir metadata (item ID, artifact type, connection details) as `source_info` on the video record, and makes it available for Premiere Pro linking in downstream tiles.

### Prerequisites

1. Go to **Settings > Integrations** in the [Mosaic dashboard](https://edit.mosaic.so).
2. Add your Mimir instance URL (e.g. `https://mimir.mjoll.no`) and an API key generated from your Mimir user settings.
3. Mosaic verifies the connection on save. If verification fails, check that the URL and API key are correct.

### Single Mimir asset

```bash theme={null}
curl -X POST "https://api.mosaic.so/agent/[agent_id]/run" \
  -H "Authorization: Bearer mk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "mimir_assets": [
      {
        "id": "b60d57d2-4b12-a80c-6f14-c5eefaa91460",
        "artifact": "highres"
      }
    ],
    "callback_url": "https://your-webhook.com/callback"
  }'
```

### Multiple Mimir assets with different artifacts

```json theme={null}
{
  "mimir_assets": [
    { "id": "b60d57d2-4b12-a80c-6f14-c5eefaa91460", "artifact": "highres" },
    { "id": "a1e0b6bd-d3be-4d1b-a529-41dd8927325e", "artifact": "proxy" }
  ],
  "callback_url": "https://your-webhook.com/callback"
}
```

### Mimir assets in multi-input workflows

```json theme={null}
{
  "video_inputs": [
    {
      "agent_node_id": "11111111-1111-1111-1111-111111111111",
      "mimir_assets": [
        { "id": "b60d57d2-4b12-a80c-6f14-c5eefaa91460" }
      ]
    },
    {
      "agent_node_id": "22222222-2222-2222-2222-222222222222",
      "video_urls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"]
    }
  ],
  "callback_url": "https://your-webhook.com/callback"
}
```

### `mimir_assets` entry schema

| Field                 | Type          | Required | Description                                                                  |
| --------------------- | ------------- | -------- | ---------------------------------------------------------------------------- |
| `id`                  | string (UUID) | Yes      | Mimir item ID.                                                               |
| `artifact`            | string        | No       | Which artifact variant to download (see table below). Defaults to `highres`. |
| `input_clip_start_ms` | integer       | No       | Optional start offset for this Mimir asset.                                  |
| `input_clip_end_ms`   | integer       | No       | Optional end offset for this Mimir asset.                                    |

#### Artifact options

| Value     | Behavior                                                                                                                               |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `highres` | Downloads the high-resolution source file. **Default** when `artifact` is omitted. Returns `400` if the item has no highres available. |
| `proxy`   | Downloads the lower-resolution proxy. Returns `400` if the item has no proxy available.                                                |
| `auto`    | Prefers highres if available, falls back to proxy. Returns `400` only if neither is available.                                         |

Regardless of which artifact is downloaded, the Mimir item ID is always stored in `source_info` so Premiere Pro exports can link back to the original asset in Mimir.

<Note>
  `mimir_assets` require an **organization-scoped API key** (`mk_` prefix). The Mimir connection itself is **workspace-scoped** — configure it per workspace in Settings → Integrations. If no Mimir connection is configured for the agent's workspace, the API returns a `400` error explaining how to set one up.
</Note>

### How Mimir metadata flows

When a Mimir asset is ingested:

1. Mosaic fetches the item details from your Mimir instance.
2. The selected artifact URL (highres or proxy) is downloaded.
3. Mimir metadata (item ID, artifact type, connection details) is stored in `videos.source_info`.
4. Downstream tiles (e.g. News UK, Sun) that generate Premiere Pro projects use this metadata to link clips back to Mimir.

## Agent graph best practices

* For "shorter/tighter" edits, place `Rough Cut` and/or `Clips` before style-heavy nodes.
* Place `Reframe` before `Captions`, `Cinematic Captions`, `Motion Graphics`, and `Watermark` so overlays are composed against final framing.
* Keep `update_params` minimal and explicit (only send fields you want to override).

## Publish to social after render

After run completion, retrieve `outputs[].video_url` from `GET /agent_run/[run_id]` and send that URL in `media_urls` to [`POST /social/post`](/api/social/post-social-post).

## Response

```json theme={null}
{
  "run_id": "7f8d9c2b-4a6e-8b3f-1d5c-9e2f3a4b5c6d"
}
```

The `run_id` is used to track the progress of your agent run.
