How It Works
- Pass a
webhook_urlwhen you create a run - When the run finishes (
COMPLETED,FAILED, orCANCELLED), TinyFish sends aPOSTrequest to your URL - The payload contains the full run data — the same shape as
GET /v1/runs/{id}
Webhook delivery is non-blocking. If your endpoint is down, the run still succeeds — you can always fetch the result via the API.
Configuration
Addwebhook_url to any run creation endpoint. The URL must use HTTPS.
/run, /run-async, /run-sse, and /run-batch.
Payload
Your endpoint receives aPOST request with Content-Type: application/json:
Event Types
| Event | When |
|---|---|
run.completed | Run finished (check result for data) |
run.failed | Infrastructure error occurred |
run.cancelled | Run was manually cancelled |
Payload Fields
| Field | Type | Description |
|---|---|---|
event | string | Event type (e.g. run.completed) |
run_id | string | Unique run identifier |
status | string | COMPLETED, FAILED, or CANCELLED |
data | object | Full run data — same shape as GET /v1/runs/{id} |
data.result | object | null | Extracted data (when completed) |
data.error | object | null | Error details (when failed) |
data.steps | array | List of actions the agent took |
Screenshots are not included in webhook payloads to keep the payload size small. To get screenshots, call
GET /v1/runs/{id}?screenshots=base64 after receiving the webhook.Error Payload
When a run fails,data.error contains details about what went wrong:
Retry Behavior
TinyFish retries failed webhook deliveries automatically:| Behavior | Detail |
|---|---|
| Total attempts | 4 (1 initial + 3 retries) |
| Backoff | Exponential: 1s, 2s, 4s |
| Timeout | 10 seconds per attempt |
| 4xx responses | No retry (fails immediately) |
| 5xx responses | Retried with backoff |
| Network errors | Retried with backoff |
Receiving Webhooks
Here’s how to handle webhook events on your server:Best Practices
Respond within 10 seconds
Respond within 10 seconds
TinyFish waits up to 10 seconds for your response. Do heavy processing asynchronously — acknowledge the webhook immediately and handle the data in the background.
Handle duplicates idempotently
Handle duplicates idempotently
In rare cases (network retries, server restarts), you may receive the same webhook more than once. Use
run_id to deduplicate.Verify by fetching the run
Verify by fetching the run
For sensitive workflows, confirm the webhook data by calling
GET /v1/runs/{run_id} before acting on the payload.Return 2xx to acknowledge
Return 2xx to acknowledge
Any 2xx response acknowledges the webhook. Non-2xx responses trigger retries (except 4xx, which fail immediately).
Related
Runs
Understand run lifecycle and statuses
Endpoints
Choose sync, async, or streaming