The partner API is a pay-in rail, not a wallet. A customer pays in whichever of the listed assets they hold, an exchange provider converts it, and the settlement lands in the asset and network your finance team asked for — in your own wallet, in one hop, with nobody holding a float in between.
- One quote request reaches every connected exchange at once.
- Each checkout is one order, tagged with your own order number.
- Crypto payments do not reverse: there are no chargebacks to reserve against.
- No custody means no client-money balance sitting on your books or ours.
A checkout, endpoint by endpoint
-
Offer what can actually be paid right now
GET /v1/assetsreturns every asset and network with a provider behind it. Cache it for a few minutes and render it as the "pay with" list — an asset nobody can serve should never reach the customer. -
Price the cart in your settlement asset
The cart is
149.00 USDT; the customer wants to pay in ETH. Quote withamount_to=149and the offer answers with the exactFromAmount.rate_type=fixedkeeps that number still while the customer pays. -
Open the order against your settlement wallet
to_addressis your treasury address — it never changes per customer.client_order_idis your shop's order number, and it is what reconciliation reads later. Send anIdempotency-Key: a retried checkout must not become two orders. -
Render the payment screen
DepositAddress,AmountFrom, the network, a QR and a countdown. Nothing else is needed, and nothing else should be shown — a wrong network is the single most common way a crypto payment goes missing. -
Release the goods on a terminal status
Poll
GET /v1/partner/orders/{id}every 5–10 seconds.DONEcarries the settledAmountToReceivedand the payoutTxID; that is your proof of payment.
Streaming the price into the checkout
A checkout that waits for the slowest exchange feels broken. Stream instead — offers arrive as each provider answers, the first usually inside 400 ms:
// Your backend. The key never reaches the browser; proxy this to the client.
const url = new URL("https://api.swapzilla.io/v1/partner/quotes-sse");
url.search = new URLSearchParams({
from_asset: "ETH", from_network: "ERC20",
to_asset: "USDT", to_network: "TRC20",
amount_to: "149", rate_type: "fixed", timeout_ms: "5000",
});
const res = await fetch(url, {
headers: { "X-API-Key": process.env.SWAPZILLA_KEY, Accept: "text/event-stream" },
});
// events: offer · provider_error · ping · done
// `done` carries { deviations: { "<offer_id>": 0.16 } } — the final ranking.
Then the order, with everything reconciliation will want:
curl -s -X POST "https://api.swapzilla.io/v1/partner/orders" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c0b52-6f2a-4d43-9f4a-1a0d64c1f3a2" \
-d '{
"offer_id": "0b0c8f0e-2c1a-4f3f-8f57-2a1d1c4e77aa",
"to_address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"refund_address": "0x750c44dB01899176f2e64bD25A2fabAC1140d8e9",
"client_order_id": "SHOP-88214",
"expected_to_amount": 149
}'
Validate before you charge. Every offer carries
MinFromAmount and MaxFromAmount; a cart below a
provider's minimum fails at order creation, not at quote time. Check the
bounds, and check the customer's refund address with
GET /v1/validate-address, before the payment screen appears.
Reconciliation and support
| You need | Where it comes from |
|---|---|
| Today's payments | GET /v1/partner/orders?page=1&limit=100 — yours only, newest first, paged. |
| Which shop order a payment belongs to | client_order_id, echoed back on the order. |
| Proof the customer was paid out | TxID and AmountToReceived on a DONE order. |
| A reference a provider's support will recognise | ProviderOrderID — log it next to your own id. |
| An answer right now, not in ten seconds | POST /v1/partner/orders/{id}/refresh goes to the provider synchronously. At most once every five seconds. |
What the API does not do
| Not included | What that means for you |
|---|---|
| Fiat settlement | There is no off-ramp to a bank account. Settle in a stablecoin and cash out through your own channel. |
| Webhooks | None yet — checkout status comes from polling, or from a stream you run yourself over the polled state. |
| A hosted checkout page | The page, the branding and the emails are yours; the API supplies amount, address and status. |
| Wallet screening, AML scoring or graph analytics | Not part of this API at all. If your compliance programme needs them, they come from a separate vendor. |
| Refunds as an operation | A failed swap is refunded by the provider to refund_address. A completed payment cannot be reversed through the API. |
Who runs a checkout like this
- Shops and SaaS that want a stablecoin balance rather than a portfolio: customers pay in fifty assets, you settle in one.
- Digital goods and top-ups, where irreversible payment removes the fraud reserve entirely.
- Marketplaces settling to each seller's own wallet — the platform routes the payment without ever holding it.
- Services billing customers on chains they never wanted to support: the provider network handles the conversion, not your treasury.
Questions
Is SwapZilla a payment service provider holding my money?
No. The swap is non-custodial: the customer's coins go straight to the exchange provider's deposit address and the provider pays out to the address you supplied. SwapZilla never takes possession of the funds, so there is no balance to withdraw and no payout schedule to wait for.
How do I get notified when a payment completes?
By polling GET /v1/partner/orders/{id} every 5–10 seconds until the status is terminal. There are no webhooks yet; our own poller refreshes each open order every ten seconds, so nothing faster than that gains you anything.
What protects me from the rate moving during checkout?
Three things: quote with rate_type=fixed so the provider locks the rate, treat the five-minute offer expiry as your checkout window, and pass expected_to_amount so an order whose payout drifted is refused instead of created.
Can I accept payment in one asset and settle in another?
That is the default. The customer chooses the source asset and network from /v1/assets, and your settlement asset, network and address are fixed in the order — the provider does the conversion in between.
Does the API screen customer wallets for AML risk?
No. The partner API quotes, executes and reports exchanges; it performs no wallet screening, risk scoring or transaction-graph analysis. Offers do carry a KycRating from A to D, but that describes how intrusive the provider's own KYC is, not the customer's risk.
How many assets can a customer pay with?
GET /v1/assets is the live answer — the top-100 assets by market cap, each listed with its networks and the providers currently serving them. It changes as providers come and go, which is why it should be read rather than hard-coded.
What else the same key builds
- Crypto payment links and invoicesPay-by-link and invoicing for freelancers and contractors — quote by the amount due, settle straight to the payee's wallet.
- Crypto exchange API, SDK and swap widgetEmbed swaps in a wallet, bot, aggregator or website — streaming quotes, one order call, your own UI.
- Crypto payroll for contractors and remote teamsRecurring payouts to a contractor roster: each person's own asset and network, exact net amounts, per-run reconciliation.
- Multi-send: batch payouts to many addressesOne-off fan-out to hundreds of addresses: cross-chain, per-recipient status, safe retries.
- Your own MCP server for AI agentsThe published swapzilla-mcp server in one line — or your own, on your partner key, with allow-lists and spending caps.
- Streaming quotes, live rates and price alertsServer-sent quote streaming, an always-fresh rate feed and order tracking you can turn into alerts.
Getting a key
Register in the partner cabinet and your partner id and the api_key that goes in X-API-Key are issued at once. The key starts working once it is activated: write to @swapzilla_support_bot with a sentence about what you are building. Every endpoint, field and status is in the partner API reference.