# Migrate Robots webhooks from Beta to GA

Handle versioned Robots job and Directive-run events before you start creating jobs and Directives through v1.

The Robots Beta API is v0 and the GA API is v1, and each sends its own webhook events. Deploy support for v1 webhook events **before** you start creating jobs or Directives through `/robots/v1`. The API version that created a job or Directive determines both its event type and payload. Existing v0 resources continue sending v0 events, including events delivered after your application starts creating v1 resources.

<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>

Use [Migrate Robots from Beta to GA](/docs/guides/robots-migrate-to-v1) for request and output mappings, and [Migrate Robots Directives from Beta to GA](/docs/guides/robots-migrate-directives-to-v1) for switching asset creation to v1 Directives.

## Accept both event namespaces

| Event family | V0 | V1 |
| :-- | :-- | :-- |
| Job lifecycle | `robots.job.{workflow}.{event}` | `robots.v1.job.{workflow}.{event}` |
| Directive-run lifecycle | `robots.directive_run.{event}` | `robots.v1.directive_run.{event}` |

Workflow names in event types use underscores: `find_key_moments`, `translate_audio`, or `generate_engagement_insights`. HTTP workflow paths continue using hyphens.

For example, `robots.job.translate_audio.completed` becomes `robots.v1.job.translate_audio.completed`. Directive-run events use `created`, `completed`, `partial`, and `errored` in both namespaces.

Update exact-match handlers, prefix checks, queues, analytics rules, and any event-type allowlists in your own infrastructure. A handler or downstream filter that only accepts `robots.job.*` will miss `robots.v1.job.*`.

Keep the existing [webhook signature verification](/docs/core/verify-webhook-signatures), duplicate-delivery handling, and retry behavior. The new namespace does not replace those requirements.

## Route payloads by event type

Use the event's `type` to choose the parser. Don't pick the parser based on which version your app currently creates jobs with: v0 and v1 events arrive side by side during the migration.

The following example dispatches an **already verified** webhook event. Each handler then parses the payload for its version.

```javascript
function handleRobotsEvent(event) {
  if (
    event.type.startsWith('robots.v1.job.') ||
    event.type.startsWith('robots.v1.directive_run.')
  ) {
    return handleV1RobotsEvent(event);
  }

  if (
    event.type.startsWith('robots.job.') ||
    event.type.startsWith('robots.directive_run.')
  ) {
    return handleV0RobotsEvent(event);
  }
}
```

The envelope is unchanged: `data` is the job or run object itself, in both versions. Do not add an extra `job` or `directive_run` wrapper to your parser.

For example, this is an excerpt from a v1 caption-translation event:

```json
{
  "type": "robots.v1.job.translate_captions.completed",
  "data": {
    "id": "rjob_example",
    "workflow": "translate-captions",
    "status": "completed",
    "parameters": {
      "asset_id": "YOUR_ASSET_ID",
      "track_id": "SOURCE_TRACK_ID",
      "output_language_code": "es"
    },
    "outputs": {
      "track_id": "NEW_TRACK_ID",
      "replaced_track_ids": ["DELETED_TRACK_ID"]
    }
  }
}
```

This excerpt omits unchanged job and event fields. Download URLs remain available where the workflow supplies them. Replacement IDs are optional and appear only when deletions were recorded.

## Update job payload parsers

V1 job webhook data uses the same v1 parameter and output field names as a v1 job detail response. Update these together:

* Translation targets use `parameters.output_language_code`.
* Key-moment duration preferences use `parameters.target_duration` in seconds.
* Thumbnail times use `time`; moment and cue intervals use `start_time` and `end_time`. Values are seconds and can be fractional.
* Caption editing, caption translation, and audio translation return `outputs.track_id`.
* Track replacements use `replaced_track_ids[]` strings instead of `replaced_tracks[]` objects or singular aliases.
* Premium captions report `detected_language_code`.
* Chapter asset update outcomes use `asset_updates.chapters`.
* Deprecated parameters and output aliases are absent.

Use the [full response mapping](/docs/guides/robots-migrate-to-v1#update-response-parsing) to update each workflow you consume. Keep a v0 parser for old jobs instead of applying v1 renames or unit conversions to every incoming event.

When fetching more details after an event, use `/robots/v1/jobs/{workflow}/{JOB_ID}` for v1-created jobs and `/robots/v0/jobs/{workflow}/{JOB_ID}` for v0-created jobs. A wrong-version detail request returns `404`.

## Update Directive-run payload parsers

V1 events deliver the same run representation used by the v1 start, list, and detail endpoints. For example, a created event has the following `type` and `data`:

```json
{
  "type": "robots.v1.directive_run.created",
  "data": {
    "id": "drvrun_example",
    "directive_id": "drv_example",
    "subject_id": "YOUR_ASSET_ID",
    "status": "pending",
    "node_states": [],
    "started_at": 1746403300,
    "completed_at": null
  }
}
```

V0 Directive-run webhook data uses `asset_id`; v1 uses `subject_id`. Nodes use `workflow` instead of `workflow_name`. Nodes waiting on another binding report `waiting_for_source_bindings` and `source_bindings[]` instead of `waiting_for_source_workflow` and `source_workflows[]`. Failure details remain in `reason`.

The webhook run identifier is `data.id` in both versions. The `run_id` → `id` rename applies to v0 **HTTP** run responses. See [run-response changes](/docs/guides/robots-migrate-directives-to-v1#update-run-response-parsing) for the complete mapping.

Runs started by a Directive, and the jobs they dispatch, send events for the Directive's version. A v0 Directive keeps sending v0 events after you switch your own job requests to v1. [Create and attach a v1 Directive](/docs/guides/robots-migrate-directives-to-v1#test-and-switch-automatic-triggers) to move that Directive's events to v1.

## Test before switching to v1

1. Deploy handlers for both versions while you're still creating jobs through v0.
2. Create one v1 job for each workflow your integration uses. Verify event routing, times parsed as seconds, any track IDs, and follow-up GET requests.
3. If you use Directives, start a v1 run and verify both its run event and its child-job events. Check `partial` and `errored` handling too.
4. Confirm your consumer still processes a v0 delivery. Retries or outstanding runs can deliver v0 events after the cutover.
5. Switch new requests to v1, and keep monitoring both namespaces.

If you switch new requests back to v0, keep both parsers deployed: jobs and Directives already created through v1 keep sending v1 events. Remove v0 handling only after you've stopped creating v0 jobs, your v0 Directives have stopped running, and remaining deliveries have been accounted for.
