code you can switch on, plus a human-readable error message.
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
Recommended retry schedule
For5xx and network errors:
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 anIdempotency-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.
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
400with 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 are403; missing resources are404. A500from 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
Idempotency-Key across all retries — Teel returns the originally-created payout on retry rather than creating duplicates.