Skip to main content
Short answers to the questions integrators ask most, each with a link to the page that covers the topic in full. If your question isn’t here, see Support.

Getting started

The Olympex REST API returns the best route Olympex finds across its liquidity sources for a swap on one chain or a transfer between two chains, builds the unsigned transaction calldata for that route, and reports the status of transactions and cross-chain transfers. It also runs limit orders and DCA strategies, which Olympex executes from the maker’s wallet, and lists the enabled chains and the tokens on each one.Olympex never holds your keys. For swaps, your wallet signs and broadcasts every transaction. For limit orders and DCA, the maker signs each token pair once and approves the Olympex order contract, and that allowance caps what the orders can spend. See How Olympex works.
Create a test API key in one click on Create a test API key, or call POST /accounts from a terminal or your server with a name of at least 6 characters and a password of at least 8. The response contains your API key ID and your secret key, a random string shown once, and the password becomes your passphrase. The account can call every signed endpoint immediately: there is no activation step.Save the secret key as soon as you receive it: Olympex stores only an encrypted copy and can’t show it again. Create your production account from your server, with a passphrase of at least 24 random characters from a password manager, in printable ASCII with no leading or trailing spaces. See Credentials.
No. Every API key, including a test key created from these docs, is a real account on the live API, and quotes use live prices.
  • Quotes, chain checks, and the chain, token, order and strategy reads change nothing.
  • POST /swap returns unsigned calldata and never broadcasts it. That calldata is real mainnet calldata, so sending it from a funded wallet moves funds.
  • POST /limit-order and POST /dca-order/strategies create real orders that Olympex executes against the maker’s allowance. Test them with small amounts from a wallet you control. To test the DCA calls without scheduling orders, create the strategy with "status": "cancelled".
Call GET /chains for the enabled chain IDs instead of hard-coding them. They are Ethereum (1), Optimism (10), BNB Chain (56), Polygon (137), Base (8453), Arbitrum (42161), Avalanche (43114) and Linea (59144). Cross-chain transfers can start on Ethereum, Optimism, BNB Chain, Polygon, Arbitrum and Avalanche. Limit orders and DCA execute only on the chains listed in The order contract.GET /tokens lists the tokens on each chain. Cache the list, and match tokens by address, never by symbol: symbols aren’t unique, and some carry a suffix such as STRK_1. The list doesn’t limit what you can trade: a quote tells you whether any token address has a route. See Supported chains and tokens.
For single-chain swaps, Olympex requests quotes from okx, oneInch, openOceanV3, openOceanV4, zeroExV2AllowanceHolder, uniswapV3Hermes and uniswapV4Hermes, and returns the best route: by default the one with the highest output (orderBy: "MAX_OUT_AMOUNT"). The quote names the winner in aggregatorId and lists every source that quoted in aggregatorOrder, best first. To leave sources out, pass their IDs in excludeMetaAggregatorId. See Aggregation and routing.
The cross-chain providers are okx, rango and liFi. Signed requests from API accounts are quoted and built with okx or rango. The quote’s aggregatorId names the provider and bridgeInfo.displayName names the bridge it chose. The dexHash in the cross-chain /swap response identifies the provider when you track the transfer. See Cross-chain mechanics.

Authentication

Signed endpoints take four headers built from three credentials. The API key ID identifies your account in x-api-key-id, and the passphrase travels in x-passphrase. The secret key never leaves your server: it keys an HMAC-SHA256 over the method, the path, the canonical query, the timestamp, a single-use nonce and the SHA-256 hash of the canonical request body, which is the empty string for a GET or DELETE. The signature goes in x-signature, and x-value-info carries the timestamp, the nonce and the body hash. POST /accounts is public; every other endpoint is signed. See Authentication overview.
The gateway’s 403 {"message": "Forbidden"} doesn’t say which check failed. The most common causes:
  • The signed method, path or query isn’t the request you sent. Sign the method in uppercase, the full path starting with /api/v1, and the canonical query. A signer that signs only the timestamp, the nonce and the body hash, without the OLPX-HMAC-SHA256-V2 line, is rejected.
  • The timestamp is in milliseconds, or your clock is more than 300 seconds from server time. Send Unix time in seconds from a synchronized clock.
  • The nonce was used before, usually by a retry that resends the same headers. Sign every attempt again with 24 new hexadecimal characters. In a shell, OLYMPEX_NONCE or OLYMPEX_TIMESTAMP left set after testing the known-answer vectors has the same effect: run unset OLYMPEX_NONCE OLYMPEX_TIMESTAMP.
  • The HMAC is keyed with the decoded secret instead of the secret key string, or the signed message ends with a newline.
  • The API key ID or the passphrase is wrong, or the account is inactive.
