> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ionicfi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Reliable API requests

> Retry safely and recover when a response does not arrive.

Reliable integrations assume that the client might not receive the response even when the server did the work.

## Retry matrix

| Condition                         | What to do                                                                  |
| --------------------------------- | --------------------------------------------------------------------------- |
| Network timeout before response   | Retry with the same `Idempotency-Key`.                                      |
| `409 IDEMPOTENCY_KEY_IN_PROGRESS` | Wait at least `Retry-After` seconds, then retry with the same key.          |
| `422 IDEMPOTENCY_BODY_MISMATCH`   | Stop. The retry key was reused for a different operation.                   |
| `429 RATE_LIMIT_EXCEEDED`         | Back off until `Retry-After` or `X-RateLimit-Reset`.                        |
| `5xx`                             | Retry with the same key for creates and other money-moving mutations.       |
| Payment declined                  | Do not blindly retry. Ask the buyer for another method or show the decline. |

## Recover after an unknown result

If a payment request times out, retrieve the resource instead of creating the
payment again. Store your own order ID so you can match the API result to the
original request:

* Store `client_reference_id` on checkout sessions.
* Store `metadata.order_id` or similar on checkout sessions, payment links, refunds, and customers.

## Confirm payment on your server

Success redirects can be lost, forged, duplicated, or opened in another tab. Always verify server-side state before fulfillment.

```bash theme={null}
curl https://api.ionicfi.com/v1/checkout/sessions/cs_000000000000000000000000 \
  -H "Authorization: Bearer sk_v1_test_..."
```

## Reuse keys only for retries

An idempotency key should represent one business operation, not one endpoint forever.

Good:

```text theme={null}
order_123_create_checkout_session
```

Bad:

```text theme={null}
checkout
```
