Skip to main content
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

  1. Your backend starts an order with POST /onramp/orders and kind: "exchange".
  2. Your app shows the hosted flow in an iframe or in-app browser.
  3. The user chooses an exchange and completes the transfer in Swapped’s hosted flow.
  4. The order advances through its stages, pushed as ramp-order webhooks.
  5. 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.