A 403 whose envelope carries FORBIDDEN and "Invalid body hash" means the body doesn’t match the signed bodyHash. Hash the canonical JSON (keys sorted at every level, no whitespace) as unpadded base64url, send exactly those bytes, and set Content-Type: application/json. For a GET or DELETE, sign the empty string and send no body. A 401 {"message": "Unauthorized"} means a signing header is missing.On a gateway 401 or 403, sign the request again once with a new nonce. If it fails again, stop and check your credentials and your clock, and if correctly signed requests keep failing, contact partners@olympex.io. Don’t retry an envelope UNAUTHORIZED or FORBIDDEN ("Invalid body hash") unchanged: fix the cause first.The troubleshooting table maps every symptom to its fix, and the known-answer vectors on the same page let you test your implementation offline, with and without a body.
API accounts have no rotation, revocation, deletion, scope or expiry features, so credentials stay valid until Olympex deactivates the account. To replace credentials, create a new account, move your integration to it, then ask partners@olympex.io to deactivate the old account. Limit orders and DCA strategies belong to the API key that created them, and the new account can’t read, change or cancel them. Manage the old account’s open orders and strategies with its own credentials, and cancel them or let them finish before you ask to deactivate it.If a secret key or a passphrase leaks, email partners@olympex.io right away and ask to deactivate the account. Include the API key ID, never the secret key or the passphrase. If the account has open limit orders or DCA strategies, also set each maker’s allowance to the order contract to 0. See Credentials.
Call signed endpoints from your server. Signing needs the secret key and the passphrase, and an app that ships them to users’ devices publishes them. Browsers also enforce the API’s CORS policy, which allows only specific origins. See Security model.The order signature for limit orders and DCA is different: it comes from the maker’s wallet, not from your API credentials. Your app can ask the user’s wallet for it in the browser and send it to your server, which creates the order. See Sign a pair.

Requests and errors

A field or query parameter is missing, has the wrong type or is out of range. error.details lists each field at fault with a message, for example {"field": "params.chainId", "message": "Invalid input: expected number, received string"}. The usual causes:
  • chainId was sent as a JSON string, such as "137". It is an integer in every request body. See Chain IDs.
  • An amount, slippage or gas price was sent as a number in a quote or swap, or slippage or gasPrice in a limit order. Send them as decimal strings. DCA strategies are the opposite: totalAmount, slippage, minPrice and maxPrice must be JSON numbers.
  • A limit order body includes a field Olympex sets (status, txHash, executorAddress, reasonFail, allowance, estimateGas or effectivePriceGas), or an expired that isn’t a Unix timestamp in milliseconds (13 digits), in the future and at most 365 days ahead.
  • A cross-chain body has a top-level key other than mode, params and fees, such as dryRun. Cross-chain bodies reject unknown top-level keys.
  • GET /tokens got a query parameter other than chainId ("Invalid query parameters"), or a chain that isn’t enabled ("Chain N is not enabled").
  • Olympex has no reference price for a limit order’s pair ("Not exist reference price for this pair A/B"). See Reference price.
  • The request has no Content-Type: application/json header, or another type, such as curl’s default application/x-www-form-urlencoded. The gateway then base64-encodes the body, and the API answers 400 with "Invalid JSON body" on POST /accounts, or 403 with "Invalid body hash" on signed endpoints.
