Requests

Requests are the units of work in Zeplo. Each request represents an HTTP call that Zeplo will execute on your behalf.

Enqueuing a request

Send a POST to your queue’s enqueue endpoint:

curl -X POST "https://v2-api.zeplo.io/queues/QUEUE_ID/enqueue" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "POST",
    "url": "https://your-api.com/webhook",
    "headers": {"Content-Type": "application/json", "X-Secret": "s3cret"},
    "body": "{\"order_id\": 789}",
    "delay": 0,
    "retries": 3,
    "requestId": "order-789"
  }'
Field Type Default Description
method string POST HTTP method (GET, POST, PUT, PATCH, DELETE)
url string required Target URL to call
headers object {} HTTP headers to include
body string null Request body (typically JSON-encoded)
delay int 0 Seconds to wait before executing
retries int 3 Retry count (Zeplo will make retries + 1 total attempts)
requestId string null User-defined request ID used for idempotency within a queue

Legacy v1 compatibility headers

The public enqueue endpoint also supports a subset of legacy v1 control headers:

  • X-Zeplo-Delay
  • X-Zeplo-Delay-Until
  • X-Zeplo-Retry
  • X-Zeplo-Interval
  • X-Zeplo-Cron
  • X-Zeplo-Timezone

Behavior:

  • X-Zeplo-Retry is used when body retries is omitted
  • X-Zeplo-Interval creates a recurring interval schedule
  • X-Zeplo-Cron creates a recurring cron schedule
  • X-Zeplo-Timezone sets the schedule timezone
  • if both X-Zeplo-Interval and X-Zeplo-Cron are present, interval wins

When X-Zeplo-Interval or X-Zeplo-Cron is used, the enqueue endpoint returns a schedule-shaped response with scheduleId, type, nextRun, and createdAt.

Request lifecycle

Every request moves through these statuses:

  1. Pending — Queued and waiting to be processed
  2. Scheduled — Delayed or scheduled for future execution
  3. Processing — Currently being executed
  4. Completed — Successfully executed (2xx response)
  5. Failed — All attempts exhausted without success
  6. Cancelled — Manually cancelled before execution

Viewing a request

curl "https://v2-api.zeplo.io/workspaces/WS_ID/requests/REQUEST_ID" \
  -H "Authorization: Bearer YOUR_TOKEN"

Response:

{
  "id": "req_xyz789",
  "queue": "q_abc123",
  "status": "completed",
  "method": "POST",
  "url": "https://your-api.com/webhook",
  "response_status_code": 200,
  "response_time": 145,
  "attempts": 1,
  "max_attempts": 3,
  "created": "2026-02-25T12:00:00Z",
  "completed_at": "2026-02-25T12:00:01Z",
  "timeline": [
    {"status": "pending", "timestamp": "2026-02-25T12:00:00Z"},
    {"status": "processing", "timestamp": "2026-02-25T12:00:00.5Z"},
    {"status": "completed", "message": "HTTP 200", "timestamp": "2026-02-25T12:00:01Z"}
  ]
}

Idempotency

If you provide an idempotency_key, Zeplo ensures only one request with that key exists per queue. Duplicate enqueue calls with the same key return the existing request instead of creating a new one.

This is useful for ensuring exactly-once delivery in retry scenarios on your side.

What counts as a failure?

A request is considered failed if:

  • The HTTP response status code is ≥ 400
  • The request times out (30 second default)
  • The target URL is unreachable

Failed requests are automatically retried up to max_attempts. See Retry for details.

Large payloads

Request bodies larger than 256KB are automatically offloaded to cloud storage. This is transparent — you don’t need to do anything differently. The body is reconstructed when the request is executed.