# Migrate Robots Directives from Beta to GA

Create v1 Directives, convert binding and resource configuration, and switch asset creation to the new Directive without losing access to v0 runs.

A Directive keeps the API version used to create it. To move a Directive from the Robots Beta API (v0) to the GA API (v1), create a new Directive with v1 configuration, test it, then replace the old Directive ID in your asset-creation integrations. The existing Directive does not change version.

<Callout type="info" title="Your existing Directives keep running">
  Nothing changes for your existing Directives today. They stay on v0 and keep running as normal: assets created with a v0 Directive ID still trigger it, and its runs, child jobs, and webhooks work as they do now. Migrate them to v1 before the v0 support period ends, six months after the v1 launch.
</Callout>

<Callout type="info" title="Migrate with your coding agent">
  Paste this prompt into your agent to review your integration, apply the relevant changes, and test the migration.

  <div />
</Callout>

Start with the [Robots API migration guide](/docs/guides/robots-migrate-to-v1) for workflow parameter and output changes. Update and deploy [webhook handlers](/docs/guides/robots-migrate-webhooks-to-v1) before starting v1 runs. See the <ApiRefLink href="/docs/api-reference/robots/directives">Directives API reference</ApiRefLink> for the complete configuration.

## Choose how to create the v1 copy

### From the Dashboard

Open an existing v0 Directive and choose **Create v1 copy**. Review the workflows, resources, and options, then create the new Directive. Legacy options that v1 no longer supports are omitted from the copy. Remove workflows unavailable in v1, such as Find Scenes, before creating it; replace scene analysis with Analyze Structure where appropriate.

The copy has a new ID. The v0 Directive stays in place, and integrations that attach its ID keep triggering it. Creating a copy does not move asset references, modify external integrations, or delete the original.

### From the API

1. Fetch the existing configuration through `GET /robots/v0/directives/{DIRECTIVE_ID}`.
2. Convert it using the mappings below. Send configuration fields only, omitting response metadata such as `id`, timestamps, and `_links`.
3. Create the replacement with `POST /robots/v1/directives`.
4. Store the returned v1 Directive ID alongside its API version.

## Convert the configuration

| Configuration field | V0 | V1 |
| :-- | :-- | :-- |
| Workflow bindings | `workflows[]` | `bindings[]` |
| Binding options | `params` | `parameters` |
| Mux API source options | `source.params` | `source.parameters` |
| Caption resource selector | `kind: "caption"` | `kind: "subtitles"` |
| Track resource language | `language` | `language_code` |
| Caption generation source audio language | `source.params.source_audio_language` | `source.parameters.source_audio_language_code` |
| Shot-generation action | `action: "request_shots"` | `action: "generate_shots"` |

Binding `workflow`, binding/resource `reference_id`, `inputs[]`, and `source.binding` keep their names. Preserve reference IDs so dependencies still resolve. Don't put `asset_id` or the source `track_id` in binding parameters; the Directive supplies them.