Fix the fields and send again; an unchanged request fails the same way. See API conventions.
A 404 with the code NOT_FOUND and a message that names the method and the path, such as "No route for GET /api/v1/quote", means that no endpoint matches them. Paths start at the base URL, which ends in /api/v1, and they are lowercase and case-sensitive: /support-chain works, /Support-Chain returns 404. Each endpoint accepts only the method its page shows, so a GET /quotes also returns 404.On an {id} path, a 404 whose message names the resource concerns an order or strategy ID. See the next question.
On an {id} path, a 404 with the code NOT_FOUND means that no limit order, DCA strategy or DCA order with that ID belongs to the API key you signed with. Either the ID doesn’t exist, or another API key created it: Olympex answers the same way in both cases. The message names the resource: "Limit order not found", "DCA strategy not found" or "DCA order not found". A DCA order belongs to the API key that created its strategy.Don’t retry the request unchanged. Check the ID, and sign with the API key that created the order or strategy. The list endpoints return only the orders and strategies of the API key you sign with, so an ID you take from them resolves with that key. See Not found.
The API gateway stops a request after about 30 seconds and returns 500 or 503 with a {"message": …} body instead of the envelope. The first request after a quiet period can also get a gateway 500 {"message": "Internal Server Error"}. Set your client timeout a little above 30 seconds. Retry those responses with backoff, signing each attempt again, except POST /accounts, POST /limit-order and POST /dca-order/strategies: they create a new resource on every success, so check what exists before you send them again. See Errors and retries.

Quotes and swaps

  • amount in a request is a decimal string in human-readable units of the input token: "10" is 10 USDT.
  • outAmount, toTokenAmount, minimumReceived and minOutAmount are integer strings in base units of the output token: "10034668" is 10.034668 USDC, which has 6 decimals.
  • slippage is a percentage string: "1" is 1%.
  • gasPrice is a gas price hint in whole gwei, rounded up, because some sources reject fractional gwei. On a chain whose gas price is below 1 gwei, that gives "1". See The gasPrice hint.
  • value in a /swap response is the native token amount in wei.
Quote, swap and limit-order amounts, prices and slippage are decimal strings. DCA strategies take totalAmount, slippage, minPrice and maxPrice as JSON numbers instead. See API conventions.
A quote isn’t reserved. Prices keep moving, so request the swap right after the quote and protect it with slippage. The calldata from POST /swap carries its own on-chain expiry, 5 minutes on most routes, and is bound to the account it was built for, so broadcast it right after you receive it. Some routes include a market maker’s firm quote that expires within seconds of the build. If you miss the window, request a new quote and a new swap. See Slippage and price impact.
  • The price moved past your slippage. A single-chain swap reverts when it would deliver less than minOutAmount. Request a new quote and swap.
  • The calldata expired. On most routes, calldata expires 5 minutes after /swap builds it, and a market maker’s firm quote inside some routes expires within seconds. Broadcast right after you receive it, and build the swap again if it reverts as expired.
  • The route can’t execute. A 200 from /swap doesn’t guarantee that the calldata executes: a source can build calldata that reverts. Run eth_estimateGas before you send. If it reverts while the allowance and the balance are in order, build the swap again with the next aggregatorId in the quote’s aggregatorOrder, or, for a cross-chain transfer, request a new quote.
  • Another swap replaced it. Another Olympex swap from the same account can invalidate earlier calldata. Build and send one swap at a time per account.
  • The allowance is too low. For ERC-20 input, approve the exact amount for contractToApprove before you send. For tokens such as USDT that require it, set the allowance to 0 first.
  • The gas limit is too low. Estimate gas yourself instead of relying on gasLimit.
See Execute a swap.
Only as a fallback. gasLimit is estimatedGas multiplied by 2, and estimatedGas can be a placeholder of "1500000", "0", or a wei amount on cross-chain routes. Estimate gas with eth_estimateGas and add a buffer, for example 20%. See Gas and fees.
For a cross-chain transfer, call POST /tx-status with the source-chain transaction hash, the source chainId as an integer, and the dexHash from the cross-chain /swap response in lowercase. Poll with backoff, for example every 15 to 30 seconds. A 500 TX_STATUS_ERROR means the status is unknown, not that the transfer failed: Olympex returns it right after broadcast and also for some transfers the provider marks failed. Keep polling up to a cap you choose, then check the source transaction on a block explorer or contact Support with the requestId.For a single-chain swap, poll GET /transactions/{hash} with the chainId, which returns pending, success, reverted or not_found, or read the transaction receipt from your RPC. See Track a swap to finality.

Limit orders and DCA

