Skip to main content
Olympex returns calldata and your wallet broadcasts it, so tracking happens in two places. A single-chain swap is final when its transaction is: read the receipt from your RPC, or poll GET /transactions/{hash}. A cross-chain transfer finishes on another chain: poll POST /tx-status until the provider reports success or failure.
You need the hash of the transaction you broadcast. For cross-chain transfers you also need the source chain ID and the dexHash from the cross-chain POST /swap response. See Execute a swap and Cross-chain swap end-to-end.

Prerequisites

  • An RPC URL for each chain you track, as POLYGON_RPC_URL in the examples, and viem 2 or ethers v6. To read single-chain receipts through Olympex instead, GET /transactions/{hash} needs only your API credentials.
  • For cross-chain transfers: API credentials in your server’s environment and the signing helper from Sign requests. TypeScript examples run on Node.js 22.18 or later, in an ES module project (npm pkg set type=module); Python examples need 3.8 or later with requests.
  • A place to store tracking records (a database table or a queue), so tracking survives restarts.

Steps

1

Store what you need before you broadcast

Write a tracking record as soon as you have the calldata, and add the hash when the wallet returns it. If your service restarts mid-transfer, it resumes from these records.
2

Single-chain: wait for the receipt

The transaction receipt is the result: success means the swap executed and paid at least minOutAmount; reverted means no tokens moved and the wallet paid only gas. Read it from your RPC, as below, or poll GET /transactions/{hash}, which reports pending, success, reverted or not_found with the block number and confirmations. That endpoint doesn’t detect a replaced transaction: once the replacement is mined, it reports the original hash as not_found.Two more outcomes need handling. The receipt can take longer than your timeout, and the user can speed up, replace or cancel the transaction from their wallet with the same nonce. A sped-up transaction (“repriced”) is the same swap; a replaced or cancelled one means the swap never ran, even though the replacement’s receipt can say success.
Choose the number of confirmations from your own risk policy for each chain. A pending result isn’t a failure: keep the record open and check the hash again later.
3

Cross-chain: confirm the source transaction first

Wait for the source transaction’s receipt with the same code. If it reverted, nothing was bridged: mark the transfer failed and stop. If it succeeded, the source leg is done and the transfer is in the provider’s hands; start polling.
4

Cross-chain: poll POST /tx-status with backoff

Send the source transaction hash as hash, the source chain ID as an integer in chainId, and the lowercase dexHash. Poll every 15 to 30 seconds and stop at a cap you choose.A 500 TX_STATUS_ERROR means the status is unknown, not that the transfer failed. Olympex returns it right after the broadcast, before the provider has a status for it, and also for some transfers the provider marks failed. The response doesn’t tell the two apart, so keep polling, rely on your cap, and save the requestId from the last error for support:
500 TX_STATUS_ERROR
The same error comes back on every poll, and never clears, when hash, chainId or dexHash doesn’t identify a transfer. If it persists, check all three against the broadcast transaction and the POST /swap response.The poller signs every call again, backs off from 15 to 30 seconds with jitter, treats TX_STATUS_ERROR, other 5xx responses and network failures as “no status yet”, signs a gateway 401 or 403 again once, throws on any other 4xx, and stops on a final status or at your cap:
Call it with the record you stored:
An illustrative response for a completed transfer:
Response (illustrative)
status, detailStatus, fromChainId and toChainId are always present. fromTxHash, toTxHash, fromAmount, toAmount, the token addresses and bridgeHash appear when the provider reports them. fromAmount and toAmount pass through from the provider without conversion, so check their unit before you do arithmetic with them. errorMsg is always null in a 200 response: when the provider reports an error, Olympex returns 500 TX_STATUS_ERROR instead, without the provider’s message. To show the user what happened, use detailStatus.
5

Map provider statuses to your states

status and detailStatus are the provider’s own values, so their casing varies. Compare status against these sets exactly:Use detailStatus for display only, and never branch on it.
6

Fall back when you reach your cap

If the transfer has no final status when your cap expires, don’t mark it failed. Show it as delayed, link the source transaction on the source chain’s block explorer, and keep a slower background check running. If it stays unresolved, contact partners@olympex.io with the transaction hash, source chain ID, dexHash and the last requestId. See Support.

Verify

  • Single-chain: a confirmed swap has status: "success" in its receipt, and a replaced or cancelled transaction shows as not executed even when the replacement succeeded.
  • Cross-chain: the poller returns success with a toTxHash that opens on the destination chain’s explorer, and the destination transaction delivered at least the quote’s minimumReceived to account.
  • A 500 TX_STATUS_ERROR during polling leads to another attempt, not a failure.
  • After a restart, open tracking records resume from storage.

Common pitfalls

Declaring success from the source receipt. On a cross-chain swap the source leg can succeed while the transfer fails or is refunded. Only a success status from POST /tx-status means the funds arrived.
Treating TX_STATUS_ERROR as a failure. It means the status is unknown for now. Telling a user a transfer failed while it’s still in flight can lead them to swap again.
Trusting a replacement’s receipt. When a user replaces or cancels the swap from their wallet, the transaction that lands isn’t the swap, and its receipt can still say success.
Wrong /tx-status inputs. chainId is the source chain ID as an integer (137), hash is the source-chain transaction, and dexHash comes from the cross-chain POST /swap response, in lowercase. A string chainId returns 400, but a wrong value of the right type doesn’t: it returns 500 TX_STATUS_ERROR on every poll until your cap.

What’s next

Get cross-chain transfer status

Every field of POST /tx-status.

Cross-chain swap end-to-end

The full flow from quote to delivery.

Handle errors and retries

Retries, backoff and request IDs.

Cross-chain mechanics

What happens between the two chains.