Start an exchange order for a registered account, then show Swapped’s hosted Connect flow in your app. Headless means you do not use the Rhinestone widget; users still complete the provider flow in Swapped’s UI.
How it works
- Your backend starts an order with
POST /onramp/orders and kind: "exchange".
- Your app shows the hosted flow in an iframe or in-app browser.
- The user chooses an exchange and completes the transfer in Swapped’s hosted flow.
- The order advances through its stages, pushed as
ramp-order webhooks.
- The funded crypto lands on the account and enters the standard deposit pipeline.
Prerequisites
- The account is registered. Starting an order for an account that is not registered to your project returns
403 Unauthorized.
- A webhook URL is configured if you want order updates pushed rather than polled.
- Calls are made from your backend. The endpoints require your API key, which never ships in client-side code.
Start an order
provider, kind, and account are required. There’s no amount or payment-method prefill; the user chooses those inside the exchange flow. The optional fields:
connections is not forwarded to Swapped, whose picker is configured per partner. Only connection narrows what a session shows, which is why declaring an allowlist without one is refused.
The response matches the onramp checkout response: 202 with orderId, nextAction, and expiresAt. Full schema: POST /onramp/orders.
List exchanges
List the connections to offer:
By default this lists the centralized exchanges. Pass connectionKind=wallet or connectionKind=all for Web3 wallets, or connections=binance,coinbase to resolve your own allowlist. Inside an embedded browser, offer no kind: "wallet" entry: that rail hands off to a wallet app over a URL scheme the container can’t open. Full schema: GET /onramp/options.
Show the hosted connection flow
Embed nextAction.url in an iframe with the permissions needed by the provider:
In a mobile app, open the URL in an in-app browser (SFSafariViewController on iOS, Chrome Custom Tabs on Android) rather than a plain WebView. Camera access and provider authentication can be restricted in bare WebViews.
The URL has no redirect or callback parameter. Detect completion through the ramp-order webhook or by polling the order, then dismiss the provider UI from your own interface.
A user who abandons the connection flow produces no terminal event. Apply your own timeout when waiting on an order.
Migrate from the deprecated routes
POST /onramp/swapped/connect-url and GET /onramp/swapped/connect-exchanges are deprecated. They keep working unchanged until their retirement is announced. Move to POST /onramp/orders with kind: "exchange" (smartAccount becomes account) and GET /onramp/options?kind=exchange (the kind filter becomes connectionKind, and the list is connections instead of exchanges). The mapping of the response is the same as for checkouts.