Apply the [workflow parameter changes](/docs/guides/robots-migrate-to-v1#update-request-paths-and-parameters) inside every binding too: translation targets become `output_language_code`, key-moment target durations become seconds, and deprecated fields are removed. Replace `find-scenes` bindings with an appropriately configured `analyze-structure` binding.

For example, this v0 configuration generates a caption resource, then translates it:

```json
{
  "name": "Generate and translate captions",
  "subject": { "type": "video.asset" },
  "resources": [
    {
      "reference_id": "captions_en",
      "type": "video.asset.track",
      "kind": "caption",
      "language": "en",
      "source": {
        "via": "mux_api",
        "action": "generate_subtitles",
        "params": {
          "language_code": "en",
          "source_audio_language": "en-US"
        }
      }
    }
  ],
  "workflows": [
    {
      "reference_id": "translate_es",
      "workflow": "translate-captions",
      "inputs": ["captions_en"],
      "params": { "to_language_code": "es" }
    }
  ]
}
```

Save this v1 configuration as `directive-v1.json`:

```json
{
  "name": "Generate and translate captions v1",
  "subject": { "type": "video.asset" },
  "resources": [
    {
      "reference_id": "captions_en",
      "type": "video.asset.track",
      "kind": "subtitles",
      "language_code": "en",
      "source": {
        "via": "mux_api",
        "action": "generate_subtitles",
        "parameters": {
          "language_code": "en",
          "source_audio_language_code": "en-US"
        }
      }
    }
  ],
  "bindings": [
    {
      "reference_id": "translate_es",
      "workflow": "translate-captions",
      "inputs": ["captions_en"],
      "parameters": { "output_language_code": "es" }
    }
  ]
}
```

Create it through v1:

```bash
curl https://api.mux.com/robots/v1/directives \
  -u "$MUX_TOKEN_ID:$MUX_TOKEN_SECRET" \
  -H "Content-Type: application/json" \
  -d @directive-v1.json
```

Unknown fields are ignored, so a successful create request does not mean obsolete optional fields still take effect. Review the resulting configuration and its behavior on a test asset.

## Update list and detail handling

`GET /robots/v1/directives` returns slim summaries of **both v0 and v1 Directives**, with `id`, `name`, `created_at`, `updated_at`, and `_links.self`. It no longer returns the full configuration in every list entry.

Follow `_links.self.href` to get the full configuration. A summary with a `/robots/v0/directives/...` link still represents a v0 Directive even though you discovered it through the v1 list. The v0 list continues returning full v0 configurations.

Individual detail, delete, and run routes require the version that created the Directive. A version mismatch returns `404`; the v1 detail endpoint only returns v1 Directives. Keep the version that created each Directive with any saved Directive ID. If an older saved link contains only an ID, try the v1 detail endpoint and fall back to v0 **only on 404**, not authentication or server errors.

For a v0 Directive, keep using `/robots/v0/directives/{id}/runs` and its run-detail routes while it remains active. For a v1 Directive, use the corresponding v1 routes.

## Update run-response parsing

V1 uses one run representation across start responses, lists, detail reads, and webhook `data`. It includes `id`, `directive_id`, `subject_id`, `status`, `node_states`, `started_at`, and `completed_at`.

| Surface | V0 | V1 |
| :-- | :-- | :-- |
| HTTP run identifier | `run_id` | `id` |
| Run relationship | V0 HTTP responses vary by operation | `directive_id` consistently identifies the Directive. |
| Dispatched/waiting node workflow | `workflow_name` | `workflow` |
| Source dependency status | `waiting_for_source_workflow` | `waiting_for_source_bindings` |
| Source dependency references | `source_workflows[]` | `source_bindings[]` |
| Directive-run webhook asset | `data.asset_id` | `data.subject_id` |

`source_bindings[]` contains binding reference IDs, not workflow names. Node failure details remain in `reason`. Run timestamps are still Unix seconds. The manual start request still uses `{ "asset_id": "YOUR_ASSET_ID" }`; `subject_id` is a response field, not a renamed request parameter.

Child jobs inherit the Directive's version. Fetch their details through that version too, rather than assuming that every job visible in your dashboard or list is v1.

## Test and switch automatic triggers

A Directive triggers automatically when its ID is attached to an asset at creation. Test the new Directive, then switch those attachments to its ID.

1. Run the new Directive manually against a test asset:

```bash
curl https://api.mux.com/robots/v1/directives/YOUR_V1_DIRECTIVE_ID/runs \
  -u "$MUX_TOKEN_ID:$MUX_TOKEN_SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "asset_id": "YOUR_TEST_ASSET_ID" }'
```

2. Verify the v1 run, its child-job outputs, and the `robots.v1.directive_run.*` and `robots.v1.job.*` webhook handlers. V1 caption track selection rules also apply when a Directive dispatches jobs.
3. Replace the v0 Directive ID in asset-creation requests, upload settings, templates, and any stored integration configuration with the **new v1 ID**. The Video API route itself does not change:

```bash
curl https://api.mux.com/video/v1/assets \
  -u "$MUX_TOKEN_ID:$MUX_TOKEN_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": [{ "url": "https://example.com/my-video.mp4" }],
    "playback_policies": ["public"],
    "directives": [{ "id": "YOUR_V1_DIRECTIVE_ID" }]
  }'
```

4. Confirm a newly created asset triggers the v1 Directive. A Directive runs on the version that created it; there is no version field to add to the Video request's `directives[]` entry.
5. Keep v0 history and webhook handling available until the old Directive has stopped running and outstanding deliveries have arrived. Delete the old Directive through its v0 route once you no longer need new runs from it.

<Callout type="warning">
  Attaching both the old and new Directive IDs can start both Directives. Their child jobs can both execute and consume units. Creating the v1 copy does not replace the old attachment automatically.
</Callout>

To roll back during the v0 support period, restore the old v0 ID in the integrations that create assets. Keep the original Directive until you have verified the cutover; deleting it removes that rollback option.

## Migration checklist

* \[ ] Every binding and source uses the v1 field names and units.
* \[ ] Legacy options and workflows unavailable in v1 have been reviewed or replaced.
* \[ ] The new Directive has been tested manually, including caption track selection and asset updates.
* \[ ] List consumers fetch configuration through `_links.self`.
* \[ ] Run parsers and child-job reads use the correct version.
* \[ ] Webhook handlers accept both v0 and v1 events.
* \[ ] Asset-creation integrations reference the new v1 Directive ID.
* \[ ] A newly uploaded asset has successfully triggered the new Directive.
