Skip to main content
POST /offramp/initiate endpoint creates an off-ramp transaction where the customer sends stablecoin and receives Euro (EUR) instantly. Switch returns a deposit address — once the customer sends the amount in the speicifed asset to that address, the EUR payout is processed automatically.
Before calling this endpoint to create a payment, call GET /requirement to retrieve the required beneficiary fields based on the country and channel.

Example request

curl https://api.onswitch.xyz/offramp/initiate \
  --request POST \
  --header 'Content-Type: application/json' \
  --header 'x-service-key: '"$YOUR_SERVICE_KEY" \
  --data '{
  "country": "DE",
  "currency": "EUR",
  "amount": 56.082951,
  "asset": "base:usdc",
  "narration": "Bank transfer to John Doe",
  "channel": "BANK",
  "beneficiary": {
    "holder_city": "Berlin",
    "holder_name": "John Doe",
    "holder_postal_code": "10117",
    "holder_street": "Revolut Bank UAB",
    "holder_type": "INDIVIDUAL",
    "iban": "DE41100101789312345678",
    "reason": "PERSONAL_TRANSFER"
  }
}'

Frequently Asked Questions

Add exact_output and amount if you want an exact amount to be received at the destination. e.g; if you want 10,000 EUR
{
  "exact_output": true,
  "amount": 10000
}
Add callback_url to set the URL to receive webhook notifications when the payment status changes.
{
  "callback_url": "https://your-webhook-url.com"
}
Add developer_fee and developer_recipient to set the developer fee you wish to charge from the payment amount.
{
  "developer_fee": 0.5,
  "developer_recipient": "0x1234567890123456789012345678901234567890"
}
Include holder_type on beneficiary depending on the payout recipient; if Business, set to BUSINESS else INDIVIDUAL.
{
  "beneficiary": {
    "holder_type": "INDIVIDUAL"
  }
}
Add reason to set the purpose of the payment. This is mostly required for transfers out of Nigeria.
{
  "reason": "CAPITAL_CONTRIBUTIONS"
}
Allowed values are listed under Reason.
Add refund_address to set the wallet address to refund the stablecoin deposit to if the payment fails for any reason.
{
  "refund_address": "0x1234567890123456789012345678901234567890"
}
Add channel to set the specific channel or settlement method to use for the payment, if not set, the default channel for the country will be used.
{
  "channel": "BANK"
}
Allowed values are listed under Countries.
Add static if you want to always generate the same deposit address for the same local currency beneficiary details.
{
  "static": true
}

Example response

{
  "success": true,
  "message": "Offramp initiated successfully",
  "timestamp": "2026-03-31T04:03:15.931Z",
  "data": {
    "status": "AWAITIGB_DEPOSIT",
    "type": "OFFRAMP",
    "reference": "6c01338d-67e5-4d0c-a394-9d3e367f46a5",
    "rate": 0.8207,
    "source": {
      "amount": 56.082951,
      "currency": "USDC",
      "network": "BASE"
    },
    "destination": {
      "amount": 46.031947,
      "currency": "EUR",
      "network": "FIAT"
    },
    "deposit": {
      "amount": 56.082951,
      "address": "0xcd257a5867B42556fa14c35de714154B277f70fD",
      "asset": "base:usdc",
      "note": [
        "Kindly send the exact amount to the wallet address to complete the transaction.",
        "This dynamic wallet address has a 30 minutes expiry window and can only be used once."
      ]
    }
  }
}

Completing the Deposit

After initiating, you are expected to send exactly deposit.amount of deposit.asset to deposit.address. Check deposit.note for specific instructions.
The deposit address is for one-time use only and expires after 30 minutes. if not created with static set to true.
If less or more amount than specified in deposit.amount is sent, the deposit will be processed based on the amount sent, so long as it is within the limits and the asset (deposit.asset) sent is supported.

Need Help?

Email Support

Send us a message and we’ll get back to you shortly.

Book a Demo

Hop on a call with our team.