Tasks

Migrate a task to a newer workflow version

Moves an open task onto a newer version of its workflow. A state the target version also declares maps to itself; state_map maps a state it lacks. The payload is re-validated against the target payload_schema. The mapped state's on_enter is not fired: transition the task when you want the target's automation. A task with a dispatch in flight or a transition pending approval is refused, since both belong to the version they started under. Recorded in history as a row with transition: null and both versions.

post/v1/projects/{project_id}/tasks/{task_id}/migrate

Request

  • Base URL: https://api.naturali.ai
  • URL: https://api.naturali.ai/v1/projects/{project_id}/tasks/{task_id}/migrate
  • Auth: one of:
    • HTTP bearer
    • OAuth 2 (authorization code, authorization URL https://api.naturali.ai/authorize, token URL https://api.naturali.ai/token, scopes: mcp:access)

Path parameters

task_idstring required

The task to migrate.

Request body

to_versioninteger required

The workflow version to move the task onto; newer than its current one.

state_mapobject

Current state name to a state the target version declares. Required only for a state the target lacks; an entry for a state both declare overrides the identity mapping.

Response

The task on the target version

idstring
project_idstring
workflow_idstring
workflow_versioninteger nullable

The workflow version this task runs on, fixed when the task was created. Transitions, approval gates and payload validation all resolve through it, so editing the workflow never re-shapes a task already in flight. null for tasks created before pinning existed, which run on the live definition.

titlestring
statestring
status'open' | 'closed'
payloadobject

Caller-owned task data; input to guards (as task.payload) and dispatch mappings. The engine never writes into it except the workflow's declared payload_writes.

metadataMetadataBag

Caller-owned annotations on a resource, stored as the object they were written as: the types a value was written with are the types a read returns, so a filter can ask an ordering question about a number. Unlike other body fields, keys are stored and returned verbatim in the casing supplied — they are not converted between snake_case and camelCase.

No key is reserved, and that is the point: every piece of state the platform owns lives in its own typed column, so nothing written here reaches platform state. The platform never reads the bag — it is not an IAM context, not a policy input and not part of a prompt — which is what separates it from a tag bag.

last_resultunknown
assigneestring nullable
active_dispatchobject nullable

{ kind, id, status } of the current state's dispatch, if any. kind is generation, orchestration_run or tool_call; a tool_call always carries a null id, since a direct tool call leaves no addressable record. Carries an additional attempt (1-based) while the state's on_enter.retry policy is in effect.

automation_status'running' | 'completed' | 'failed' | 'unrouted' | 'paused' | 'null' nullable

Status of the current state's dispatch. null until a state with an automation is entered. paused means an operator pause suppressed this state's on_enter before it ran, so resume-task will start it.

pause_requested_atstring date-time nullable

When an operator paused this task's automation, or null when no pause is in force.

pause_reasonstring nullable

The reason supplied with the pause, when one was.

automation_chain_depthinteger

Server-owned. How many machine-driven transitions have run back-to-back with no outside intervention — a dispatch outcome routed through on_complete/on_failure, or a transition-task call made by a dispatched run or agent with its run-as token. Any move by a person, a plain API key, or an approval resolution resets it to 0. Once it would exceed the server's limit (TASK_AUTOMATION_CHAIN_LIMIT, default 50) the next such transition is refused with TASK_AUTOMATION_CHAIN_LIMIT, bounding a cycle composed across workflows and orchestrations.

pending_transitionstring nullable

The name of a requires_approval transition parked awaiting a human decision. Non-null while an ApprovalItem gates the move; the task stays in its current state and no other transition may fire until the approval resolves.

entered_state_atstring date-time
created_atstring date-time
updated_atstring date-time

Example response

{
  "workflow_version": 1,
  "metadata": {
    "author": "John",
    "revision": 2
  }
}

Changes

No recorded changes to this operation across all 1 revision of this API.