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.
Migrate with your coding agent
Paste this prompt into your agent to review your integration, apply the relevant changes, and test the migration.
Use Migrate Robots from Beta to GA for request and output mappings, and Migrate Robots Directives from Beta to GA for switching asset creation to v1 Directives.
| 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, duplicate-delivery handling, and retry behavior. The new namespace does not replace those requirements.
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.
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:
{
"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.
V1 job webhook data uses the same v1 parameter and output field names as a v1 job detail response. Update these together:
parameters.output_language_code.parameters.target_duration in seconds.time; moment and cue intervals use start_time and end_time. Values are seconds and can be fractional.outputs.track_id.replaced_track_ids[] strings instead of replaced_tracks[] objects or singular aliases.detected_language_code.asset_updates.chapters.Use the full response mapping 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.
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:
{
"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 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 to move that Directive's events to v1.
partial and errored handling too.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.