Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.runflow.io/llms.txt

Use this file to discover all available pages before exploring further.

Long-running models push their final payload to a URL you control. You provide the URL on the request; Runflow POSTs the result when the run finishes.

Pattern

  1. Call POST /v1/models/{model_id}/runs with callback_url, where {model_id} is the slash-delimited provider/model path shown on the model page.
  2. Save the returned id. Callback payloads call the same value run_id.
  3. Run finishes in the background.
  4. Runflow POSTs to callback_url.
  5. Your handler returns 200 OK within a few seconds.

Callback payload

The callback body is an event envelope, frozen at delivery time:
{
  "event": "run.completed",
  "run_id": "01J0...",
  "status": "succeeded",
  "output": { "image_urls": ["https://..."] },
  "duration_ms": 102345,
  "created_at": "2026-05-06T10:00:00.000+00:00",
  "completed_at": "2026-05-06T10:01:42.000+00:00",
  "metadata": null
}
FieldNotes
eventOne of run.completed, run.failed, run.cancelled, run.partial_succeeded.
run_idUUIDv7 of the run. Match against the id from your POST /runs response.
statusTerminal callback status. Run records expose the same value as status_code on GET /v1/runs/{id}.
outputThe normalized model output on success, an error envelope on failure, or null if cancelled. Batch callbacks use a self-describing {items, succeeded, failed, cancelled, total} envelope, see the OpenAPI for the full shape.
duration_msTotal run wall-clock time.
created_at, completed_atISO 8601, +00:00 offset (not Z) so HMAC verification stays byte-equivalent.
metadataWhatever you passed at run creation, verbatim.
Output URLs are presigned and time-limited. Download or re-upload them to your own storage on receipt. Batch callbacks ship the same envelope but with batch_id instead of run_id.

Verify the source

Create a callback secret and Runflow signs every callback with HMAC-SHA256:
curl -X POST https://api.runflow.io/v1/callback-secrets \
  -H "Authorization: Bearer $RUNFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"label": "production"}'
Save the returned plain_secret. Runflow then sends Runflow-Signature: <hmac-hex> on every callback (alongside a Runflow-Request-Id for log correlation). See Verify callback signatures for handler code.

Retries

Runflow retries failed callbacks (non-2xx response, timeout, connection error) on an exponential schedule. Inspect attempts with GET /v1/runs/{run_id}/callback.

Manual redelivery

Replay a callback at any time:
curl -X POST https://api.runflow.io/v1/runs/{run_id}/callback-redeliveries \
  -H "Authorization: Bearer $RUNFLOW_API_KEY"

Local development

Your laptop is not reachable from the public internet. Tunnel it:
ngrok http 3000
# use the https://abc123.ngrok-free.app URL as callback_url

Verify signatures

HMAC verify in Node and Python.

Callback delivery API

History, redelivery, and secrets.