Skip to content

Creating a session

Every Swapped Connect integration starts with a sessionId created on your backend — never compute the signature below in a browser, since it requires your secret key.

This is the same request used to build the hosted iframe URL. If you already have that working, generating a session for the SDK is the same signed request against a different path — sent as a POST, with no iframe to embed.

Endpoint

Use the host that matches the SDK environment. A staging sessionId will not load against production.

EnvironmentSession endpointSDK client
ProductionPOST https://connect-api.swapped.com/api/sessionsomit environment, or environment: 'production'
StagingPOST https://staging-api.swapped.app/api/sessionsenvironment: 'staging'

Parameters are passed as a query string on the POST request (not a JSON body) — identical to the iframe URL's query string.

ParamRequiredNotes
apiKeyYesYour publishable API key, from the "Developers" section of the Swapped dashboard
walletAddressYesDestination wallet(s): CURRENCY:NETWORK:ADDRESS[:AMOUNT], comma-separated for multiple currencies. AMOUNT is an optional minimum deposit (must be > 0)
signatureYesHMAC-SHA256 of the query string, signed with your secret key (see below)
baseCurrencyCodeNoFiat currency code for transactions (e.g. USD, EUR, GBP)
connectionNoExchange platform or wallet to use (e.g. Binance, Coinbase, Kraken, Phantom)
destinationTagNoNumeric destination tag (XRP) or text memo (TON)
baseCountryNoISO country code for the user's location; auto-detected if omitted
webhookUrlNoURL-encoded HTTPS URL to receive transaction webhooks
payWalletAddressNoWallet for Exchange Pay products, same format as walletAddress
externalCustomerIdNoYour own customer identifier
preferredCurrencyToReceiveNoDefault currency for Exchange Pay products: CURRENCY:NETWORK
nameNoURL-encoded merchant name shown in the Connect interface
logoNoURL-encoded, publicly accessible HTTPS URL to a merchant logo (PNG/SVG)

NETWORK in walletAddress / payWalletAddress is one of: bitcoin, litecoin, ethereum, solana, polygon, bsc, ripple, base, tron, avalanche, arb, cronos, fantom, optimism.

Sign the request

Same signing scheme as the iframe URL: HMAC-SHA256 over the query string (including the leading ?), Base64-encoded, then URL-encoded when appended.

ts
import crypto from 'crypto';

const apiKey = 'your-api-key';
const secretKey = 'your-secret-key'; // backend only
const walletAddress = 'BTC:bitcoin:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa:10';

const params = new URLSearchParams({ apiKey, walletAddress });
const signature = crypto
  .createHmac('sha256', secretKey)
  .update(`?${params.toString()}`)
  .digest('base64');

params.append('signature', signature);

const apiBaseUrl = 'https://connect-api.swapped.com' // or https://staging-api.swapped.app
const response = await fetch(
  `${apiBaseUrl}/api/sessions?${params.toString()}`,
  { method: 'POST' },
);

const { sessionId } = await response.json();

Use the sessionId

Pass the returned sessionId to the SDK in the browser — this package is client-only and must not run on the server. No redirect and no hosted widget iframe to embed (the SDK still mounts a hidden /gateway iframe when wallets or coinbase is enabled):

ts
import { createSwappedConnectClient } from '@swapped/connect-sdk';

const client = createSwappedConnectClient({
  sessionId,
  environment: 'production', // 'staging' if the session was created on staging
});
await client.loadSession();

Continue with Client (Core) or Client (React).

Errors

StatusMeaning
403Unknown apiKey, invalid signature, or the partner account is disabled
422Missing or malformed parameters (e.g. walletAddress empty)
500Unexpected server error