Retries and idempotency
Retry the right errors, safely
Not every failure deserves a retry. Retrying the wrong status wastes quota; retrying without care can duplicate side effects.
What to retry
429rate limited — retry with exponential backoff and jitter; treat it as a signal to lower concurrency.500provider or service error — retry with backoff. The failure was upstream or transient.
attempt 1 → fail attempt 2 → wait 1s + jitter attempt 3 → wait 2s + jitter attempt 4 → wait 4s + jitter give up (or alert)
What not to retry
402quota exceeded — automatic retries just burn attempts; resolve plan/quota first.401,400,404,422— deterministic request problems. Fix the key, body, or feature choice.
Full details in the error catalog.
Idempotent-by-design requests
Chat completion requests are not automatically idempotent: the same request can produce different output at non-zero temperature. If you must retry a completed-but- dropped response, make the retry cheap and deterministic:
curl https://api.hardcarrx.com/v1/chat/completions \
-H "Authorization: Bearer ***" \
-H "Content-Type: application/json" \
-d '{
"provider": "openai",
"model": "gpt-4.1-mini",
"messages": [{"role": "user", "content": "Hello"}],
"temperature": 0
}'- Set
temperature: 0when reproducibility matters. - Keep requests small so a retry after a timeout is cheap.
- Correlate attempts with the returned request logs ( request-log troubleshooting) to confirm whether the first attempt actually completed.
Memory writes
/v1/memory/store creates a new memory object on each call — a blind retry stores duplicates. Check the response memory_id before retrying; use /v1/memory/query on your metadata to detect an already-stored write.