/track - Request the status of a swap
The /track endpoint provides real-time status information for a specific transaction. It is particularly useful for tracking the progress and details of swaps, transfers, and other operations. To use this endpoint, you normally provide the chain ID and transaction hash.
For NEAR Intents swaps, you can also call the endpoint with depositAddress, which is the address the deposit transaction was sent to.
For deposit-channel routes you can also call it with depositChannelId — the meta.providerDepositChannelId returned by /v3/swap. This is the way to track a Chainflip swap whose deposit was broadcast outside your app, where you never see a transaction hash.
For a complete list of chain IDs used by SwapKit you can check the table here.
Method: POST
URL: https://api.swapkit.dev/track
SwapKit has it's own transaction tracking interface here: https://track.swapkit.dev/. You can also directly fill the fields by directing users to https://track.swapkit.dev/?hash={{hash}} by populating it with the respective transaction hash.
Request Body:
hash
string
Transaction hash (required if using chainId)
chainId
string
Chain ID of the transaction (required if using hash)
depositChannelId
string
Deposit channel ID, can be used instead of hash and chainId. Use the meta.providerDepositChannelId returned by /v3/swap. Needed for Chainflip when the deposit was broadcast without a wallet connection, so no hash is available.
depositAddress
string
Deposit address used to swap with NEAR Intents, can be used instead of hash and chainId
block
number
Block number. Required for Polkadot.
routeId
string
The routeId of the /v3/quote route this transaction executed. Pass it on /track calls until the response contains a parsed transaction, to enable realized-slippage reporting on completion. Best-effort: quote data expires. Send it on the first call, right after broadcast.
Provide exactly one of: hash + chainId, depositChannelId, or depositAddress. routeId is not one of those identifiers — it is additive, and is passed alongside whichever one you use.
Example Requests:
Response
The response contains detailed information about the transaction status, type, and associated metadata. It also includes the array "legs" which represent the different stages or components of the transaction.
Response Fields:
chainId
string
The chain ID where the transaction occurred.
hash
string
The transaction hash.
block
number
The block number where the transaction was included.
type
string
The type of the transaction (e.g., swap, token_transfer).
fromAsset
string
The asset being sent.
fromAmount
string
The amount of fromAsset that was actually deposited.
fromAddress
string
The address sending the asset.
toAsset
string
The asset being received.
toAmount
string
The amount of toAsset.
toAddress
string
The recipient address.
finalisedAt
number
Unix timestamp in seconds at which the transaction finalised, or -1 when it hasn't finalised or the time isn't known. Always seconds — provider values reported in milliseconds or nanoseconds are normalized before you see them.
slippageTolerance
number (Optional)
Tolerance of the quote the swap committed to, in basis points. See Realized slippage.
realizedSlippageBps
number (Optional)
Realized slippage of the settled output vs the quoted expected output, in basis points. Positive means the swap settled for less than quoted. See Realized slippage.
meta
object
Metadata including images, provider info, and fees — the fees actually charged. See Realized fees. And the USD valuations amountInUsd / amountOutUsd (see USD amounts). On a refunded or partially refunded swap it also carries refundReason, the provider's own reason for the refund; absent when the provider gave none, and on swaps that were not refunded.
payload
object
Additional transaction specific data.
legs
array
Detailed breakdown of each transaction leg.
Example response:
Notes:
The
legsarray provides a detailed view of each step in the transaction process.metacontains additional information, including images, the swap provider details, the fees actually charged (meta.fees), and the USD valuations (meta.amountInUsd/meta.amountOutUsd).The
payloadmay include data likeevmCalldataormemofor more complex transactions.
Realized fees
meta.fees reports what the swap actually settled, as opposed to the estimates returned by /v3/quote. It uses the same schema as the quote response's fees, so a quote and its settled result can be compared entry for entry.
It appears at transaction level and on each entry of legs, and is omitted entirely — never an empty array — whenever no fee has settled yet or the provider exposes none.
One exception: NEAR's outbound echoes the quote-time withdrawal fee, since 1Click exposes no settled value. It appears only on a successful swap and is already reflected in the amount received.
Fee entry fields
type
string
One of inbound, outbound, liquidity, network, affiliate, service.
amount
string
Fee amount, in decimal units of asset.
asset
string
Asset the fee was charged in (e.g. "BTC.BTC").
chain
string
Chain of the fee asset.
protocol
string
Provider that charged it (e.g. "CHAINFLIP").
amountBps
number
Optional. Fee in basis points — present on affiliate and service entries.
It is an array, not one bucket per type, because a single swap can pay the same type more than once. Within one provider, entries sharing a type and asset are summed. Across legs they're concatenated, not summed: an exact repeat of type + asset + protocol is dropped, while the same type and asset from different protocols both appear. inbound is the exception — see below.
Leg-level vs transaction-level
Each leg reports what that leg paid. For inbound, the transaction level reports the sum of the wallet gas and any matching ingress. On a Chainflip BTC deposit, the miner fee sits on the deposit leg, Chainflip's ingress fee sits on the swap leg, and the transaction reports the total:
Those two components merged because both were in BTC. When they're in different assets they stay separate — a Chainflip USDC deposit on Ethereum reports two inbound entries: the ingress fee in USDC and the wallet gas in ETH.
Plain transfers with no swap provider report no inbound fee — there is nothing to attribute it to. It is also omitted when the fee is zero, when the chain data doesn't expose the sender's fee (Zcash shielded sends, UTXO transactions with an unresolvable input, Tron when free bandwidth covered the cost).
USD amounts
meta.amountInUsd / meta.amountOutUsd value the amount deposited and received. Transaction-level only.
Positive 2-decimal string or absent — never
"0". A sub-cent value rounds to zero and is therefore reported as absent, not as a misleading"0.00". Absent means "not priced", not "worth nothing"; each field resolves independently.Priced at current price at track time; only live or recently-settled swaps (~1h of
finalisedAt), never backfilled.The first valid value stored is kept forever, even under
forceUpdate. There is no settlement guard, so if you track while the swap is still pending, whatevertoAmountthe parser had at that moment is the value that gets frozen.
Realized slippage
On a completed swap, /track compares the settled output with the quote it was committed against. Both fields are in bps, transaction-level only (not per leg), and omitted when uncomputable.
slippageTolerance
number (optional)
Tolerance of the quote the swap committed to, in bps.
realizedSlippageBps
number (optional)
(expected − actual) / expected in bps, rounded. Positive = received less than quoted.
Only on completed swaps. Either field may be absent;
slippageTolerancein particular isn't available from every quote source.On a partially refunded swap the value measures against the full quoted amount, so it reads as a large positive number — check
trackingStatusforpartially_refundedbefore reading it as slippage.Automatic on Chainflip, NEAR, Garden, Flashnet, Jupiter and Harbor routes. On any other route, pass
routeIdon your/trackcalls until the response contains a parsed transaction — quotes expire ~5 minutes after quoting, so call right after broadcast.
Status fields
Every transaction, and every leg in its legs array, carries two status fields:
status— the coarse lifecycle state. Always present, a small stable set. Poll this for completion.trackingStatus— the finer phase. Varies more between providers, optional in the schema, and the only place some states are reported.
Both are taken from the leg currently in flight — the first leg not yet completed, refunded or failed — so they advance as the swap moves between legs, and report the last leg once all are terminal. unknown and not_started are not terminal.
Two exceptions:
partially_refundedon any leg surfaces as the transaction'strackingStatus, whichever leg is in flight.When the transaction's
trackingStatusisrefunded, itsstatusis reported asrefunded. Legs keep their own values.
Poll status and treat completed, refunded and failed as terminal. Read trackingStatus for mid-swap progress, or for the states status cannot express.
Chainflip
pending → swapping → completed
status, mapped from its SWAPPING/SENDING states
THORChain (incl. streaming), Maya, NEAR Intents, Mayan, Flashnet, Garden
pending → completed
trackingStatus
Harbor
pending → completed
not reported — trackingStatus goes inbound → outbound → completed
Same-chain: 1inch and the other EVM aggregators, Jupiter on Solana
unknown → completed / failed
no middle state; never reports pending
Before the deposit is seen, a cross-chain status may read not_started or unknown.
So a THORChain or NEAR swap observably goes pending → completed, and that is correct. To display "swapping", read legs[].trackingStatus.
Chainflip caveat. The transaction reads swapping only once the deposit leg has confirmed. That leg's status comes from our own chain parsing, so while it is still settling the transaction reads pending — trackingStatus mempool or broadcasted on UTXO deposits, starting on EVM — even though legs[1].status already reads swapping.
Tracking status
trackingStatus reports the specific phase of the transaction. Use it for progress display, and for what status cannot express (swapping off Chainflip, partially_refunded).
Which values a route passes through depends on the provider; the set is deliberately not uniform and may grow. Keep polling status for completion — don't read an unrecognized trackingStatus as "still progressing", since dropped, reverted, replaced, retries_exceeded and parsing_error all accompany a swap that has stopped.
Transaction status
An important part of the response is the transaction status from the status field, which can have multiple values:
not_started
The swap has not happened yet.
pending
Intermediate state. The transaction has been detected by the mempool but is pending block confirmation.
swapping
The swap is happening.
completed
The swap is finished.
refunded
The swap was refunded because of the slippage settings.
unknown
Catch all for other situations.
failed
The transaction failed in an inbound EVM contract.
Last updated

