AWS Step Functions wait for callback on an AI video run
Pause a Step Functions execution with .waitForTaskToken until an AI video run ends: park the task token, then return it when Sume's webhook arrives.

To make AWS Step Functions wait for a callback, append .waitForTaskToken to a Task state's Resource and pass the task token, $$.Task.Token, to whatever does the work. The execution pauses until something calls SendTaskSuccess or SendTaskFailure with that token, or until the state times out. For an AI video job, one task starts the job, and the job's webhook hands the token back.
AWS facts come from the Step Functions guide on service integration patterns, Lambda, the Task state, quotas, and error handling, plus the SendTaskSuccess and SendTaskFailure API reference. Sume facts come from Create a run, Runs and results, and Run webhooks. All were read on 2026-09-27. Sume has no Step Functions integration: your Lambda functions call its HTTPS API.
How does the callback pattern fit a Sume video run?
Split it into two states, so the run id is in the execution's data before the wait begins:
StartRun, a plain Lambda task, creates a Sume Format run whosecommunication.webhook_urlpoints at your receiver, and returns the run id. ItsIdempotency-Keycomes from the execution name, so a retried task gets the original run back: same key and same body return200with the original receipt, with no second run and no second charge.WaitForVideo, a Lambda task with.waitForTaskToken, hands a small function the run id and the token. The function stores the token under the run id in a table you own and returns, and the execution waits.- Your webhook receiver verifies Sume's signed POST, looks the token up by
run_id, and callsSendTaskSuccessorSendTaskFailure. - Keep
SUME_API_KEYserver-side; AWS recommends Secrets Manager over Lambda environment variables for API keys.
"StartRun": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"Parameters": {
"FunctionName": "arn:aws:lambda:region:account-id:function:start-sume-run",
"Payload": { "order.$": "$.order", "execution.$": "$$.Execution.Name" }
},
"ResultPath": "$.run",
"Next": "WaitForVideo"
},
"WaitForVideo": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke.waitForTaskToken",
"Parameters": {
"FunctionName": "arn:aws:lambda:region:account-id:function:park-task-token",
"Payload": { "run_id.$": "$.run.Payload.run_id", "token.$": "$$.Task.Token" }
},
"TimeoutSeconds": 6000,
"ResultPath": "$.video",
"Catch": [{ "ErrorEquals": ["States.Timeout"], "ResultPath": "$.timeout", "Next": "ReadRun" }],
"Next": "Publish"
}Which Step Functions settings does a video run need?
Most defaults assume short tasks. These are the ones to change or check:
| Setting | Value | Why |
|---|---|---|
| Workflow type | Standard | Express Workflows only support Request Response integrations, and an Express execution is capped at 5 minutes. |
Resource | arn:aws:states:::lambda:invoke.waitForTaskToken | Lambda supports Wait for Callback on Standard Workflows. A function ARN set directly in Resource can't take .waitForTaskToken. |
| Task token | $$.Task.Token | Up to 2,048 characters, and it only works when returned by a principal in the same AWS account. |
TimeoutSeconds | 6000 (100 minutes) | The default is 99,999,999. Sume force-finalizes a run as failed 90 minutes after created_at. |
HeartbeatSeconds | Leave unset | Sume sends one POST when a run completes or fails, and nothing before that. |
| Task output | A small JSON summary | SendTaskSuccess takes at most 262,144 bytes of output; Sume inlines receipts up to 1 MiB. |
Why not put the task token in the webhook URL?
It looks simpler, since the receiver would need no table. Two things break it. The token may not fit: it can be up to 2,048 characters, and Sume caps webhook_url at 2,048 characters, host and path included. And it defeats safe retries: the URL is part of the request body, and Sume answers the same key with a different body with 409 idempotency_conflict. A callback task that times out gets a new random token, so a retry carrying the new token in its URL is exactly that.
What should the webhook receiver send back?
The receiver is an ordinary webhook endpoint; AWS Lambda webhook receiver for Sume covers the function URL and the signature check. After the check:
- Look the token up by the envelope's
run_id. If it isn't stored yet, answer503: Sume retries a failed attempt, up to 10 attempts, and honors yourRetry-After. status: "OK": callSendTaskSuccesswith the token and a shortoutput, such as the run id andpayload.primary_output_url. A receipt over 1 MiB arrives withpayload: null, butstatusstill reports the outcome.status: "ERROR": callSendTaskFailurewitherrorset to Sume'serror.code(at most 256 characters) andcauseset to its message.- If Step Functions answers
TaskTimedOut, the token expired or its task already closed, for example because an earlier delivery already succeeded. Answer2xxanyway, or Sume keeps retrying. - Answer within 10 seconds, the time Sume gives each attempt, and dedupe on
request_id, which repeats on every retry.
How long should the state wait if no webhook comes?
Without a timeout, a task waiting for a token waits until the execution reaches the one-year quota. Set TimeoutSeconds past Sume's own deadline: a run in progress is force-finalized as failed 90 minutes after created_at, or sooner when it is older than 25 minutes and has been silent for 10. Long-form video is 15 to 30 minutes of work.
When TimeoutSeconds runs out, the state fails with States.Timeout, which the States.TaskFailed wildcard does not match, so catch it by name, as above, and route it to a ReadRun state that reads GET /v1/format-runs/{run_id} once. That read is how the execution learns about a run that never POSTs: a canceled run delivers no webhook, and an endpoint that refuses all 10 attempts leaves the run as it was, with nothing delivered. Your timeout doesn't stop the run or its spend either.
Sources
- Create a run
- Runs and results
- Run webhooks
- AWS Step Functions: Discover service integration patterns (read 2026-09-27)
- AWS Step Functions: Invoke an AWS Lambda function (read 2026-09-27)
- AWS Step Functions: Task workflow state (read 2026-09-27)
- AWS Step Functions: Service quotas (read 2026-09-27)
- AWS Step Functions: Handling errors (read 2026-09-27)
- AWS Step Functions API: SendTaskSuccess (read 2026-09-27)
- AWS Step Functions API: SendTaskFailure (read 2026-09-27)
- AWS Lambda: Working with environment variables (read 2026-09-27)
Related posts
More in Integrations
- Axios retry: retry a POST safely with an idempotency key
Use axios-retry for network errors, 429 and 5xx with exponential backoff, and retry a paid POST only when it carries an Idempotency-Key.
- Azure Functions timeout: don't wait for an AI video job
Azure Functions time out after 5 minutes by default on Consumption, and HTTP triggers must answer in 230 seconds. Submit video jobs with a callback.
- Bubble API Connector: generate AI video with the Sume API
Set up Bubble's API Connector for Sume: the key in a private header, a manual response so setup costs nothing, and a backend poll of the job.
- Claude Agent SDK MCP server: connect Sume with an API key
Add Sume's hosted MCP server to the Claude Agent SDK with an API-key header, allow only the tools you need, and dry-run paid calls before submitting.
Written by Sume