Skip to main content
Teel returns standard HTTP status codes. The body is JSON with a stable, machine-readable code you can switch on, plus a human-readable error message.
Switch on code, not error. Each code has exactly one meaning and never changes once shipped — it’s part of the contract. The error message is for humans and may be reworded at any time. Some errors also include a details object with structured context (e.g. the offending field and the bound it violated).

Status codes

What is and isn’t retryable

For 5xx and network errors:
With ±20% jitter to spread retry storms across many clients. Total wait: ~31 seconds across 5 attempts. For 429 responses, ignore the schedule above and wait the number of seconds in the Retry-After header. A retry before that just adds load.

Idempotency

Mutating POSTs accept an Idempotency-Key header — POST /rfq/execute, POST /rfq/execute-batch, POST /recipients, POST /recipients/bulk, and POST /webhooks/subscriptions. Include a UUID you generate; if the same key is sent within 24 hours, Teel returns the original response without creating a duplicate.
Always set this on payout execution. A network timeout on a POST without Idempotency-Key leaves you uncertain whether the payout was created — and retrying might double-charge your customer. With the header set, retry is safe. Reusing a key with a different body returns 409 IDEMPOTENCY_KEY_REUSED. The header is not required on quotes (those are idempotent by request shape) or on reads, and is not honored on update / delete endpoints.

Rate limiting

Per-key default: 60 requests per minute, burst 20. Specific endpoint families have tighter limits: Every response carries:
X-RateLimit-Reset is a Unix timestamp (seconds) when the bucket fully refills. If you find yourself consistently near the limit, batch where possible (POST /rfq/execute-batch instead of N calls to POST /rfq/execute) and cache quote results client-side for ~30s rather than re-quoting on every page render.

What we never do

  • We do not return 4xx for transient issues. If you got a 400 / 401 / 403 / 404 / 409, the request is wrong; do not retry.
  • We do not silently truncate fields. If a field exceeds a limit, you get a 400 with the field name and the violated bound. Quietly truncating user-supplied amounts is a class of bug we deliberately avoid.
  • We do not return generic 500s if we can avoid it. Validation failures are 400 / 422; permission failures are 403; missing resources are 404. A 500 from our side really means “something we didn’t expect went wrong” — please report it to support@teel.finance so we can fix it.

Examples

Idempotent payout with retries

Same Idempotency-Key across all retries — Teel returns the originally-created payout on retry rather than creating duplicates.