Yes. Olympex executes both from the maker’s wallet, and nothing moves when you create them.
  • Limit order. Sells amount of inTokenAddress for outTokenAddress. The order executes when the market price of inTokenAddress, in outTokenAddress, reaches priceTrigger or better. Create one with POST /limit-order.
  • DCA strategy. Spends totalAmount of tokenAddressFrom in iterations equal orders, one every frequency seconds, buying tokenAddressTo on the same chain. Create one with POST /dca-order/strategies.
Both need an order signature and an allowance from the maker. See Limit orders, DCA strategies, and the guides Place a limit order and Run a DCA strategy.
The strategy is the plan you create: the tokens, totalAmount, iterations, frequency and optional price bounds. DCA orders are its executions. Olympex creates them as the strategy runs, each spending totalAmount / iterations, and there is no endpoint to create one. GET /dca-order/strategies/{id}/orders lists a strategy’s orders, oldest first.To stop a strategy, send PATCH /dca-order/strategies/{id} with {"status":"cancelled"}, which can’t be undone, and lower the maker’s allowance to the order contract. DCA orders are read-only: no endpoint changes or cancels one. See Cancel a strategy.
The maker is the wallet in accountTo. It sells the token, receives the output, signs the token pair and approves the order contract. It must be an externally owned account (EOA): smart-contract wallets such as Safe or ERC-4337 accounts can’t sign orders, because only 65-byte ECDSA signatures are accepted.Send accountTo in EIP-55 checksummed form everywhere. Olympex stores it as you sent it, and the ?accountTo= filter on the list endpoints matches case-sensitively.
The maker signs keccak256(abi.encodePacked(maker, maker, tokenIn, tokenOut)) once per token pair, with EIP-191 personal_sign over the 32 raw bytes, not over the hex string. The signature lets the Olympex order contract execute swaps of tokenIn for tokenOut from the maker’s wallet.
  • It doesn’t bind an amount, price, expiry, chain or order: Olympex enforces those when it executes.
  • It stays valid after you cancel an order, and the same signature serves limit orders and DCA for that pair.
  • Olympex doesn’t check it when you create an order, and a wrong signature makes execution fail later. Recover the signer and compare it with the maker before you send it.
Your allowance to the order contract is the on-chain limit on what orders can spend. See Order signatures and allowances.
Approve the Olympex order contract for the chain, listed in The order contract. It isn’t the contractToApprove that POST /swap returns, which is for swaps.
  • Limit order: amount, plus the execution gas cost in the token sold, plus a buffer. Estimate the gas cost with a single-chain POST /quotes for the same pair and amount with "includeGasInfo": true: dataFeeTransaction.transactionFeeInToken.
  • DCA strategy: totalAmount. Its execution gas comes out of the token bought.
  • Several orders: orders that sell the same token on the same chain share one allowance, so approve the sum.
Never approve an unlimited amount. Cancelling an order doesn’t change the allowance. To stop every order that sells a token, set the allowance to 0. See How much to approve.
  • Native tokens. The token sold must be an ERC-20: wrap first, and sell WETH, WBNB or WPOL. Token addresses lists their addresses.
  • ERC-20 tokens whose transfer and approve don’t return a boolean. USDT on Ethereum isn’t supported as the token you sell in limit orders or DCA on Ethereum.
  • Fee-on-transfer tokens.
The create call can accept an order that sells one of these, and that order can’t execute, so check the token before you create the order. See What can’t be sold.
Olympex needs a reference price for the pair. It reuses a recent lookup for the same chain and token addresses, or looks up a market for the two symbols, or identifies the tokens by address. When all of these fail, POST /limit-order returns 400 VALIDATION_ERROR with "Not exist reference price for this pair A/B", where A/B are the symbols you sent, and no order is created.Send each token’s real symbol in tokenASymbol (the token you sell) and tokenBSymbol (the token you buy). Read symbol() from the token contract, or take the symbol from GET /tokens by address, trimmed and without a trailing _<number> (STRK for STRK_1). Check that the addresses are token contracts on that chain. The error can also be temporary, so retry later with backoff before you rule the pair out.Olympex doesn’t check the symbols against the token contracts, so check the ones the response returns. Responses can return normalized symbols, such as ETH for WETH. Cancel an order whose symbols match neither your tokens nor their normalized forms. See Reference price.
Poll. The API doesn’t push status changes.
  • Limit order. GET /limit-order/{id} returns its status: pending, then executing or submitted, then completed with txHash. It can also end as failed, with reasonFail[], or cancelled.
  • DCA. GET /dca-order/strategies/{id}/orders returns each order’s status. A successful order carries transactionHash, amountReceived and executionPrice. The strategy’s status becomes finished when every order has run.
