cryptoinfraDocs

#Swaps

Trade between two coins you hold — the output is credited to the user's balance

Open as MarkdownFor AI assistants

4 endpoints. Generated from docs/openapi.yaml v1.0.0.

EndpointSummary
POST /v1/swap/quotePrice a swap between two coins you hold
POST /v1/swap/ordersStart a swap — sell one coin the user holds, credit them another
GET /v1/swap/orders/{id}Fetch one order
GET /v1/swap/orders/{id}/detailFetch one order in full — addresses, send leg, origin and timeline

#POST/v1/swap/quote

Price a swap between two coins you hold · Auth: bearer API key · operationId: quoteSwap

A SWAP trades between assets WE custody, named by OUR asset_id on both sides (GET /v1/assets) — unlike an exchange, which names its buy side by the exchange's own identifier. There is no destination address to supply and none to validate: the output lands on the user's own static wallet address and is credited to their balance.

Indicative only. A quote confers no reservation and holds no balance, and the route is re-quoted at create time — treat expires_at as the moment to ask again, not as a price lock.

Our fee is charged on the SELL side, taken OUT of amount rather than added on top, and send_amount is what reaches the exchange — published so the numbers add up rather than a fee appearing from nowhere between quote and settlement.

receive_estimate is an estimate; receive_minimum is the floor this route guarantees. The user is credited what ACTUALLY ARRIVES, which is why both are published: the pair is the promise.

Both sides are assets of ours, so unlike an exchange quote every amount here carries its exact *_base twin.

A quote is good for at most 60 seconds, or less when the route itself expires sooner — expires_at carries the earlier of the two.

#Request body

application/json · required · schema SwapQuoteRequest

FieldTypeDescription
sell_asset_id requiredstringOne of OUR assets (GET /v1/assets) — what is sold out of the user's balance. (minLength 1; maxLength 64)
buy_asset_id requiredstringOne of OUR assets again — a swap trades between coins we custody, so this is an asset_id, NOT the exchange identifier an exchange takes. Must differ from sell_asset_id, and both must be enabled. (minLength 1; maxLength 64)
amount requiredstring | numberDecimal amount of sell_asset_id, fee INCLUSIVE: our fee comes out of it and send_amount is what reaches the exchange.

#Responses

StatusBodyMeaning
200SwapQuoteAn indicative price, with the moment it stops being valid.
400ErrorThe request was refused before anything was charged. error is one of: validationerror, invalidamount, invalidpair (both sides name the same asset, an asset is not enabled, an asset no exchange can route — swappable: false on GET /v1/assets, the message names it — the user_id is unknown, or the user has no address on the buy asset's chain), noroute (that pair has no liquidity path at this size — nothing is broken, try another amount or asset).
401ErrorMissing, malformed or unknown API key.
403ErrorSwaps and exchanges are turned off, or the exchange integration is not configured.
502ErrorThe exchange failed or was unreachable (your request was valid).
503ErrorOur side is not ready for this chain. The request was fine — retry rather than change it.

200 response body — SwapQuote

FieldTypeDescription
sell_asset_id requiredstring—
buy_asset_id requiredstring—
sell_amount requiredstringA monetary value as a decimal string. Always paired with a *_base field that carries the exact integer base-unit value; compute with the _base string.
sell_amount_base requiredstringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
fee requiredstringOur fee, taken OUT of sell_amount — not charged on top. a percentage with a dollar minimum (see GET /v1/pricing), plus network_fee.
fee_base requiredstringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
network_feestringThe network part of fee, in the sold asset — a USDT ⇄ TRX trade's own gas on TRON, or an exchange's send. Already inside fee.
network_fee_basestringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
send_amount requiredstringsell_amount minus fee — what reaches the exchange, published so the numbers add up.
send_amount_base requiredstringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
receive_estimate requiredstringEstimated output, in the buy asset's major units. Indicative only.
receive_estimate_base requiredstringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
receive_minimum requiredstringThe floor this route guarantees. The user is credited what ARRIVES, not this — treat it as the worst case you may quote them.
receive_minimum_base requiredstringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
providers requiredstring[]The route's legs, in order.
estimated_seconds requiredinteger | null—
expires_at requiredstring<date-time>ISO-8601. When the quote stops being valid — the moment to re-quote, not a price lock. Same shape as the exchange quote's.
json
{
  "sell_asset_id": "usdt_trc20",
  "buy_asset_id": "trx",
  "sell_amount": "1.5",
  "sell_amount_base": "1500000000",
  "fee": "1.5",
  "fee_base": "1500000000",
  "network_fee": "1.5",
  "network_fee_base": "1500000000",
  "send_amount": "1.5",
  "send_amount_base": "1500000000",
  "receive_estimate": "1.5",
  "receive_estimate_base": "1500000000",
  "receive_minimum": "1.5",
  "receive_minimum_base": "1500000000",
  "providers": [
    "string"
  ],
  "estimated_seconds": 1,
  "expires_at": "2026-08-31T04:21:00.000Z"
}

#Example request

bash
curl -X POST 'https://api.cryptoinfra.build/v1/swap/quote' \
  -H 'Authorization: Bearer ck_live_your_key' \
  -H 'Content-Type: application/json' \
  -d '{
  "sell_asset_id": "usdt_trc20",
  "buy_asset_id": "trx",
  "amount": "100"
}'

