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

# Making requests safely

> Retry without creating duplicate payments, and stay within rate limits.

## Headers every request needs

| Header | Value | Required |
| - | - | - |
| `X-BRIDGE-API-Key` | Your API key | Always |
| `API-Version` | Your account's version, for example `2026-10-29-atlas` | Always |
| `Content-Type` | `application/json` | When you send a body |
| `Idempotency-Key` | A unique value you choose | Recommended when creating anything |

## Retry safely with an idempotency key

Imagine your server sends "create a payment", but the connection drops before you see the reply. Did the payment get created? If you send the request again, you might create two.

An **idempotency key** fixes this. It's a unique value you send in the `Idempotency-Key` header, such as your own order ID. If we see the same key again, we don't create anything new. We send back the first reply.

```bash theme={null}
curl -X POST https://sandbox.core.linkio.world/api/payments/onramp \
  -H "X-BRIDGE-API-Key: $BRIDGE_API_KEY" \
  -H "API-Version: 2026-10-29-atlas" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1001" \
  -d '{ ... }'
```

### How it works

| Situation | What happens |
| - | - |
| First time we see the key | We process the request and remember the reply for **24 hours**. |
| Same key, same request, first one succeeded | You get the same reply again, with the same status code. Nothing new is created. |
| Same key, while the first request is still running | `409`: `A request with this Idempotency-Key is already being processed.` Wait and try again. |
| Same key, **different** request body | `409`: `This Idempotency-Key was used with a different request payload.` Use a new key for a new request. |
| First request failed with an error | The reply isn't remembered. Fix the problem and retry with the same key. |

> [!TIP]
>
> Use a value that is unique to the thing you're creating, such as your order ID. Don't generate a new random key when you retry, or you lose the protection.

Idempotency keys only apply to requests that create something (`POST`). Requests that only read data (`GET`) are always safe to repeat.

> [!NOTE]
>
> Idempotency errors use a shorter format than other errors: they have `code` and `message`, but no `type` or `request_id`.
>
> ```json theme={null}
> {
>   "error": {
>     "code": "idempotency_conflict",
>     "message": "A request with this Idempotency-Key is already being processed."
>   }
> }
> ```

## Rate limits

To keep the service fast for everyone, each IP address can make up to **120 requests per minute**.

Every response tells you where you stand:

| Header | Meaning |
| - | - |
| `RateLimit-Limit` | How many requests you can make in the current minute |
| `RateLimit-Remaining` | How many you have left |
| `RateLimit-Reset` | Seconds until the count resets |

If you go over, you get a `429` error and a `Retry-After` header that says how many seconds to wait:

```json theme={null}
{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limit_exceeded",
    "message": "Too many requests",
    "request_id": "req_3VnR7tY1wZ4cB6dE8fK2mQ9xLp",
    "status": 429
  }
}
```

> [!TIP]
>
> Don't check a payment's status over and over. Use [webhooks](https://docs.bridge.linkio.world/webhooks/overview.md) to be told when it changes.

## Request size

Request bodies can be up to 10 KB. Larger requests are rejected with `413`.

## Request IDs

Every error includes a `request_id` that starts with `req_`. Log it, and send it to support if you need help with a request.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.