Crypto Swap API: 6 Steps from Price to Signed Swap
Build a crypto swap flow for price, quote, approval, and plan handling. Follow the checklist with six steps and see how CryptoPayr supports hosted swaps.
Build a crypto swap flow for price, quote, approval, and plan handling. Follow the checklist with six steps and see how CryptoPayr supports hosted swaps.

A working swap integration follows one path: fetch an indicative price for the UI, request a firm quote when the user commits, confirm or set the token approval, then sign and broadcast the transaction payload the quote returns. Chained or cross-chain trades branch into a separate plan workflow instead of a single transaction, and every quote deserves a simulation check before you ask anyone to sign anything.
TL;DR:
- Keep the API key on your server, read the approval spender from each quote, and use that exact address instead of a hardcoded contract.
- Because quotes often expire after about 30 seconds, fetch a fresh quote after approval confirms and show fees, route, and minimum received before signing.
- For CHAINED routes, create a plan, handle each step, submit proof for each, and poll until COMPLETE; request a new quote after STEP_ERROR.
- Start with 100 Bps of slippage, the common default; lower limits can leave no executable route, while higher limits expose traders to worse prices.
- Use the API’s quoted gas limit with a buffer instead of calling eth_estimateGas, which may underestimate gas for unpredictable settlement paths and cause reverts.
A /price call is read-only. It gives you an indicative rate to render in the UI while a user types an amount, with no commitment and no transaction data attached. A /quote call is the executable version: it locks a route and returns a transaction object containing to, data, value, and gas, ready to hand to a wallet library for signing. This is the firm quote to transaction pattern described in 0x’s swap API quickstart.
Keep the API key server-side and route frontend calls through your own backend. This avoids exposing secrets in client bundles and lets you centralize rate-limit handling, since most providers return rate-limit headers you should log and respect rather than discover through 429 errors in production.
Before forwarding a quote to your wallet integration, check these fields:
routing: tells you whether this is a single transaction or a CHAINED plan.transaction.data and transaction.to: the actual calldata and contract to sign against.permitData: present when the route expects a Permit2 signature instead of a standard approval.issues.allowance.spender: the contract address the user must approve, which you should always read from the response rather than hardcoding.Build the backend proxy first, then wire up the client in this order:
/api/price and /api/quote proxy routes that attach your API key server-side and apply basic rate-limiting./api/price on every amount change to show an indicative rate./api/quote to get the firm, executable payload.issues.allowance.spender from the quote response; if the user’s allowance is insufficient, prompt an approval transaction against that exact spender address.transaction.to, transaction.data, transaction.value, and transaction.gas to your wallet library and submit.Start with AllowanceHolder as your baseline approval model since it is the simpler path for most integrations, and consider Permit2 only once you can comfortably manage its EIP-712 signature UX, per the guidance in 0x’s API reference.
Quotes are short-lived, often around 30 seconds, so build a re-fetch pattern that reprices automatically if the user lingers before confirming. Show the fee, route, and minimum received amount before the wallet prompt fires, not after.
Pro Tip: Re-fetch the quote immediately after an approval transaction confirms, since gas conditions and routing can shift in the time it took the approval to mine.
When a quote’s routing field returns CHAINED, you are no longer executing a single transaction. You need to call POST /plan to get a planId and an ordered list of steps, a pattern detailed in both 0x’s quickstart and Uniswap’s swapping API integration guide.
Each step in the plan has a type you need to handle explicitly:
SEND_TX: submit the transaction on-chain and return the resulting txHash to the plan.SIGN_MSG: sign an EIP-712 payload, typically for Permit2 or a UniswapX order.SEND_CALLS: submit a batch of calls together rather than one at a time.After each step, submit proof of completion via PATCH /plan, then poll with GET /plan (optionally with forceRefresh) until the plan reaches COMPLETE. Watch for STEP_ERROR states, which usually mean you need to re-quote rather than retry the same step. Some routes map to UniswapX orders that require POST /order instead of a direct swap call, so branch on the routing type before assuming a single execution path.
Slippage tolerance is set in basis points, and 100 Bps equals 1%, which is the common default across major swap APIs. Setting it too low can cause a quote to fail entirely when no route can execute within that bound; setting it too high protects execution but exposes the user to worse pricing on volatile pairs. Most integrations start at 100 Bps and let advanced users adjust from there.
For gas, use the transaction.gas value the API returns rather than calling eth_estimateGas yourself. Guidance from 0x’s troubleshooting docs notes that eth_estimateGas can return a limit that is too low because it doesn’t account for non-deterministic settlement paths. Add a buffer on top of the quoted gas limit; unused gas is refunded, so overestimating costs nothing but a reverted transaction costs real fees.
Pro Tip: Simulate every quote and check liquidityAvailable before triggering a wallet signature. Surfacing a “NoRoute” or insufficient-liquidity error before signing saves users a wasted gas fee and a confusing failure after confirmation.

