Getting started

Give Stafett a job and an HTTPS destination. Stafett stores the job, POSTs the payload to that URL, and handles retries and dead-lettering. The destination can be your own endpoint or a third-party API.

Mint an API token in the control plane. The secret is shown once; use it as a bearer token (stf_…) on every request below.

Enqueue a job

curl -X POST https://api.stafett.dev/enqueue \
  -H 'Authorization: Bearer stf_…' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://api.example.com/hooks/ship",
    "payload": {"order": 42}
  }'

Stafett returns 202 Accepted immediately:

{
  "id": "018f3b7c-6c4a-7b32-9f21-2c0a5e4d9b11",
  "status": "queued",
  "status_url": "/jobs/018f3b7c-6c4a-7b32-9f21-2c0a5e4d9b11"
}

The request schedules delivery; it does not wait for the destination to finish.

Check the result

Poll the returned status URL with the same bearer token:

curl https://api.stafett.dev/jobs/018f3b7c-6c4a-7b32-9f21-2c0a5e4d9b11 \
  -H 'Authorization: Bearer stf_…'

The status moves through queued, delivering, retrying, delivered, dead, or canceled.

Tip: follow one job live instead of polling. Same URL, add Accept: text/event-stream and use curl's -N so output is not buffered:

curl -N https://api.stafett.dev/jobs/018f3b7c-6c4a-7b32-9f21-2c0a5e4d9b11 \
  -H 'Authorization: Bearer stf_…' \
  -H 'Accept: text/event-stream'

You get a status event immediately, another on each change, then end when the job is finished and the connection closes. Details in the API reference.

Receive the delivery

Stafett POSTs the JSON payload to the url you supplied. Every delivery includes the Standard Webhooks webhook-id, webhook-timestamp, and webhook-signature headers.

When you own the endpoint, verify the signature over the raw request body with a Standard Webhooks-compatible library before processing. Do not parse and re-encode the JSON first. The stable webhook-id is the Stafett job ID — use it as your idempotency key.

from standardwebhooks.webhooks import Webhook

wh = Webhook("whsec_…")  # signing secret for your Stafett account
payload = wh.verify(request.body, dict(request.headers))

When the destination is a third-party API, pass its auth in headers. Remote APIs ignore Stafett's signing headers:

curl -X POST https://api.stafett.dev/enqueue \
  -H 'Authorization: Bearer stf_…' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://api.resend.com/emails",
    "headers": {"Authorization": "Bearer re_…"},
    "payload": {"from": "hi@example.com", "to": ["you@example.com"], "subject": "Shipped"}
  }'

Deliveries typically arrive exactly once. When an attempt fails in a way Stafett cannot verify (a timeout, or a dropped connection after the request went out), we retry rather than risk losing the job, so the same job can occasionally arrive more than once (at-least-once). Make the destination tolerate repeats; the webhook-id header is a stable idempotency key.

See the API reference for fields, limits, retries, and cancel, or try the OpenAPI explorer.