<!-- ZenPays documentation · https://docs.zenpayz.com/docs/rest-api/endpoints/ramp/widget-url -->

# Generate Widget URL

Generate a signed widget URL to embed the ramp experience in an iframe. Server-side signing ensures wallet addresses are tamper-proof. Works for both buy (on-ramp) and sell (off-ramp) modes.

<EndpointHeader verb="POST" path="/payment/api/v1/on-ramp/widget-url" />

<EndpointHeader verb="POST" path="/payment/api/v1/off-ramp/widget-url" />

The on-ramp endpoint defaults to `buy` mode; the off-ramp endpoint defaults to `sell` mode.

## Request

### Headers

<ParamTable
  label="Header"
  rows={[
    { name: "Content-Type", required: true, desc: "`application/json`" },
    { name: "x-request-id", desc: "Custom request ID for tracing" },
  ]}
/>

:::note Public Endpoint
This endpoint does not require authentication headers.
:::

### Body Parameters

<ParamTable
  rows={[
    { name: "mode", type: "string", desc: "`buy`, `sell`, or `buy,sell` (default depends on endpoint)" },
    { name: "defaultFiat", type: "string", desc: "Default fiat currency (e.g. `usd`)" },
    { name: "defaultCrypto", type: "string", desc: "Default crypto (e.g. `btc_bitcoin`)" },
    { name: "defaultAmount", type: "number", desc: "Default amount" },
    { name: "wallets", type: "string", desc: "TokenID:address format (e.g. `btc:bc1q...`)" },
    { name: "networkWallets", type: "string", desc: "NetworkID:address format (e.g. `ethereum:0x...`)" },
    { name: "walletAddressTags", type: "string", desc: "TokenID:tag format for memo coins" },
    { name: "successRedirectUrl", type: "string", desc: "URL to redirect on success" },
    { name: "failureRedirectUrl", type: "string", desc: "URL to redirect on failure" },
    { name: "onlyFiats", type: "string", desc: "Restrict fiat options (comma-separated)" },
    { name: "onlyCryptos", type: "string", desc: "Restrict crypto options (comma-separated)" },
    { name: "onlyCryptoNetworks", type: "string", desc: "Restrict networks (comma-separated)" },
    { name: "email", type: "string", desc: "Pre-fill user email" },
    { name: "uuid", type: "string", desc: "Unique user identifier" },
    { name: "partnerContext", type: "string", desc: "Custom tracking context" },
  ]}
/>

## Response

### Success (200 OK)

```json
{
  "success": true,
  "data": {
    "widgetUrl": "https://buy.onramper.com/?apiKey=...&mode=buy&defaultFiat=usd&defaultCrypto=BTC&wallets=btc:bc1q...&signature=abc123",
    "embedMode": "iframe"
  },
  "message": "Widget URL generated"
}
```

### Response Fields

<ParamTable
  rows={[
    { name: "widgetUrl", type: "string", desc: "Signed URL to embed in an iframe" },
    { name: "embedMode", type: "string", desc: "Always `iframe`" },
  ]}
/>

### Error Responses

<ErrorTable
  rows={[
    { code: "RAMP_WIDGET_URL_FAILED", status: "500", message: "Failed to generate buy widget URL" },
    { code: "OFFRAMP_WIDGET_URL_FAILED", status: "500", message: "Failed to generate sell widget URL" },
  ]}
/>

## Embedding the Widget

```html
<iframe
  src="{widgetUrl}"
  height="660px"
  width="482px"
  title="Buy Crypto"
  allow="accelerometer; autoplay; camera; gyroscope; payment"
  sandbox="allow-scripts allow-same-origin allow-popups allow-forms allow-top-navigation"
  style="border: none; border-radius: 12px;"
/>
```

<CodeRail>

## Examples

<Tabs groupId="language">
  <TabItem value="curl" label="cURL" default>

```bash
# Buy widget
curl -X POST https://api.zenpayz.com/payment/api/v1/on-ramp/widget-url \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "buy",
    "defaultFiat": "usd",
    "defaultCrypto": "BTC",
    "wallets": "btc:bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
    "successRedirectUrl": "https://yourapp.com/success"
  }'

# Sell widget
curl -X POST https://api.zenpayz.com/payment/api/v1/off-ramp/widget-url \
  -H "Content-Type: application/json" \
  -d '{
    "defaultFiat": "usd",
    "defaultCrypto": "BTC"
  }'
```

  </TabItem>
  <TabItem value="javascript" label="JavaScript">

```javascript
// Generate buy widget URL
const response = await fetch('https://api.zenpayz.com/payment/api/v1/on-ramp/widget-url', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    mode: 'buy',
    defaultFiat: 'usd',
    defaultCrypto: 'BTC',
    wallets: 'btc:bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh',
    successRedirectUrl: 'https://yourapp.com/success',
  }),
});

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

// Embed in iframe
const iframe = document.createElement('iframe');
iframe.src = data.widgetUrl;
iframe.style.cssText = 'border:none; border-radius:12px; width:482px; height:660px;';
iframe.allow = 'accelerometer; autoplay; camera; gyroscope; payment';
document.getElementById('widget-container').appendChild(iframe);
```

  </TabItem>
  <TabItem value="python" label="Python">

```python
import requests

# Generate buy widget URL
response = requests.post(
    "https://api.zenpayz.com/payment/api/v1/on-ramp/widget-url",
    json={
        "mode": "buy",
        "defaultFiat": "usd",
        "defaultCrypto": "BTC",
        "wallets": "btc:bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
        "successRedirectUrl": "https://yourapp.com/success",
    },
)

data = response.json()["data"]
print(f"Widget URL: {data['widgetUrl']}")
print(f"Embed mode: {data['embedMode']}")
```

  </TabItem>
</Tabs>

</CodeRail>

## Integration Flow (Widget Mode)

```
1. POST /on-ramp/widget-url     → Get signed widget URL
2. Embed widgetUrl in iframe     → User completes purchase inside widget
3. User redirected to success/failure URL when done
```

## Next Steps

- [Config](/docs/rest-api/endpoints/ramp/config) -- Check integration mode (widget vs API)
- [Wallet Addresses](/docs/rest-api/endpoints/ramp/wallet-addresses) -- Understand wallet resolution
- [Buy Checkout](/docs/rest-api/endpoints/ramp/buy-checkout) -- API mode alternative
