The first decision in any retry policy is which failures deserve a second attempt. Retrying a permanent error wastes quota, adds latency, and on a shared upstream can look like abuse. A 400 means your payload is malformed, a 401 means the key is wrong or revoked, a 403 means the endpoint rejects you, a 404 means the path does not exist, and a 410 means it was removed for good. None of those get better with time, and general HTTP retry guidance says to move them straight to a dead-letter path instead of looping Hookdeck's retry guidance.
Transient failures are the opposite: they resolve on their own. Connection timeouts, connection refused, connection resets, and temporary DNS failures all fall in this bin, as do 500, 502, 503 and 504, because they signal a server-side problem that often clears in seconds Hookdeck's retry guidance. 429 is a special case: the upstream is asking you to slow down, so honor its Retry-After header when present and otherwise back off more aggressively than usual Hookdeck's retry guidance.
Model APIs add nuance. A 429 that means "your per-minute budget is spent" is transient and worth retrying, but a 429 that means "your credits ran out" is a wall, and looping on it only burns your own CPU. The published error guides separate rate limits, provider overload (503 and overload codes), and quota or billing exhaustion, and they are explicit that retrying billing errors will not restore access AI API error and retry guide. Read the error body, not just the status code, before you decide.
The second axis is idempotency. A GET is safe to replay. A POST that creates a resource is not, unless the server can deduplicate it. HTTP defines idempotency in terms of intended effect: repeating identical requests should have the same effect as making one Stripe's advanced error handling. Stripe implements this with client-generated idempotency keys, reused across retries of the same logical operation, so a retry after a lost response returns the original result instead of charging twice Stripe idempotent requests. If your model call triggers a side effect (writing a record, sending a message, charging a card), send an idempotency key or do not retry it at all.



