Idempotency
Write requests (POST, PATCH, PUT, DELETE) accept an Idempotency-Key header so retries are safe:
POST /api/v1/trades
Authorization: Bearer tvty_YOUR_KEY_HERE
Idempotency-Key: my-script-2026-05-10-trade-1
Content-Type: application/json
{ ... trade body ... }
If the same key is reused within 24 hours with the same body, the server returns the cached response (and sets X-Idempotent-Replay: true) without re-executing the write. Reusing the same key with a different body returns HTTP 409 idempotency_conflict.
Concurrent identical requests are also safe: only one wins the “leader” slot and runs the side effect; the others poll briefly and return the leader’s response. So five parallel POSTs with the same Idempotency-Key produce one DB row plus four replays, never five rows.
Replays still count against your rate limit. Each call — fresh or replayed — decrements X-RateLimit-Remaining by one. The replay path is cheap (no side effect, returns the cached body) but it is a billable request. Build your retry logic to back off on transport errors rather than blindly re-sending the same key in a tight loop.
The key must be 1–64 characters of [A-Za-z0-9_-]. Use a UUID or a deterministic identifier from your client (e.g. {user}-{operation}-{timestamp}).
Idempotency contract in detail
Every write endpoint accepts an Idempotency-Key header. The contract is:
- Fresh key → the side effect runs once. The full response is cached for 24 hours.
- Same key, identical body →
200/201/204with the cached response. The headerX-Idempotent-Replay: trueis set. The side effect does not run again. - Same key, different body →
409 idempotency_conflict. Pick a fresh key. - Five concurrent identical requests → one wins the “leader” slot and runs the side effect. The other four poll for up to 30 seconds, then return the leader’s cached response. Net result: exactly one row inserted, all five callers get
201. - Keys must be 1–64 characters of
[A-Za-z0-9_-]. UUIDs are perfect. Deterministic strings like{user}-{operation}-{2026-05-10}also work.
The 24-hour window starts at the original request time. After that, the same key can be reused for a fresh write.
The server caches responses by (api_key, Idempotency-Key) for 24 hours. A retry of the same request returns the cached response without re-executing the side effect. A retry with a different body returns 409 idempotency_conflict. Without this header, a network retry can double-create rows.