Treat a status you don’t recognize as not final.
To change anything else, such as the tokens, the chain or the maker, cancel and create a new order or strategy. If you change an amount, set the allowance to match.
Not blindly. Each successful POST /limit-order or POST /dca-order/strategies creates a new order or strategy, and Olympex ignores any id you send. After a timeout, list your orders with GET /limit-order?accountTo=<maker>, or your strategies with GET /dca-order/strategies?accountTo=<maker>, and look for a match on your own fields before you send the call again.GET, PATCH and DELETE requests are safe to repeat. A repeated DELETE /limit-order/{id} returns 409 CONFLICT once the first call has cancelled the order. See Requests that create a resource.
Yes. DCA strategies take totalAmount, slippage, minPrice and maxPrice as JSON numbers, and bounds such as a minPrice of 0.00025 are fractional. The reference signers in TypeScript and Python, and the API console, canonicalize numbers the way JavaScript does, so these values 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 within ±(253 − 1). A number formatted differently changes the body hash, and the request fails with 403 FORBIDDEN "Invalid body hash". See Portability rules.

Fees

Pricing and commercial terms are agreed with Olympex: contact partners@olympex.io. Every quote for an API account carries integratorFeeBreakdown, which reports the Olympex protocol fee next to yours. The protocol fee applies even when you send no fees, and integratorMarginBps is then 0. protocolFeeBps is the rate in basis points and can be fractional (the examples show 15, which is 0.15%), and protocolFeeAmount is the amount in base units. Read the rate from each response instead of hard-coding it.For swaps, gas is paid by the sending wallet in the chain’s native token, and none of it goes to Olympex. For limit orders and DCA, Olympex pays the execution gas and is reimbursed from the maker: in the token sold, on top of amount, for a limit order, and out of the token bought for each DCA order. See Gas and fees.
Yes, on swaps. Add a top-level fees object to POST /quotes and POST /swap. feeBps is an integer from 0 to 100 basis points, where 100 is 1%. feeRecipient is the EVM address that receives your 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. Send the same fees object on the quote and the swap, so the quote you show matches the calldata you send. Limit orders and DCA strategies don’t take a fees object. See Gas and fees.

Limits and tools

Olympex doesn’t publish per-key rate limits or quotas, and responses carry no rate-limit headers. That doesn’t make capacity unlimited: tell partners@olympex.io your expected volume before you launch, retry 500 and 503 responses with exponential backoff and jitter, signing each attempt again, and cap how many requests you send in parallel. The API gateway can answer 429 {"message": "Too Many Requests"} when it receives too many requests in a short time: wait, back off and send fewer requests in parallel. See Limits.
Download it from https://docs.olympex.io/api-reference/openapi.json. It is curated from the live service and includes the gateway’s own error responses. Most response examples, including every /quotes and /swap example, are captured from the live API; the /tx-status success example is illustrative. Every endpoint page in the API reference is generated from it. The service also serves its own spec at GET /openapi.json and Swagger UI at GET /docs; build against the curated spec instead. See OpenAPI specification.
There is no SDK package. Generate a typed client from the OpenAPI specification and add a signer to it, or use the reference implementations in TypeScript, Python and bash on Sign requests.
The browser couldn’t read the API’s response. Usually the API’s CORS policy doesn’t allow the origin you’re browsing from, or the gateway rejected the request without CORS headers. Click Copy as cURL and run the command in a terminal: it sends the same signed request. Add -i to the command (or -D -) to see the HTTP status and the response headers, including apigw-requestid. To create a key, follow Create a key from a terminal. Use a test API key in the console, never production credentials. See API console.
The meta.requestId of the failing response (for a gateway response, its apigw-requestid header), the endpoint, the time of the request in UTC, and the request body without credentials. For a limit order or a DCA strategy, add its id, the chain ID and the maker address. Never send the secret key or the passphrase. Support lists everything that helps.

Quickstart

Send your first signed request.

Sign requests

The signing algorithm, reference code and troubleshooting.

Glossary

Definitions of the terms used across the docs.

Support

How to contact Olympex and what to include.