Instance Recovery
When an automated task fails, a process token ends up in the wrong element, or you need to reprocess a case from scratch, Stateway provides targeted recovery operations that let you intervene without recreating the entire instance.
When to Use Each Mechanism
| Situation | Mechanism |
|---|---|
| Automated task failed | Token Retry |
| Token arrived at the wrong element | Token Move |
| Token is stuck in an event that will never fire | Token Cancel |
| Need to re-execute an already-completed step | Token Add |
| Need to reprocess the entire case from the beginning | Instance Re-run |
All operations require the instances:write scope and are fully recorded in the audit log.
Reading the Current State
Before intervening, inspect the instance and its tokens.
Request:
curl https://api.stateway.io/v1/instances/{instanceId} \
-H "X-API-Key: sw_live_your_key"
Response:
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "error",
"error": "Service task 'callPaymentApi' failed: HTTP 502"
}
}
List all tokens to find which one is blocked:
Request:
curl https://api.stateway.io/v1/instances/{instanceId}/tokens \
-H "X-API-Key: sw_live_your_key"
Response:
{
"data": [
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"element_id": "callPaymentApi",
"element_type": "serviceTask",
"status": "dead"
}
]
}
Token Retry
Use token retry when a serviceTask, businessRuleTask, or sendTask failed and left the instance in error status — service tasks have no automatic retry (see Service Tasks). The retry creates a new token at the same element and restarts execution from that point.
Prerequisites:
- Instance status:
error - Token status:
dead - Element type:
serviceTask,businessRuleTask, orsendTask
Request:
curl -X POST https://api.stateway.io/v1/instances/{instanceId}/tokens/{tokenId}/retry \
-H "X-API-Key: sw_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"variables": {
"payment_endpoint": "https://payments.example.com/v2/charge"
},
"reason": "External service restored after maintenance"
}'
The variables field applies an additive patch to the instance variables before re-execution — useful to correct data that caused the failure. The reason field is recorded in the audit log.
Response:
{
"data": {
"new_token_id": "a3d2b1c4-1234-5678-9abc-def012345678",
"original_token_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"element_id": "callPaymentApi",
"element_type": "serviceTask",
"instance_status": "running",
"variables_patched": ["payment_endpoint"]
}
}
The instance status returns to running and execution resumes automatically.
For userTask elements or gateways, use Token Move instead — token retry is only available for task types that generate service jobs.
Token Move
Use token move when a token is at the wrong element — for example, a gateway evaluated a condition with inconsistent data. Moving a token marks the current token as dead and creates a new one at the target element, then resumes execution from there. Token Move also recovers a token that already died because its output could not be persisted (a variables merge failure) — regardless of element type, including userTask and timer events, which token retry does not cover. The variables that failed to merge are lost permanently; moving to the same element re-executes its handler, which for a callActivity means running a sub-instance that already ran a second time.
Prerequisites:
- Instance status:
runningorerror - Token status:
active,waiting, ordead(deadonly when instance status iserror) target_element_idmust exist in the process definition
Request:
curl -X POST https://api.stateway.io/v1/instances/{instanceId}/tokens/{tokenId}/move \
-H "X-API-Key: sw_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"target_element_id": "sendConfirmationEmail",
"variables": {
"skip_payment": true
},
"reason": "Payment processed manually outside the system"
}'
Response:
{
"data": {
"new_token_id": "b5e3c2d1-2345-6789-abcd-ef0123456789",
"original_token_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"from_element_id": "callPaymentApi",
"to_element_id": "sendConfirmationEmail",
"instance_status": "running"
}
}
Be careful when moving a token to a position after a parallel gateway (parallelGateway). If the gateway is waiting for other branches to complete, the gateway may end up in an unresolvable state. Inspect all active tokens before moving.
Token status dead alone does not guarantee the token is the cause of the instance's current error status — an instance can have more than one dead token in its history. Inspect GET /instances/{id}/tokens before moving a dead token to confirm you are recovering the one that actually failed.
Token Cancel
Use token cancel when a token is stuck in an intermediateCatchEvent or userTask that will never complete. Cancelling removes the token from the flow without replacing it — the instance continues with its remaining active tokens.
Prerequisites:
- Instance status:
running - Token status:
activeorwaiting - The token must not be the only active token in the instance
Request:
curl -X DELETE https://api.stateway.io/v1/instances/{instanceId}/tokens/{tokenId} \
-H "X-API-Key: sw_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"reason": "External event will never arrive — cancelled manually"
}'
Response:
{
"data": {
"cancelled_token_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"element_id": "waitForApprovalEvent",
"remaining_active_tokens": 2
}
}
If the cancelled token was associated with a user task, that task is also cancelled automatically.
You cannot cancel the last active token in an instance — doing so would leave the instance running with no active flow. Use instance termination (POST /v1/instances/{id}/terminate) if you need to stop the instance entirely.
Token Add
Use token add when you need to re-execute a step that has already completed, or force execution of a parallel step that should have been triggered. A new token is placed at the specified element without affecting any existing tokens.
Prerequisites:
- Instance status:
running element_idmust exist in the process definition
Request:
curl -X POST https://api.stateway.io/v1/instances/{instanceId}/tokens \
-H "X-API-Key: sw_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"element_id": "sendNotificationEmail",
"variables": {
"notification_type": "manual_trigger"
},
"reason": "Notification failed due to network error — manual resend"
}'
Response:
{
"data": {
"new_token_id": "c7f4d3e2-3456-789a-bcde-f01234567890",
"element_id": "sendNotificationEmail",
"element_type": "serviceTask"
}
}
Execution begins immediately — the engine processes the new token in the background.
Instance Re-run
Use instance re-run when you need to reprocess a case from the beginning — for example, after correcting the process definition or fixing the initial input data. Re-run creates an independent new instance that copies the initial variables from a source instance, with an optional patch.
The source instance is not modified and can be in any status (completed, running, error).
Request:
curl -X POST https://api.stateway.io/v1/instances \
-H "X-API-Key: sw_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"source_instance_id": "550e8400-e29b-41d4-a716-446655440000",
"definition_key": "credit-approval",
"variables": {
"credit_limit": 50000
},
"metadata": {
"source": "manual-rerun"
}
}'
The variables field is merged on top of the source instance's initial variables — fields you provide override the originals, fields you omit are copied as-is.
Response:
{
"data": {
"id": "661f9511-f30c-52e5-b827-557766551111",
"definition_key": "credit-approval",
"status": "running",
"metadata": {
"source": "manual-rerun",
"source_instance_id": "550e8400-e29b-41d4-a716-446655440000"
},
"started_at": "2026-05-27T14:00:00.000Z"
}
}
The source_instance_id is stored in the new instance's metadata for traceability.
You can re-run against a different definition_key or pin a specific definition_version. If definition_version is omitted, the engine uses the latest active version of the specified definition.
Auditability
Every recovery operation records an entry in the audit log and dispatches a webhook event if you have an active subscription. See Webhooks for subscription setup.
| Operation | Audit log action | Webhook event |
|---|---|---|
| Token Retry | instance.token_retried | instance.token_retried |
| Token Move | instance.token_moved | instance.token_moved |
| Token Cancel | instance.token_cancelled | instance.token_cancelled |
| Token Add | instance.token_added | instance.token_added |
| Instance Re-run | instance.rerun_created | instance.rerun_created |