Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.onswitch.xyz/llms.txt

Use this file to discover all available pages before exploring further.

Set webhook URL

Payments

Add callback_url to the request body when you call POST /offramp/initiate to create a payment for stablecoin to local currency conversion. See Stablecoin to NGN for a guide.

Wallets

Add callback_url when you call POST /wallet/create, or update it later on the wallet, so you can get webhook notifications about deposits and withdrawals on your wallet. See Create stablecoin wallet.

How notifications work

Switch sends each notification as:
  • Method: POST
  • Headers: Content-Type: application/json, x-switch-signature (HMAC-SHA256 hex digest of the raw body), x-switch-timestamp (when the request was sent; use for optional replay windows)
  • Body: JSON payload (depending on context; see Payment webhooks or Wallet webhooks)
Your server should acknowledge the request by returning any 2xx status quickly for successfully received notifications. Switch will retry delivery up to 3 times if the server does not acknowledge the request.

Verify webhooks

Always verify that incoming requests comes from Switch before you trust.

How to verify

  1. Read the body and the x-switch-signature header from the incoming request.
  2. Compute the expected webhook signature using your switch service key and the body.
  3. Compare the computed signature to the x-switch-signature from request header.
import crypto from 'crypto';

function verifySwitchWebhook(webhookBody, webhookSignature, yourServiceKey) {
const expected = crypto
.createHmac('sha256', yourServiceKey)
.update(webhookBody, 'utf8')
.digest('hex');
const a = Buffer.from(expected, 'utf8');
const b = Buffer.from(webhookSignature.trim(), 'utf8');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}

If verification fails, ignore the webhook and do not process it.

Payment webhooks

You receive these notifications whenever callback_url is set on your payment initiation request payload.

Payment status

StatusDescription
AWAITING_DEPOSITWaiting for the user to send the stablecoin.
PROCESSINGStablecoin received is being processed.
COMPLETEDStablecoin payout to local currency is completed.
FAILEDStablecoin payout to local currency failed.
REVERSEDStablecoin payout to local currency was reversed.
SCHEDULEDPayment is delayed due to liquidity constraints.
BLOCKEDPayment is blocked for compliance or risk reasons.

Example payload

For a USDC on Base to Nigeria Naira (NGN) in AWAITING_DEPOSIT status.
{
  "success": true,
  "message": "Offramp initiated successfully",
  "timestamp": "2026-04-23T14:35:04.264Z",
  "data": {
    "status": "AWAITING_DEPOSIT",
    "type": "OFFRAMP",
    "reference": "61f9a35a-e535-4f04-ba50-3058b4c856c4",
    "beneficiary": "69e8e664b9fea9f9e6dc3cbb",
    "rate": 1380.845,
    "developer_fee": {
      "amount": 0,
      "amount_usd": 0,
      "currency": "USDC",
      "network": "BASE"
    },
    "source": {
      "amount": 10,
      "amount_usd": 10,
      "network": "BASE",
      "currency": "USDC"
    },
    "destination": {
      "amount": 13808.45,
      "amount_usd": 10,
      "network": "FIAT",
      "currency": "NGN"
    },
    "deposit": {
      "amount": 10,
      "address": "0x3131b6f6a32751C9d99C1710e357A6C4297d17Bc",
      "asset": "base:usdc",
      "note": [
        "Kindly send the exact amount to the wallet address to complete the transaction.",
        "This wallet address is for one-time use only and has a 30 minutes expiry window."
      ]
    },
    "meta": {},
    "created_at": "2026-04-23T14:35:02.448Z",
    "updated_at": "2026-04-23T14:35:02.448Z"
  }
}

Payload field reference

FieldTypeDescription
statusstringCurrent status; see Payment status.
typestringOFFRAMP or ONRAMP.
referencestringUnique transaction reference (UUID).
source.amountnumberAmount of source to be sent.
source.currencystringSource currency code e.g. USDC.
source.networkstringSource network e.g. Base.
destination.amountnumberAmount of destination to be received.
destination.currencystringDestination currency code e.g. NGN.
destination.networkstringDestination network e.g. Fiat.
deposit.amountnumberAmount to send to the deposit address.
deposit.addressstringWallet address to send the amount to.
deposit.assetstringAsset to deposit e.g. base:usdc.
deposit.notestring[]Specific instructions for the deposit
meta.session_idstringPayout bank transfer session ID.
meta.explorer_urlstringURL to view the deposit on-chain.
meta.hashstringHash of the deposit transaction.
meta.session_id is only present when the bank payment has been initiated and is successfully processed.
meta.explorer_url and meta.hash are only present when the deposit has been made on-chain to the provided deposit address.

Wallet webhooks

You receive these notifications whenever callback_url is set on your wallet (at creation or via update) and the wallet receives or sends funds.

Example wallet payload

Incoming USDC on Base to the wallet address.
{
  "address": "0xe0836E4D35047843dA08D510dFb91E7ecd0c43FC",
  "wallet": "69d8d8f1ad6205a9a0e89302",
  "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
  "decimals": 6,
  "type": "receive",
  "sender": "0x04e05B9bCed583e4F25F7942684dCfe8Ab2632E1",
  "receiver": "0xe0836E4D35047843dA08D510dFb91E7ecd0c43FC",
  "hash": "0xb8ce59fc3717ada4c02eadf9682a9e934f625ebb",
  "amount": 100000000,
  "asset": "base:usdc"
}

Wallet payload field reference

FieldTypeDescription
addressstringWallet address involved in the event.
tokenstringContract address of the token on the network.
decimalsnumberToken decimals (for interpreting amount).
typestringreceive for deposits to the wallet, send for withdrawals from the wallet.
senderstringAddress that sent the funds.
receiverstringAddress that received the funds.
hashstringOn-chain transaction hash.
amountnumberAmount of the token.
assetstringSwitch asset id (e.g. base:usdc).

Need Help?

Email

Send us a message

Call

Book a call with us