Most teams building a swap UI lean on a small, stable set of tools:
Approval handling has one well-known trap: some ERC-20 tokens, including USDT, revert if you try to change a nonzero allowance directly. The standard fix is a two-step reset: set the allowance to zero first, wait for confirmation, then set it to the required amount. Always read the spender address from the API response rather than approving a settlement contract address you’ve hardcoded, and only move to Permit2 once your team is ready to manage its EIP-712 signature flow end to end.
Everything above maps directly onto the instant crypto exchange API designed for developers who want swap functionality without running their own liquidity routing.
Developer documentation and code samples for the exchange API cover the same price-to-quote-to-settlement sequence described in this guide, so teams already familiar with aggregator-style flows can adapt existing integration code with minimal rework.
This guide was written by Dustin for development teams evaluating swap integration paths.
Ship the simpler approval model first. AllowanceHolder gets a working swap into production faster, and you can migrate to Permit2 once you have real usage data to justify the added signature complexity. Track quote expiry failures and routing errors from day one; that telemetry tells you where to spend your next engineering cycle, not guesswork. Test every approval and plan step on testnets before touching mainnet liquidity.
— Dustin
If you would rather ship the integration this week than build and maintain route-aggregation logic yourself, our instant crypto exchange gives you a no-KYC swap API that handles pricing, quoting, and settlement behind endpoints you can wire up using the same patterns covered above. Pricing details for the service are available on the pricing page of the provider’s website.

For teams that also need fiat-adjacent compliance tooling alongside crypto rails, automated KYC and onboarding from our partner POW IT UP pairs well with a KYC-free swap layer when you need both in the same product.
Check out the developer documentation for endpoint references and code samples, or get in touch to request an API key and start testing in a sandbox environment today.
A price is an indicative, non-binding estimate meant for live UI display as a user types an amount. A quote is the firm, executable version that returns the actual transaction payload, including to, data, value, and gas, ready for wallet signing.
You need the plan workflow whenever a quote’s routing field returns CHAINED, which signals a multi-step or cross-chain trade rather than a single transaction. Call POST /plan to get a planId and step list, then submit proof of each step via PATCH /plan and poll GET /plan until the status reaches COMPLETE.
AllowanceHolder is the recommended starting point for most integrations because it avoids the extra EIP-712 signature UX that Permit2 requires. Move to Permit2 once your team can handle its gasless signature flow and the backend validation it adds.
100 Bps (1%) is the common default across major swap APIs, and it balances execution success against price protection for most trades. Setting slippage too low can cause quotes to fail outright when no route fits within that bound.
No, our instant crypto exchange is built as a no-KYC swap API, letting integrators onboard without collecting identity documents from end users.
Open a free CryptoPayr account and take your first crypto payment the same day.
Get started for free
Test crypto payments safely with sandbox checks, public testnets, and regtest. Verify checkout, webhooks, confirmations, refunds, and edge cases before...
Secure crypto IPN webhooks with HTTPS, signature checks, replay protection, and idempotency. Learn how to prevent retries from fulfilling orders twice.
Add wallet support to crypto checkout with hosted checkout, plugins, or an API fallback. Cover mobile handoffs, secure requests, and gasless options.