API error handling: telling a client what went wrong and what to do
API error handling is a design decision, not a fallback. Which status codes to use, what an error body should contain, and the distinction that decides whether a client retries.
Idempotency is what stops a retried request charging a card twice. How idempotency keys work, which operations need them, and what the server has to remember.
Networks fail in the most inconvenient way available: the request arrives, the work happens, and the response is lost. The client has no way to tell that from a request that never arrived, so it retries — and without idempotency the customer is charged twice, the invoice is created twice, and somebody spends a morning reconciling it. Idempotency is the property that makes sending the same request twice indistinguishable from sending it once.
The client generates a unique key per logical operation — not per attempt — and sends it with the request. The server records the key with the result. If the same key arrives again, the server returns the stored result instead of doing the work a second time. The important detail is where the key comes from: it must be generated before the first attempt and reused for every retry of that attempt, which means it belongs to the operation in the client's own model, not to the HTTP call.
Decide what happens when the same key arrives with a different body. Returning the original result silently hides a client bug; rejecting it with a clear error surfaces one. The second is almost always right, and it has to be documented either way.
Generate the key when the user acts, not when the request is built, and persist it alongside whatever you are creating. If your retry logic generates a fresh key each attempt, you have implemented retries with extra steps and no protection. This is also why at-least-once delivery is the normal guarantee for webhooks: the sender cannot know you received it, so the receiver has to be able to handle the same event arriving twice.
The Ettex Api documents the authentication model and the endpoints in one place, and the same discipline applies to anything consuming them through an agent, where retries are invisible to you. If you are designing a receiver rather than a caller, the practical rule is to treat every incoming event as a possible duplicate and key on the event identifier.
Yes, provided it is generated once per logical operation and reused across retries. The failure is almost never collision; it is regenerating the key on each attempt.
Long enough to cover realistic retry windows — often twenty-four hours, longer for financial operations. Publish the number so clients know when a replay stops being recognised.
By definition they should be, if they set a value rather than modify it relatively. An endpoint that increments on every call is not idempotent whatever verb it uses.
API error handling is a design decision, not a fallback. Which status codes to use, what an error body should contain, and the distinction that decides whether a client retries.
API key rotation fails when it is a single swap with no overlap. How to run it with two valid keys, what to do about keys you cannot find, and why rotation only matters if revocation works.
API versioning is a promise about what will not break. Which changes are safe, how to version without forking your codebase, and how to deprecate without stranding integrations.