#POST/v1/swap/orders

Start a swap — sell one coin the user holds, credit them another · Auth: bearer API key · operationId: createSwapOrder

201, and the user's balance is ALREADY debited: the sell leg is an ordinary withdrawal, priced, signed and broadcast by the same code as any other payout. Our fee comes out of the amount, and the withdrawal fee is NOT charged on top.

The output is NOT credited yet. It is paid to the user's OWN static wallet address on the buy asset's chain and credited by the ordinary deposit path once it confirms — so poll GET /v1/swap/orders/{id} (or watch the user's balance) rather than reading 201 as completion. The user is credited what ARRIVES, not receive_estimate; receive_minimum is the floor the route guaranteed.

pending until the sell leg is on-chain, then sent/swapping while the exchange works, and completed once the output is reported.

The route is re-quoted at execution time rather than carried over from POST /v1/swap/quote, so an order's numbers are the ones actually executed and may differ slightly from the quote you showed. Quote first anyway: it is the cheap way to find out that a pair has no route at this size.

Idempotent on idempotency_key — replaying a key returns the ORIGINAL order instead of starting a second swap; the same key with a DIFFERENT payload is refused with 409 idempotency_conflict. Always retry a failed or timed-out create with the SAME key.

#Request body

application/json · required · schema SwapOrderRequest

FieldTypeDescription
sell_asset_id requiredstringOne of OUR assets (GET /v1/assets) — what is sold out of the user's balance. (minLength 1; maxLength 64)
buy_asset_id requiredstringOne of OUR assets again — a swap trades between coins we custody, so this is an asset_id, NOT the exchange identifier an exchange takes. Must differ from sell_asset_id, and both must be enabled. (minLength 1; maxLength 64)
amount requiredstring | numberDecimal amount of sell_asset_id, fee INCLUSIVE: our fee comes out of it and send_amount is what reaches the exchange.
user_id requiredstringYour external_user_id — whose balance is sold, and whose deposit address on the buy asset's chain receives the output. The user must already have an address on that chain. (minLength 1)
idempotency_keystringReplaying a key returns the ORIGINAL order instead of starting a second swap; the same key with a different payload is 409 idempotencyconflict. Use a fresh key per logical swap; always retry with the same one. (minLength 1; maxLength 255)_

#Responses

StatusBodyMeaning
201SwapOrderSwap started; the sell leg is queued as a withdrawal.
400ErrorThe request was refused before anything was charged. error is one of: validationerror, invalidamount, invalidpair (both sides name the same asset, an asset is not enabled, an asset no exchange can route — swappable: false on GET /v1/assets, the message names it — the user_id is unknown, or the user has no address on the buy asset's chain), noroute (that pair has no liquidity path at this size — nothing is broken, try another amount or asset).
401ErrorMissing, malformed or unknown API key.
403ErrorSwaps and exchanges are turned off, or the exchange integration is not configured.
404ErrorUnknown externaluserid for this tenant.
409Errorerror is one of: insufficientbalance (the sell amount would overdraw the user's balance), idempotencyconflict (this idempotency_key was already used with a DIFFERENT payload — your replay is not the request you think it is).
502ErrorThe exchange failed or was unreachable (your request was valid).
503ErrorOur side is not ready for this chain. The request was fine — retry rather than change it.

201 response body — SwapOrder

FieldTypeDescription
order_id requiredstring<uuid>—
user_idstringYour external_user_id. Present on create; absent when listing or fetching.
kind requiredstringswap buys one of OUR assets: the output lands on the user's own deposit address and is credited to their balance. exchange buys a coin we do not custody: the output is paid to destination_address and never enters our system. (one of swap, exchange)
sell_asset_id requiredstring—
buy_asset_id requiredstring | nullOne of our assets on a swap; null on an exchange (we have no asset row for it).
buy_asset_external requiredstring | nullThe exchange's identifier on an exchange (e.g. SOL.SOL); null on a swap.
buy_symbol requiredstring | nullDisplay ticker of the bought coin on an exchange, so a listing needs no catalogue lookup. Null on a swap.
buy_chain requiredstring | nullChain of the bought coin on an exchange, as the exchange names it. Null on a swap.
destination_addressstringWhere the bought coin was paid. Present on EXCHANGE rows ONLY — echoed back so you can confirm it — and absent on a swap, whose output goes to the user's own static wallet address. This payout is irreversible and outside our custody.
sell_amount requiredstringA monetary value as a decimal string. Always paired with a *_base field that carries the exact integer base-unit value; compute with the _base string.
sell_amount_base requiredstringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
fee requiredstringOur fee, taken out of sell_amount — a percentage with a dollar minimum (see GET /v1/pricing), plus network_fee.
fee_base requiredstringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
network_feestringThe network part of fee, in the sold asset — a USDT ⇄ TRX trade's own gas on TRON, or an exchange's send. Already inside fee.
network_fee_basestringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
receive_estimatestring | nullWhat the route estimated. A swap's is in the buy asset's major units; an exchange's is the exchange's decimal string.
receive_estimate_basestring | nullExact base units on a SWAP. Always null on an exchange.
receive_minimumstring | nullThe floor the route guaranteed. The user is credited what arrives, not this.
receive_minimum_basestring | nullExact base units on a SWAP. Always null on an exchange.
receivedstring | nullWhat ACTUALLY arrived. Null until the exchange settles.
received_basestring | nullExact base units on a SWAP. Always null on an exchange.
providers requiredstring[]—
status requiredstringpending until the sell leg is on-chain, then sent and swapping while the exchange works; completed when it reports the payout. (one of pending, sent, swapping, completed, refunded, failed)
tracking_statusstring | nullThe exchange's own last word on the route, verbatim. Informational.
txidstring | nullThe on-chain SELL payment that started the order — the handle to show a customer, and the one the exchange's tracker keys on. Null until it is sent.
created_at requiredstring<date-time>—
updated_at requiredstring<date-time>—
json
{
  "order_id": "string",
  "user_id": "string",
  "kind": "swap",
  "sell_asset_id": "string",
  "buy_asset_id": "string",
  "buy_asset_external": "string",
  "buy_symbol": "string",
  "buy_chain": "string",
  "destination_address": "string",
  "sell_amount": "1.5",
  "sell_amount_base": "1500000000",
  "fee": "1.5",
  "fee_base": "1500000000",
  "network_fee": "1.5",
  "network_fee_base": "1500000000",
  "receive_estimate": "string",
  "receive_estimate_base": "string",
  "receive_minimum": "string",
  "receive_minimum_base": "string",
  "received": "string",
  "received_base": "string",
  "providers": [
    "string"
  ],
  "status": "pending",
  "tracking_status": "string",
  "txid": "string",
  "created_at": "2026-08-31T09:15:00.000Z",
  "updated_at": "2026-08-31T09:15:00.000Z"
}

#Example request

bash
curl -X POST 'https://api.cryptoinfra.build/v1/swap/orders' \
  -H 'Authorization: Bearer ck_live_your_key' \
  -H 'Content-Type: application/json' \
  -d '{
  "sell_asset_id": "usdt_trc20",
  "buy_asset_id": "trx",
  "amount": "100",
  "user_id": "string"
}'

#GET/v1/swap/orders/{id}

Fetch one order · Auth: bearer API key · operationId: getSwapOrder

The authoritative read, for either kind — another merchant's order is simply 404. Poll it while status is pending, sent or swapping.

On a SWAP, received is what actually arrived and was credited to the user's balance; it stays null until the output confirms, so a completed status with a populated received is the signal to tell your customer it is done.

user_id is not echoed here — it is returned on create, and by GET /v1/swap/orders/{id}/detail.

#Parameters

NameInTypeRequiredDescription
idpathstring<uuid>yesThe order_id from create or the list.

#Responses

StatusBodyMeaning
200SwapOrderThe order.
401ErrorMissing, malformed or unknown API key.
404ErrorUnknown order, or one belonging to another merchant — the two are indistinguishable by design.

200 response body — SwapOrder

FieldTypeDescription
order_id requiredstring<uuid>—
user_idstringYour external_user_id. Present on create; absent when listing or fetching.
kind requiredstringswap buys one of OUR assets: the output lands on the user's own deposit address and is credited to their balance. exchange buys a coin we do not custody: the output is paid to destination_address and never enters our system. (one of swap, exchange)
sell_asset_id requiredstring—
buy_asset_id requiredstring | nullOne of our assets on a swap; null on an exchange (we have no asset row for it).
buy_asset_external requiredstring | nullThe exchange's identifier on an exchange (e.g. SOL.SOL); null on a swap.
buy_symbol requiredstring | nullDisplay ticker of the bought coin on an exchange, so a listing needs no catalogue lookup. Null on a swap.
buy_chain requiredstring | nullChain of the bought coin on an exchange, as the exchange names it. Null on a swap.
destination_addressstringWhere the bought coin was paid. Present on EXCHANGE rows ONLY — echoed back so you can confirm it — and absent on a swap, whose output goes to the user's own static wallet address. This payout is irreversible and outside our custody.
sell_amount requiredstringA monetary value as a decimal string. Always paired with a *_base field that carries the exact integer base-unit value; compute with the _base string.
sell_amount_base requiredstringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
fee requiredstringOur fee, taken out of sell_amount — a percentage with a dollar minimum (see GET /v1/pricing), plus network_fee.
fee_base requiredstringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
network_feestringThe network part of fee, in the sold asset — a USDT ⇄ TRX trade's own gas on TRON, or an exchange's send. Already inside fee.
network_fee_basestringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
receive_estimatestring | nullWhat the route estimated. A swap's is in the buy asset's major units; an exchange's is the exchange's decimal string.
receive_estimate_basestring | nullExact base units on a SWAP. Always null on an exchange.
receive_minimumstring | nullThe floor the route guaranteed. The user is credited what arrives, not this.
receive_minimum_basestring | nullExact base units on a SWAP. Always null on an exchange.
receivedstring | nullWhat ACTUALLY arrived. Null until the exchange settles.
received_basestring | nullExact base units on a SWAP. Always null on an exchange.
providers requiredstring[]—
status requiredstringpending until the sell leg is on-chain, then sent and swapping while the exchange works; completed when it reports the payout. (one of pending, sent, swapping, completed, refunded, failed)
tracking_statusstring | nullThe exchange's own last word on the route, verbatim. Informational.
txidstring | nullThe on-chain SELL payment that started the order — the handle to show a customer, and the one the exchange's tracker keys on. Null until it is sent.
created_at requiredstring<date-time>—
updated_at requiredstring<date-time>—
json
{
  "order_id": "string",
  "user_id": "string",
  "kind": "swap",
  "sell_asset_id": "string",
  "buy_asset_id": "string",
  "buy_asset_external": "string",
  "buy_symbol": "string",
  "buy_chain": "string",
  "destination_address": "string",
  "sell_amount": "1.5",
  "sell_amount_base": "1500000000",
  "fee": "1.5",
  "fee_base": "1500000000",
  "network_fee": "1.5",
  "network_fee_base": "1500000000",
  "receive_estimate": "string",
  "receive_estimate_base": "string",
  "receive_minimum": "string",
  "receive_minimum_base": "string",
  "received": "string",
  "received_base": "string",
  "providers": [
    "string"
  ],
  "status": "pending",
  "tracking_status": "string",
  "txid": "string",
  "created_at": "2026-08-31T09:15:00.000Z",
  "updated_at": "2026-08-31T09:15:00.000Z"
}

#Example request

bash
curl -X GET 'https://api.cryptoinfra.build/v1/swap/orders/string' \
  -H 'Authorization: Bearer ck_live_your_key'

#GET/v1/swap/orders/{id}/detail

Fetch one order in full — addresses, send leg, origin and timeline · Auth: bearer API key · operationId: getSwapOrderDetail

Everything GET /v1/swap/orders/{id} returns, plus every hop: the exchange's one-time deposit address, the address the output went to, the on-chain send with its confirmations, who asked for the order and from where, and the story in order. Enough to answer "where is my money" from a block explorer without opening a ticket.

Deliberately narrower than the operator's view of the same order. You see YOUR facts — your team member, your IP, your addresses, your money — not what the send cost us in gas or the ledger account codes behind it.

received_deposit is LABELLED, never asserted: nothing on-chain ties a swap to the deposit that credited it, so this is our best match by asset, amount and time. confidence says how far to trust it (ambiguous means a second deposit could equally be this swap's output) and a page should present it as likely, not as fact. It is always null on an exchange, whose output never reaches us.

#Parameters

NameInTypeRequiredDescription
idpathstring<uuid>yesThe order_id from create or the list.

#Responses

StatusBodyMeaning
200SwapOrderDetailThe order in full.
401ErrorMissing, malformed or unknown API key.
404ErrorUnknown order, or one belonging to another merchant — the two are indistinguishable by design.

200 response body — SwapOrderDetail

FieldTypeDescription
order_id requiredstring<uuid>—
user_id requiredstringYour external_user_id. Always present here, unlike the summary shape.
kind requiredstringswap buys one of OUR assets: the output lands on the user's own deposit address and is credited to their balance. exchange buys a coin we do not custody: the output is paid to destination_address and never enters our system. (one of swap, exchange)
sell_asset_id requiredstring—
buy_asset_id requiredstring | nullOne of our assets on a swap; null on an exchange (we have no asset row for it).
buy_asset_external requiredstring | nullThe exchange's identifier on an exchange (e.g. SOL.SOL); null on a swap.
buy_symbol requiredstring | nullDisplay ticker of the bought coin on an exchange, so a listing needs no catalogue lookup. Null on a swap.
buy_chain requiredstring | nullChain of the bought coin on an exchange, as the exchange names it. Null on a swap.
destination_address requiredstringWhere the output was sent. Always present here for BOTH kinds: on a swap it is the user's own static wallet address on the buy asset's chain (the summary shape omits it there), and on an exchange it is the address you supplied.
sell_amount requiredstringA monetary value as a decimal string. Always paired with a *_base field that carries the exact integer base-unit value; compute with the _base string.
sell_amount_base requiredstringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
fee requiredstringOur fee, taken out of sell_amount — a percentage with a dollar minimum (see GET /v1/pricing), plus network_fee.
fee_base requiredstringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
network_feestringThe network part of fee, in the sold asset — a USDT ⇄ TRX trade's own gas on TRON, or an exchange's send. Already inside fee.
network_fee_basestringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
receive_estimatestring | nullWhat the route estimated. A swap's is in the buy asset's major units; an exchange's is the exchange's decimal string.
receive_estimate_basestring | nullExact base units on a SWAP. Always null on an exchange.
receive_minimumstring | nullThe floor the route guaranteed. The user is credited what arrives, not this.
receive_minimum_basestring | nullExact base units on a SWAP. Always null on an exchange.
receivedstring | nullWhat ACTUALLY arrived. Null until the exchange settles.
received_basestring | nullExact base units on a SWAP. Always null on an exchange.
providers requiredstring[]—
status requiredstringpending until the sell leg is on-chain, then sent and swapping while the exchange works; completed when it reports the payout. (one of pending, sent, swapping, completed, refunded, failed)
tracking_statusstring | nullThe exchange's own last word on the route, verbatim. Informational.
txidstring | nullThe on-chain SELL payment that started the order — the handle to show a customer, and the one the exchange's tracker keys on. Null until it is sent.
created_at requiredstring<date-time>—
updated_at requiredstring<date-time>—
send_amount requiredstringsell_amount minus fee — what was actually paid to the exchange.
send_amount_base requiredstringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
exchange_address requiredstringThe exchange's one-time deposit address for THIS order — where the sell payment went. The first hop to follow on a block explorer.
swap_id requiredstring | nullThe exchange's own id for the route, for a support conversation with them.
sent_at requiredstring<date-time> | nullWhen the sell payment reached the chain. Null before that.
settled_at requiredstring<date-time> | nullWhen the exchange reported a terminal state. Null while still moving.
error requiredstring | nullWhy the order failed, when it did.
send requiredobject | nullThe withdrawal that paid the exchange. Null until it exists.
send.status requiredstring—
send.txid requiredstring | null—
send.confirmations requiredinteger—
send.block_height requiredinteger | null—
send.error requiredstring | null—
origin requiredobject | nullWho asked for this order and from where. Null when nothing was recorded.
origin.actor_email requiredstring | nullThe dashboard login that asked. Null when an API key did — there is no person.
origin.ip requiredstring | null—
origin.ip_geo requiredobject | nullGeolocation of ip, or null when lookup is off, failed, or the address is private.
origin.user_agent requiredstring | null—
origin.via requiredstring | null(one of dashboard_session, api_key, null)
origin.at requiredstring<date-time>—
received_deposit requiredobject | nullOur best MATCH for the deposit that credited this swap's output — a label, not an assertion, because nothing on-chain ties the two together. Null on an exchange (its output never reaches us) and until a candidate appears.
received_deposit.amount requiredstringA monetary value as a decimal string. Always paired with a *_base field that carries the exact integer base-unit value; compute with the _base string.
received_deposit.amount_base requiredstringExact integer amount in the asset's smallest unit. (pattern ^[0-9]+$)
received_deposit.txid requiredstring—
received_deposit.status requiredstring—
received_deposit.credited_at requiredstring<date-time> | null—
received_deposit.confidence requiredstringunconfirmed is a single plausible match; ambiguous means more than one deposit could be this output — show the warning. (one of unconfirmed, ambiguous)
timeline requiredobject[]What happened, oldest first — e.g. Swap requested, Fee charged, Balance held, Payment signed, Payment on chain, Payment confirmed, Output seen on chain, Credited to balance. Human-readable and additive; new steps may appear, so render the list rather than switching on it.
timeline[].at requiredstring<date-time>—
timeline[].event requiredstring—
timeline[].detail requiredstring | nullThe step's one supporting fact (often a txid). Null when there is none.
json
{
  "order_id": "string",
  "user_id": "string",
  "kind": "swap",
  "sell_asset_id": "string",
  "buy_asset_id": "string",
  "buy_asset_external": "string",
  "buy_symbol": "string",
  "buy_chain": "string",
  "destination_address": "string",
  "sell_amount": "1.5",
  "sell_amount_base": "1500000000",
  "fee": "1.5",
  "fee_base": "1500000000",
  "network_fee": "1.5",
  "network_fee_base": "1500000000",
  "receive_estimate": "string",
  "receive_estimate_base": "string",
  "receive_minimum": "string",
  "receive_minimum_base": "string",
  "received": "string",
  "received_base": "string",
  "providers": [
    "string"
  ],
  "status": "pending",
  "tracking_status": "string",
  "txid": "string",
  "created_at": "2026-08-31T09:15:00.000Z",
  "updated_at": "2026-08-31T09:15:00.000Z",
  "send_amount": "1.5",
  "send_amount_base": "1500000000",
  "exchange_address": "string",
  "swap_id": "string",
  "sent_at": "2026-08-31T09:15:00.000Z",
  "settled_at": "2026-08-31T09:15:00.000Z",
  "error": "string",
  "send": {
    "status": "string",
    "txid": "string",
    "confirmations": 1,
    "block_height": 1,
    "error": "string"
  },
  "origin": {
    "actor_email": "string",
    "ip": "string",
    "ip_geo": {},
    "user_agent": "string",
    "via": "dashboard_session",
    "at": "2026-08-31T09:15:00.000Z"
  },
  "received_deposit": {
    "amount": "1.5",
    "amount_base": "1500000000",
    "txid": "string",
    "status": "string",
    "credited_at": "2026-08-31T09:15:00.000Z",
    "confidence": "unconfirmed"
  },
  "timeline": [
    {
      "at": "2026-08-31T09:15:00.000Z",
      "event": "Payment on chain",
      "detail": "string"
    }
  ]
}

#Example request

bash
curl -X GET 'https://api.cryptoinfra.build/v1/swap/orders/string/detail' \
  -H 'Authorization: Bearer ck_live_your_key'