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

# Limits

> The timestamp window, nonce reuse, gateway timeout, calldata expiry, order allowances and value ranges your integration has to respect.

Olympex enforces a small set of hard limits. This page lists every one of them, what happens when you cross it, and how to stay inside it. Olympex doesn't publish per-key rate limits or quotas, so design your client to back off, and tell us about the volume you expect.

## Limits at a glance

| Limit | Value | When you exceed it |
| - | - | - |
| [Timestamp window](#timestamp-window) | ±300 seconds from server time | `403` `{"message":"Forbidden"}` from the gateway |
| [Nonce reuse](#nonce-reuse) | A nonce can't repeat within 5 minutes | `403` `{"message":"Forbidden"}` from the gateway |
| [Gateway timeout](#gateway-timeout) | About 30 seconds per request | `500` `{"message":"Internal Server Error"}` or `503` `{"message":"Service Unavailable"}` |
| [Calldata expiry](#calldata-expiry) | 5 minutes on most routes, enforced on-chain | The transaction can't succeed on-chain |
| [Integrator fee](#integrator-fee) | `feeBps` from 0 to 100 (1%) | `400` `VALIDATION_ERROR` |
| [Request body](#request-bodies-and-numbers) | `POST` and `PATCH`: a JSON object, sent as `application/json`. `GET` and `DELETE`: none | `400` `VALIDATION_ERROR`, or `403` `FORBIDDEN` `"Invalid body hash"` |
| [Integers](#request-bodies-and-numbers) | Within ±(2<sup>53</sup> − 1); amounts are strings, except in DCA strategies | `403` `FORBIDDEN` `"Invalid body hash"`, or a silently changed value |
| [Order allowance](#order-allowances) | Your token allowance to the Olympex order contract | The order fails when Olympex executes it |
| [Limit order expiry](/concepts/limit-orders#expiry) | `expired`: a Unix timestamp in milliseconds (13 digits), in the future and at most 365 days ahead | `400` `VALIDATION_ERROR` |
| [Lists](#lists) | No pagination: a list returns every match | Filter with query parameters |
| [Rate limits and quotas](#rate-limits-and-quotas) | Not published | The gateway can answer `429` `{"message":"Too Many Requests"}`. Contact [partners@olympex.io](mailto:partners@olympex.io) about expected volume |

## Timestamp window

The server rejects a request whose timestamp is more than 300 seconds before or after server time. A timestamp exactly 300 seconds old is accepted, and one 301 seconds old is rejected.

* Use Unix time in **seconds**. A millisecond timestamp is always outside the window.
* Keep your server clock synchronized with NTP.
* Sign immediately before you send. Don't sign requests ahead of time, queue signed requests or cache headers.

## Nonce reuse

The server rejects a nonce it has already seen in the last 5 minutes. Generate a new nonce, 24 hexadecimal characters from 12 cryptographically secure random bytes, for every attempt, retries included. A retry that resends the headers of an earlier attempt fails with `403`.

## Gateway timeout

The API gateway ends a request that runs longer than about 30 seconds and answers `500` with `{"message":"Internal Server Error"}` or `503` with `{"message":"Service Unavailable"}`. Neither response has `meta.requestId`. Both carry an ID in the `apigw-requestid` response header: log it on your server, because browsers can't read it on cross-origin calls.

* Set your HTTP client timeout a little above 30 seconds, so the gateway's answer arrives before your client gives up. The TypeScript and Python [reference implementations](/authentication/sign-requests#reference-implementations) use 35 seconds. With curl, add `--max-time 35`.
* Retry timeouts with exponential backoff and jitter, signing every attempt again. See [Errors and retries](/authentication/errors-and-retries#back-off-with-jitter).

## Calldata expiry

The calldata that [`POST /swap`](/api-reference/swap/build-swap) returns carries an on-chain expiry: 5 minutes on most routes. Some routes include a market maker's firm quote that expires sooner, within seconds of the build. The calldata is also bound to the `account` you passed, and another Olympex swap from the same account can invalidate earlier calldata.

Quotes aren't reserved either: prices move between the quote and the swap. Request the swap right after the quote, call `POST /swap` right before the user signs, and broadcast the transaction at once. Run `eth_estimateGas` first: a `200` from `POST /swap` doesn't guarantee that the calldata executes. If the estimate reverts, don't send. Build the swap again with the next `aggregatorId` in the quote's `aggregatorOrder`, or, for a cross-chain transfer, request a new quote. If you miss the window, request a new quote and a new swap.

<Warning>
  The calldata is real mainnet calldata. Broadcasting it moves funds, and a transaction that fails on-chain still costs gas.
</Warning>

## Integrator fee

The optional `fees` object on [`POST /quotes`](/api-reference/quotes/get-quote) and [`POST /swap`](/api-reference/swap/build-swap) sets your own fee on a route. Send the same `fees` on both, so the quote you show matches the calldata you send:

* `feeBps` is an integer from 0 to 100, in basis points: `100` is 1%.
* `feeRecipient` is the EVM address that receives the fee. It is required when `feeBps` is greater than 0, and the zero address is rejected.
* Fees apply only to signed requests from API accounts.

[Gas and fees](/concepts/gas-and-fees) explains how the fee appears in `integratorFeeBreakdown`.

## Request bodies and numbers

* The body of every `POST` and `PATCH` request is a JSON object, sent with `content-type: application/json`. `GET` and `DELETE` requests have no body: sign the empty string, send no body, and send the content type anyway. See [Requests without a body](/authentication/sign-requests#requests-without-a-body).
* Types are strict. A number where the API expects a string, or the reverse, returns `400 VALIDATION_ERROR`. For example, `chainId` is a JSON integer in every request body: `"137"` returns `400`.
* Quote, swap and limit-order amounts, prices and slippage are decimal strings. DCA's `totalAmount`, `slippage`, `minPrice` and `maxPrice` must be JSON numbers.
* The reference signers canonicalize numbers the way JavaScript does, so fractional numbers sign correctly. If you write your own signer in another language, format numbers exactly as JavaScript's `JSON.stringify` does: `1.0` becomes `1`, `1e21` becomes `1e+21`, and `0.0000001` becomes `1e-7`.
* Keep integers between `-9007199254740991` and `9007199254740991`, that is ±(2<sup>53</sup> − 1). The server parses JSON numbers as JavaScript doubles, so a larger integer loses precision and no longer matches the hash you signed.
* Keep object keys in ASCII and never numeric. See the [portability rules](/authentication/sign-requests#portability-rules).

## Order allowances

Limit orders and DCA strategies execute against the maker wallet's ERC-20 allowance to the Olympex order contract on that chain. The allowance is the on-chain limit on what Olympex can move, so size it to your open orders:

* A limit order needs `amount` of `inTokenAddress` plus the execution gas cost, which Olympex takes in `inTokenAddress`. Estimate that cost with [`POST /quotes`](/api-reference/quotes/get-quote) and `"includeGasInfo": true` (`dataFeeTransaction.transactionFeeInToken`), and add a buffer, because gas prices move.
* A DCA strategy needs `totalAmount` of `tokenAddressFrom`, with no extra fee on top.
* Every open limit order and active DCA strategy that sells the same token on the same chain shares one allowance: approve the sum.

[Order signatures and allowances](/concepts/order-authorization) lists the order contract on each chain.

## Lists

`GET /limit-order`, `GET /dca-order/strategies`, `GET /dca-order/strategies/{id}/orders` and `GET /tokens` return every matching item in one response. There is no pagination.

Narrow the limit-order list with `status`, `chainId` or `accountTo`, and the strategy list with `status` or `accountTo`. These lists ignore any other query parameter, so a misspelt or unsupported filter returns the full list. Send each parameter once: a repeated parameter matches nothing. Cache the token list on your side.

## Rate limits and quotas

Olympex doesn't publish per-key rate limits or quotas, and responses carry no rate-limit headers. That doesn't mean capacity is unlimited:

* Contact [partners@olympex.io](mailto:partners@olympex.io) about your expected volume before you launch, and again before a large increase.
* Retry `500` and `503` responses with exponential backoff and jitter, and cap how many requests you send in parallel.
* The API gateway can answer `429` with `{"message":"Too Many Requests"}` when it receives too many requests in a short time. Wait, then retry with exponential backoff and jitter, signing each attempt again, and send fewer requests in parallel.
* Poll no faster than you need to, whether you follow a cross-chain transfer or an order. For cross-chain status, poll every 15 to 30 seconds, for example.

<Tip>
  Cache the results of `GET /chains` and `GET /tokens` instead of calling them before every quote. The token list is large and changes rarely: cache it for 24 hours, for example.
</Tip>

## What this means for your integration

* Sign immediately before each send, with a synchronized clock and a new nonce.
* Set your client timeout a little above 30 seconds, and retry timeouts and `500`-class errors with backoff and jitter.
* Broadcast calldata right after `POST /swap`, once `eth_estimateGas` passes, and request a new quote and swap if you miss the window.
* Send amounts and decimals as strings (JSON numbers in DCA strategies), approve only what your open orders need, and talk to Olympex about your expected volume before launch.

## Related

<CardGroup cols={2}>
  <Card title="Errors and retries" icon="circle-exclamation" href="/authentication/errors-and-retries">
    Which failures to retry, and how.
  </Card>

  <Card title="Sign requests" icon="code" href="/authentication/sign-requests">
    The timestamp, nonce and body rules in the signing algorithm.
  </Card>

  <Card title="Execute a swap" icon="route" href="/guides/execute-a-swap">
    Quote, build and broadcast inside the calldata window.
  </Card>

  <Card title="Going to production" icon="list-check" href="/guides/going-to-production">
    The checklist before you send real traffic.
  </Card>
</CardGroup>


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