> ## 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.

# Going to production

> The pre-launch checklist for an Olympex integration: credentials, signing, swap execution, limit orders and DCA, tracking, fees, monitoring and rollout.

Run this checklist before real users swap or place orders through your integration, and again after any major change. Each item links to the page with the details.

<Info>
  Before you start, run [Execute a swap](/guides/execute-a-swap) end to end with a small amount, and [Cross-chain swap end-to-end](/guides/cross-chain-swap-end-to-end) if you offer cross-chain transfers. If you offer limit orders or DCA, also run [Place a limit order](/guides/create-a-limit-order) and [Run a DCA strategy](/guides/build-a-dca-strategy).
</Info>

## Prerequisites

* A working integration on the chains and pairs you plan to launch.
* Access to your secrets manager, logging and alerting.
* A contact on your team for [partners@olympex.io](mailto:partners@olympex.io).

## Steps

<Steps>
  <Step title="Keep credentials on your servers">
    * Store the API key ID, secret key and passphrase in a secrets manager and inject them at runtime. Keep them out of source control, client bundles, mobile apps and container images.
    * Treat the passphrase like the secret key. It travels in `x-passphrase` on every request, so redact it wherever you log requests.
    * Sign requests on your servers only. Browsers and mobile apps call your backend, and your backend calls Olympex.
    * Use one API account for testing and another for your live service, so a leaked test credential doesn't expose live traffic. Both call the same live API.
    * Orders and DCA strategies belong to the API key that created them: any other key gets `404 NOT_FOUND` for them. Keep that key for as long as its orders are open.
    * Write the leak runbook now. Credentials can't be rotated or revoked through the API: email [partners@olympex.io](mailto:partners@olympex.io) to deactivate the account, then create a new one and deploy its credentials. See [Credentials](/authentication/credentials#if-a-credential-is-exposed).
  </Step>

  <Step title="Sign every request reliably">
    * Keep server clocks synchronized with NTP. The API rejects a timestamp more than 300 seconds from server time, in either direction.
    * Send the timestamp in Unix **seconds**, not milliseconds.
    * Generate a new nonce for every attempt, including retries. The API rejects a nonce it has seen in the last 5 minutes.
    * Send exactly the canonical bytes you hashed, with `Content-Type: application/json`.
    * Sign the method, the exact path you call (it starts with `/api/v1`) and the canonical query, along with the body.
    * Send quote, swap and limit-order amounts, prices and slippage as decimal strings, and DCA's `totalAmount`, `slippage`, `minPrice` and `maxPrice` as JSON numbers. A number where a quote or swap expects a string, or a string where DCA expects a number, returns `400 VALIDATION_ERROR`.
    * Use a reference signer, or format numbers exactly as JavaScript's `JSON.stringify` does if you write your own (`1.0` becomes `1`, `1e21` becomes `1e+21`, `0.0000001` becomes `1e-7`). Keep integers within ±(2<sup>53</sup> − 1).
    * Check your signer against the known-answer vectors on [Sign requests](/authentication/sign-requests#known-answer-vector) in your test suite.
  </Step>

  <Step title="Handle errors in one place">
    * Route every call through one retry wrapper that signs each attempt again, as in [Handle errors and retries](/guides/handle-errors-and-retries).
    * Retry 5xx responses (including the gateway's `500` and `503`), `422 NO_ROUTE` and connection failures with exponential backoff and jitter, and cap how many requests you send in parallel. The first request after a quiet period can get a gateway `500`: sign again and retry once, then back off.
    * Sign a gateway `401` or `403` again once, with a new nonce. If it fails again, stop and check your credentials and clock, and if correctly signed requests keep failing, contact [partners@olympex.io](mailto:partners@olympex.io).
    * Never retry a `400`, `404` or `409`, and don't retry an Olympex `UNAUTHORIZED` or `FORBIDDEN` unchanged: fix the cause.
    * Never retry `POST /limit-order`, `POST /dca-order/strategies` or `POST /accounts` automatically: each success creates a new resource. After a timeout or 5xx, list your orders or strategies and match on your own fields before you send the create again.
    * Keep your client timeout above the gateway timeout of about 30 seconds.
    * Branch on `error.code` and the HTTP status, never on `error.message`, and handle unknown codes by status.
    * On `SWAP_ERROR` or `422 NO_ROUTE` from `POST /swap`, fall back to the next source in the quote's `aggregatorOrder`. Do the same when `POST /swap` succeeds but `eth_estimateGas` of its calldata reverts.
  </Step>

  <Step title="Execute swaps safely">
    * Build calldata with `POST /swap` right before you send it, and send it as soon as the gas estimate succeeds. It carries an on-chain expiry (5 minutes on most routes), some routes include a market maker's quote that expires within seconds of the build, and it is bound to `account`. Never queue or cache it, and send one Olympex swap at a time per account.
    * Run the checks in [Check before you sign](/concepts/security-model#check-before-you-sign) on every transaction: sender, `to`, `value`, `minOutAmount` and the approval spender.
    * Approve `contractToApprove` for the exact input amount. Never approve an unlimited amount, and reset the allowance to 0 first for tokens such as USDT that require it.
    * Always run `eth_estimateGas` before you send: a `200` from `POST /swap` doesn't guarantee that the calldata executes, because a source can build calldata that reverts. If the estimate reverts once the balance and allowance are in place, don't send: build the swap again with the next source in `aggregatorOrder`, or request a new quote for a cross-chain swap, and show the user the new amounts. See [Execute a swap](/guides/execute-a-swap).
    * Add a buffer to your own estimate (for example 20%). Don't size gas from the quote's `estimatedGas`, which leaves out the Olympex contracts. Use the response's `gasLimit` only as a fallback on single-chain swaps.
    * Send from the same wallet you passed as `account`.
    * Set slippage limits: a default per pair type and a maximum that your product enforces on user input. See [Slippage and price impact](/concepts/slippage-and-price-impact#choosing-a-slippage-tolerance).
    * Before you retry a failed broadcast, check whether the first transaction reached the chain.
  </Step>

  <Step title="Run limit orders and DCA safely">
    Olympex executes limit orders and DCA orders from the maker's wallet, under the allowance the wallet grants to the Olympex order contract. That allowance is the on-chain limit on what Olympex can move. See [Order signatures and allowances](/concepts/order-authorization).

    * Approve the Olympex order contract for the chain, not the `contractToApprove` from `POST /swap`. Limit orders and DCA execute only on chains that have an order contract.
    * Approve exact amounts, never an unlimited one. A limit order needs `amount` plus its execution fee in the token sold, with a buffer: estimate the fee with `POST /quotes` and `"includeGasInfo": true`. That estimate leaves out the Olympex contracts, so make the buffer generous, for example with `gasMultiplier` `HIGH`. A DCA strategy needs `totalAmount`, with nothing on top.
    * Send each token's real symbol in `tokenASymbol` and `tokenBSymbol`. Listed symbols can carry a suffix such as `STRK_1`: read `symbol()` from the token contract, or drop a trailing `_<number>`. Olympex doesn't check the symbols against the tokens, so check the ones each create response returns, and cancel an order whose symbols aren't your tokens' (`WETH` returned as `ETH` is expected).
    * Send a limit order's `expired` as a 13-digit Unix timestamp in milliseconds, in the future and at most 365 days ahead, and don't rely on it to stop the order. Cancel orders you no longer want, and lower the allowance.
    * Approve the sum per token and chain. Every open limit order and active DCA strategy that sells the same token on the same chain shares one allowance, and `approve` replaces it: read the current allowance and add to it. For tokens such as USDT, set it to `0` before a new non-zero value.
    * Accept only EOA makers. Smart-contract wallets (Safe, ERC-4337) can't sign orders. Send `accountTo` in its EIP-55 checksummed form, and use the same form in list filters, which match case-sensitively.
    * Sign the 32 bytes of the pair hash, not its hex string, and check every signature before you send it: `verifyMessage(getBytes(inner), signature)` must return the maker. Olympex doesn't check it when you create the order, so a wrong one fails only at execution.
    * Sell only ERC-20 tokens: wrap native tokens first. USDT isn't supported as the token you sell in limit orders or DCA on Ethereum, and neither are fee-on-transfer tokens.
    * Poll `GET /limit-order/{id}` and `GET /dca-order/strategies/{id}/orders` for status changes. Olympex doesn't push them. Treat a status you don't recognize as not final, and give every poller a cap.
    * Spell list filters exactly and send each once. The order and strategy lists ignore unknown query parameters, so a misspelt filter returns everything, and a repeated parameter matches nothing.
    * Pair every cancellation with an allowance reduction. Neither `DELETE /limit-order/{id}` nor cancelling a DCA strategy changes the allowance, and the pair signature stays valid. To stop everything for a token on a chain, set its allowance to `0`.
  </Step>

  <Step title="Show users what they receive">
    * Get token addresses and decimals from `GET /tokens?chainId=`. Cache the list on your side, for example for 24 hours: it's large and changes rarely. Match tokens by address, case-insensitively, never by symbol: the native token is listed in lowercase (`0xeeee…eeee`), and symbols can carry suffixes such as `STRK_1`. Vet the tokens you offer, and read `decimals()` from the contract for any token you add that the list doesn't have.
    * On Polygon, offer POL through the native pseudo-address only. The list also carries `0x0000000000000000000000000000000000001010`, POL's system contract, with the same symbol: it can't be approved, and quotes can route it at prices unrelated to POL.
    * `GET /chains` returns chain IDs only. Keep chain names and the capabilities you need in your code, and offer a chain only while its ID is in the response.
    * Show amounts in the output token's decimals, and show the minimum the user receives: `minOutAmount` for single-chain swaps, `minimumReceived` for cross-chain transfers.
    * For cross-chain transfers, show the bridge (`bridgeInfo.displayName`) and, when the provider reports it, `estimatedTime`.
    * Present gas figures as estimates. The fee the user pays depends on the gas price when the transaction is mined.
  </Step>

  <Step title="Track every swap to a final state">
    * Store the transaction hash, chain ID and `account` for every swap, and the `dexHash` for cross-chain transfers, so tracking survives restarts.
    * Confirm single-chain swaps from the transaction receipt, and handle timeouts and transactions the user replaces or cancels in their wallet.
    * Poll `POST /tx-status` every 15 to 30 seconds for cross-chain transfers. Treat `500 TX_STATUS_ERROR` as unknown, stop at a cap you choose, then point the user to the block explorer and contact support with the `requestId`.
    * Mark a cross-chain swap complete only on a success status from `POST /tx-status`, never on the source receipt alone.

    [Track a swap to finality](/guides/track-a-swap-to-finality) has the code.
  </Step>

  <Step title="Configure your integrator fee">
    * Add `fees` with `feeBps` (0 to 100, where 100 is 1%) and `feeRecipient` to your quote and swap requests. Send the same `fees` on both, so the quote you show matches the calldata you send.
    * Fees apply only to signed requests from API accounts. Every quote carries `integratorFeeBreakdown`, with the Olympex protocol fee, even without `fees`; `integratorMarginBps` is then `0`. Check it in the quote: `integratorMarginBps` is your `feeBps`, and `protocolFeeBps` is in basis points (`15` is 0.15%).
    * Use a `feeRecipient` you control on every chain you serve. The zero address is rejected. If it's a smart-contract wallet, make sure the contract exists at that address on each chain.
    * For fee terms, email [partners@olympex.io](mailto:partners@olympex.io). See [Gas and fees](/concepts/gas-and-fees#integrator-fees).
  </Step>

  <Step title="Monitor with request IDs">
    * Log `meta.requestId` from every error response with your own correlation ID, the endpoint, status, `error.code` and latency. Gateway responses have no `meta.requestId`: log their `apigw-requestid` response header instead. The reference helpers raise gateway errors, such as a `401` or `403`, without a request ID, so read the header from your HTTP client.
    * Track error rates by endpoint and code. A rise in `403` points to clock drift or credentials: check both, and if correctly signed requests keep failing, contact [partners@olympex.io](mailto:partners@olympex.io). A rise in gateway `500` or `503` responses points to requests running past the gateway timeout.
    * Alert on cross-chain transfers that reach your polling cap without a final status, and on limit orders that end `failed` or DCA orders that end in `error`, with the order ID.
    * Olympex doesn't publish a status page, so your own metrics are the first signal. When you contact support, include request IDs, UTC timestamps and transaction hashes. See [Support](/resources/support).
  </Step>

  <Step title="Roll out in stages">
    * Launch on one chain or one pair first, watch your error rates and swap outcomes, then widen.
    * Confirm with your legal and compliance team which checks your product needs before launch, for example screening wallet addresses.
    * If you show Olympex attribution, follow [Brand assets](/resources/brand-assets).
  </Step>

  <Step title="Talk to us before you scale">
    Olympex doesn't publish request quotas. Before launch, email [partners@olympex.io](mailto:partners@olympex.io) with your expected volume, peak request rate and chains, and again before a large increase. See [Limits](/authentication/limits#rate-limits-and-quotas).
  </Step>
</Steps>

## Verify

* A small mainnet swap succeeds on each chain you enable, for each input type you support: ERC-20 input, native-token input, and cross-chain if you offer it.
* Each error path behaves as designed: a `400` isn't retried, a simulated connection failure is retried with growing delays, a `500 TX_STATUS_ERROR` keeps a transfer in progress, and calldata whose gas estimate reverts is never sent.
* A restart during a cross-chain transfer resumes tracking from storage.
* If you offer orders: a small limit order and a DCA strategy can be created, read, cancelled and reconciled after a simulated timeout, and after each cancellation the order contract's allowance is back to what your other open orders need.
* A search of your logs, traces and error reports finds no passphrase, secret key or `x-signature` value.
* Your servers' clock offset is well inside the 300-second window.

## Common pitfalls

<Warning>
  **Credentials in the browser.** Anyone who can read your client code can sign requests as you.
</Warning>

<Warning>
  **Headers in logs.** Request logging, APM agents and error trackers often capture headers. An unredacted `x-passphrase` in a log is a leaked credential.
</Warning>

<Warning>
  **Unlimited approvals.** An unlimited allowance stays open after the swap, and on the order contract it lets Olympex execute any order for a signed pair from the wallet. Approve the exact amount for every swap, and only what your open orders need on the order contract.
</Warning>

<Warning>
  **Overwriting a shared order allowance.** `approve` replaces the allowance. Approving one new order's amount on its own takes the allowance away from the other open orders and strategies that sell the same token on the same chain, and they fail at execution.
</Warning>

<Warning>
  **Queued calldata.** Calldata built minutes before sending can expire on-chain or be invalidated by another swap from the same account, and a market maker's quote inside a route can expire within seconds. Build it immediately before each transaction.
</Warning>

<Warning>
  **Sending calldata that wasn't estimated.** A `200` from `POST /swap` doesn't guarantee that the calldata executes. A transaction sent without `eth_estimateGas` can revert on-chain and still cost the user gas.
</Warning>

## What's next

<CardGroup cols={2}>
  <Card title="Security model" icon="shield-halved" href="/concepts/security-model">
    What Olympex holds, and what stays with you.
  </Card>

  <Card title="Credentials" icon="key" href="/authentication/credentials">
    Store, protect and replace your credentials.
  </Card>

  <Card title="Limits" icon="gauge" href="/authentication/limits">
    Signing windows, timeouts and volume.
  </Card>

  <Card title="Handle errors and retries" icon="circle-exclamation" href="/guides/handle-errors-and-retries">
    The retry wrapper and error mapping.
  </Card>
</CardGroup>


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