Currently Available: Need a skilled Software Developer for your next project?
Categories
Tech Stack

What Does Idempotency Mean in an API?

A client sends a payment request. The server processes it, but the connection drops before the response arrives, so the client cannot tell whether the payment went through. If it sends the request again, the customer can be charged twice.

Idempotency is the property that makes that second attempt safe. An API operation is idempotent when sending the same request several times has the same intended effect as sending it once. What counts is the final business state, such as one payment or one order. The responses, log entries and timestamps do not have to match.

RFC 9110, the HTTP specification, names this case as the reason idempotent methods matter: an idempotent request can be repeated automatically when the connection fails before the client reads the response. Retrying an operation that is not idempotent creates duplicate orders, double charges or duplicate jobs. Retry freely only when the API contract says that repeated attempts produce one intended result.

What counts as the same effect

A PUT request that sets customer 123 to the status active is a simple example. Whether the client sends that representation to PUT /customers/123 once or five times, the customer ends up active.

Deleting a resource is idempotent too. Say the first DELETE removes the resource and returns 204 No Content. A second DELETE returns 404 Not Found, because the resource is already gone. The response changed, but the result the client asked for, a resource that no longer exists, did not. MDN's definition of idempotency uses the same distinction.

The formal version is f(f(x)) = f(x), where x is the server's state and f is the operation. Applying the operation again adds no further change.

Idempotency does not mean that a repeated request causes no work on the server. The server can still write access logs, update monitoring counters, record audit events or keep a revision history for every request. RFC 9110 defines the property by the effect the client requested, and it allows the server to log each request separately or keep a revision history.

Repeated responses do not have to be identical either. A repeated GET returns different data if another client changed the resource between the two calls. The GET is still idempotent, because reading the resource does not change it.

Which HTTP methods are idempotent

RFC 9110's method definitions define GET, HEAD, OPTIONS and TRACE as safe methods, which means the client does not ask for any change on the server. Safe methods are also idempotent. PUT and DELETE are idempotent as well.

  • GET retrieves a resource. Repeating it does not modify the resource.
  • PUT creates or replaces a resource at a known URI. Sending the same representation again leaves the same state.
  • DELETE removes a resource. A second DELETE has nothing left to remove.
  • POST is not idempotent by definition. Repeating POST /orders creates several orders.
  • PATCH is not guaranteed to be idempotent. A patch that sets status to approved is idempotent. A patch that adds a fixed amount to a balance is not, because every repeat adds the amount again.

The method name alone guarantees nothing, because the endpoint has to implement those semantics. A PUT handler that creates a new random resource or sends a new payment on every call does not behave the way clients expect a PUT to behave.

When the client knows the resource URI and can send the complete final state, PUT is the natural choice. For actions such as creating an order or starting a payment, use POST and add duplicate protection in the application if clients need to retry safely.

Retries and idempotency keys

A payment is usually created with POST, so the HTTP method gives no protection against a double charge. An API can make such an operation safe to repeat with an idempotency key, a unique value that the client generates to identify one logical operation.

The client sends the same key with the original request and with every retry, and a new key for every new payment. The server stores the key together with the request parameters and the outcome. When the same key arrives again with the same parameters, the server returns the stored result, or an equivalent one, instead of running the payment again.

POST /payments
Idempotency-Key: unique-operation-key

The server should also compare the important request parameters. If a client reuses a key with different payment details, the API should reject the request instead of treating it as the original payment. Stripe documents this parameter check.

Idempotency keys are a convention that each API defines for itself. The service decides the header or parameter name, how long it keeps keys, what a key is scoped to and what happens when two requests with the same key arrive at the same time. Stripe uses an Idempotency-Key header. Amazon ECS accepts a client token only on some actions, scopes a RunTask token to one cluster and keeps it for at most 24 hours. Read the contract of the API you call instead of assuming that one key works everywhere or forever.

AWS's reliability guidance describes an idempotent service as one that processes each request exactly once, in the sense that several identical requests have the same effect as a single request. Internally, the server can still receive the same request more than once and start processing it more than once. The guarantee covers the business effect. If you publish an API, document that guarantee together with your key rules.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *