> ## 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.

# Swap stablecoins

> Convert between supported stablecoins.

**POST `/swap/initiate`** endpoint creates an swap transaction where the customer sends **`from_asset`** to the generated deposit address, the output is delivered to **`beneficiary.wallet_address`** on the destination (**`to_asset`**).

<Note>
  Use **GET `/quote`** with the same payload (**`from_asset`**, **`to_asset`**, **`amount`**, **`exact_output`**) to preview the output without creating a swap.
</Note>

## Example request

<CodeGroup>
  ```bash cURL theme={"dark"}
  curl https://api.onswitch.xyz/swap/initiate \
    --request POST \
    --header 'Content-Type: application/json' \
    --header 'x-service-key: '"$YOUR_SERVICE_KEY" \
    --data '{
    "amount": 100,
    "from_asset": "base:usdc",
    "to_asset": "bsc:usdt",
    "beneficiary": {
      "wallet_address": "0x1234567890123456789012345678901234567890"
    }
  }'
  ```

  ```javascript Node.js theme={"dark"}
  const res = await fetch('https://api.onswitch.xyz/swap/initiate', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-service-key': process.env.YOUR_SERVICE_KEY,
    },
    body: JSON.stringify({
      amount: 100,
      from_asset: 'base:usdc',
      to_asset: 'bsc:usdt',
      beneficiary: {
        wallet_address: '0x1234567890123456789012345678901234567890',
      },
    }),
  });

  const json = await res.json();
  console.log(json.data?.reference, json.data?.status);
  ```

  ```python Python theme={"dark"}
  import json
  import os
  import urllib.request

  payload = {
      "amount": 100,
      "from_asset": "base:usdc",
      "to_asset": "bsc:usdt",
      "beneficiary": {
          "wallet_address": "0x1234567890123456789012345678901234567890",
      },
  }

  req = urllib.request.Request(
      "https://api.onswitch.xyz/swap/initiate",
      method="POST",
      data=json.dumps(payload).encode("utf-8"),
      headers={
          "Content-Type": "application/json",
          "x-service-key": os.environ["YOUR_SERVICE_KEY"],
      },
  )

  with urllib.request.urlopen(req, timeout=60) as r:
      out = json.load(r)
      data = out.get("data") or {}
      print(data.get("reference"), data.get("status"))
  ```
</CodeGroup>

## Frequently Asked Questions

<AccordionGroup>
  <Accordion title="Exact destination amount" icon="circle-dollar-sign">
    Add exact\_output and amount if you want an exact amount to be received at the destination. e.g; if you want 100 USDT

    ```json theme={"dark"}
    {
      "exact_output": true,
      "amount": 100
    }
    ```
  </Accordion>

  <Accordion title="Webhook URL" icon="webhook">
    Add callback\_url to set the URL to receive webhook notifications when the payment status changes.

    ```json theme={"dark"}
    {
      "callback_url": "https://your-webhook-url.com"
    }
    ```
  </Accordion>
</AccordionGroup>

### Example response

```json theme={"dark"}
{
  "success": true,
  "message": "Swap initiated successfully",
  "timestamp": "2026-03-31T06:23:38.535Z",
  "data": {
    "status": "AWAITING_DEPOSIT",
    "type": "SWAP",
    "reference": "7ec6514e-d894-474e-87de-a796b1b96771",
    "rate": 0.999684,
    "source": {
      "amount": 100,
      "currency": "USDC",
      "network": "BASE"
    },
    "destination": {
      "amount": 100.031644952349,
      "currency": "USDT",
      "network": "BSC"
    },
    "deposit": {
      "amount": 100,
      "address": "0x24eAD3fe58DE7DbD031ADddd9f8E6199B9cC691e",
      "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.

<Warning>
  The deposit address is for **one-time use only** and expires after **30
  minutes**. if not created with **`static`** set to **`true`**.
</Warning>

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?

<CardGroup cols={2}>
  <Card title="Email Support" icon="mail" href="mailto:contact@onswitch.xyz">
    Send us a message.
  </Card>

  <Card title="Book a call" icon="calendar" href="https://calendly.com/contact-onswitch/30min">
    Hop on a call with us.
  </Card>
</CardGroup>
