Durable HTTP Jobs
Stores an HTTP request, executes it on managed workers, retries failures within a finite policy, and keeps every attempt with a terminal status.
What durable http jobs does
Stores an HTTP request, executes it on managed workers, retries failures within a finite policy, and keeps every attempt with a terminal status.
When to use durable http jobs
- Calling a flaky third-party API
- Work that must outlive the web request
- Calling an agent's HTTP endpoint with retries
Authentication
Send an API key as a bearer token. Keys are shown once, belong in a server environment, and are bound to one environment: flw_test_ keys act in test and flw_live_ keys in live.
Authorization: Bearer flw_test_••••Endpoint
POST https://api.flowyn.dev/v1/jobsRequest
Send an Idempotency-Key so a retried request cannot create a duplicate. The body is JSON.
curl -X POST https://api.flowyn.dev/v1/jobs \
-H "Authorization: Bearer $FLOWYN_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: sync-invoice-881" \
-d '{
"url": "https://api.example.com/reports/generate",
"method": "POST",
"headers": {
"Content-Type": "application/json"
},
"body": "{\"report\":\"monthly\"}",
"timeout_ms": 10000,
"max_attempts": 5
}'Response
Flowyn returns HTTP 202. The response is abridged here; the OpenAPI document lists every field.
{
"id": "6a2f1c9e-8b4d-4f3a-a5e7-2c9d0b1e4f83",
"environment": "test",
"kind": "http",
"status": "queued",
"method": "POST",
"url": "https://api.example.com/reports/generate",
"attempt_count": 0,
"max_attempts": 5,
"run_at": "2026-09-30T09:14:02Z",
"request_id": "req_5f2a9c1e7b3d4a6f8e0c2b1d",
"created_at": "2026-09-30T09:14:02Z"
}Lifecycle
POST /v1/jobsstores the call and returns HTTP 202. Nothing has been sent yet.- A worker claims the job with a lease and makes the request.
- A 2xx completes the job. A timeout, connection error, 408, 429, or 5xx records a failed attempt and schedules a retry.
- Other 4xx responses fail the job without a retry.
- When every attempt fails, the job ends
exhausted. Read the attempts withGET /v1/jobs/{id}/attempts.
Status values
| Status | Meaning |
|---|---|
| queued | Stored, waiting for a worker. |
| delayed | Waiting for run_at or a retry delay. |
| running | An attempt is in flight. |
| retrying | The last attempt failed and another is scheduled. |
| completed | A 2xx response was received. |
| failed | A response that is not retried, such as a 404. |
| exhausted | Every attempt failed. |
| cancelled | Cancelled with POST /v1/jobs/{id}/cancel. |
Retries
The wait doubles from about one second with ±20% variation, capped at five minutes. A Retry-After header is honoured.
Idempotency
Send Idempotency-Key on create. Each outbound attempt carries Idempotency-Key: <job id> so the destination can deduplicate.
Errors
| Status | type | Meaning |
|---|---|---|
| 400 | invalid_request | The body is not valid JSON, a field has the wrong type, or the body is over 1 MiB (body_too_large). |
| 401 | unauthorized | Missing, malformed, or revoked API key. |
| 402 | billing_error | The monthly credit allowance is used (credit_limit_exceeded). Reads keep working. |
| 403 | forbidden | The key lacks the ability this call needs (ability_required). |
| 404 | not_found | The id does not exist in this environment. |
| 409 | conflict | For example idempotency_mismatch: the Idempotency-Key was used with a different body. |
| 422 | invalid_request | A field value is out of range, for example invalid_timeout. |
| 429 | rate_limited | Too many requests (rate_limit_exceeded). Wait for Retry-After seconds. |
| 5xx | server_error | Flowyn failed. The body carries an error_id to quote to support. |
Limits
timeout_ms100–30,000 (default 10,000)max_attempts1–20 (default 5)bodyis a string of up to 65,536 characters- Up to 16 headers
Read it back
Keep the id and read the resource whenever you need its current state.
curl https://api.flowyn.dev/v1/jobs/6a2f1c9e-8b4d-4f3a-a5e7-2c9d0b1e4f83 \
-H "Authorization: Bearer $FLOWYN_API_KEY"Related
Next step
Run the same call on a cron with Schedules.
