Safely retrying API requests
Last editedJun 2024
Today we're announcing support for idempotency keys on our Pro API, which make it safe to retry non-idempotent API requests.
Why are they necessary?
Here's an example that illustrates the purpose of idempotency keys.
You submit a POST
request to our /payments
endpoint to create a payment. If all goes
well, you'll receive a 201 Created
response. If the request is invalid, you'll receive a
4xx
response, and know that the payment wasn't created. But what if something goes wrong
our end and we issue a 500
response? Or what if there's a network issue that means you
get no response at all? In these cases you have no way of knowing whether or not the
payment was created. This leaves you with two options:
- Hope the request succeeded, and take no further action.
- Assume the request failed, and retry it. However, if the request did succeed you'll end up with a duplicate payment.
Not an ideal situation.
Idempotency Keys
To solve this, we've now rolled out support for idempotency keys across all our creation endpoints. Idempotency keys are unique tokens that you submit as a request header, that guarantee that only one resource will be created regardless of how many times a request is sent to us.
For example, the following request can be made repeatedly, with only one payment ever being created:
POST https://api.gocardless.com/payments HTTP/1.1
Idempotency-Key: PROCESS-ME-ONCE
{
"payments": {
"amount": 100,
"currency": "GBP",
"charge_date": "2015-06-20",
"reference": "DOLLAR01",
"links": {
"mandate": "MD00001EKBQ412"
}
}
}
If the request fails, then it's perfectly safe to retry as long as you use the same idempotency key. If the original request was successful, then you'll receive the following response:
HTTP/1.1 409 (Conflict)
{
"error": {
"code": 409,
"type": "invalid_state",
"message": "A resource has already been created with this idempotency key",
"documentation_url": "https://developer.gocardless.com/pro#idempotent_creation_conflict",
"request_id": "5f917bf9-df56-460f-a165-15d9e77414cb",
"errors": [
{
"reason": "idempotent_creation_conflict",
"message": "A resource has already been created with this idempotency key",
"links": {
"conflicting_resource_id": "PM00001KKVGTS0"
}
}
]
}
}
It's worth noting that we haven't added support for idempotency keys to our update endpoints, as they're idempotent by nature. For example, trying to cancel the same payment multiple times will have no adverse effect.
We're constantly improving our API to provide a better experience to our integrators. If you have any feedback or suggestions then get in touch, we'd love to hear from you!