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

# Create Sell Deposit (Phase 1)

Phase 1 of the two-phase off-ramp (sell) flow. Generates a crypto deposit address where the customer sends their crypto. The system monitors the address for incoming deposits and confirms receipt automatically.

This endpoint is **idempotent** — calling it again with the same `intentId` returns the existing deposit instead of creating a new one.

<EndpointHeader verb="POST" path="/payment/api/v1/off-ramp/sell/checkout" />

## 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. It is designed to be called from your checkout or widget page.
:::

### Body Parameters

<ParamTable
  rows={[
    { name: "intentId", type: "string", required: true, desc: "Ramp intent ID (from [Create Ramp Intent](/docs/rest-api/endpoints/ramp/create-ramp-intent))" },
    { name: "cryptoCurrency", type: "string", required: true, desc: "Crypto to deposit (e.g. `USDT`)" },
    { name: "chain", type: "string", required: true, desc: "Blockchain network (e.g. `tron`, `ethereum`)" },
    { name: "fiatCurrency", type: "string", required: true, desc: "Target fiat currency (e.g. `USD`)" },
    { name: "cryptoAmount", type: "number", required: true, desc: "Amount of crypto to send" },
    { name: "fiatAmount", type: "number", required: true, desc: "Expected fiat payout (from quote)" },
    { name: "rate", type: "number", required: true, desc: "Locked exchange rate (from quote)" },
    { name: "totalFee", type: "number", required: true, desc: "Total fees (from quote)" },
    { name: "quoteId", type: "string", desc: "Reference to the quote used" },
    { name: "onramp", type: "string", desc: "Quote provider identifier" },
  ]}
/>

:::tip Use Quote Values
Pass the `rate`, `fiatAmount`, and `totalFee` directly from a [Sell Quote](/docs/rest-api/endpoints/ramp/sell-quotes) response to ensure consistent pricing.
:::

## Response

### Success (200 OK)

```json
{
  "success": true,
  "data": {
    "intentId": "ri_1710345678000_a1b2c3d4e5f6g7h8",
    "depositAddress": "TLfMkVBKQSy7gzP7x9URJp6ZLXyWGZbwDs",
    "memo": null,
    "currency": "USDT",
    "chain": "tron",
    "expectedCryptoAmount": 20,
    "fiatAmount": 19.78,
    "fiatCurrency": "USD",
    "rate": 0.999,
    "cryptoDepositId": "d4e5f6a7-b8c9-1234-5678-abcdef012345",
    "expiresAt": "2026-03-15T10:00:00.000Z",
  },
  "message": "Sell checkout created"
}
```

### Response Fields

<ParamTable
  rows={[
    { name: "intentId", type: "string", desc: "The ramp intent ID" },
    { name: "depositAddress", type: "string", desc: "Crypto address to send funds to" },
    { name: "memo", type: "string | null", desc: "Memo/tag (required for XRP, XLM, etc.)" },
    { name: "currency", type: "string", desc: "Crypto currency (e.g. `USDT`)" },
    { name: "chain", type: "string", desc: "Blockchain network" },
    { name: "expectedCryptoAmount", type: "number", desc: "Amount the customer should send" },
    { name: "fiatAmount", type: "number", desc: "Expected fiat payout" },
    { name: "fiatCurrency", type: "string", desc: "Fiat currency code" },
    { name: "rate", type: "number", desc: "Locked exchange rate" },
    { name: "cryptoDepositId", type: "string", desc: "Deposit tracking ID (needed for Phase 2)" },
    { name: "expiresAt", type: "string", desc: "Deposit expiry timestamp" },
  ]}
/>

:::warning Save the cryptoDepositId
You will need `cryptoDepositId` when submitting the payout in Phase 2. Store it alongside the `intentId`.
:::

### Error Responses

<ErrorTable
  rows={[
    { code: "BAD_REQUEST", status: "400", message: "Invalid or inactive intent" },
    { code: "SELL_CHECKOUT_FAILED", status: "500", message: "Failed to generate deposit address" },
  ]}
/>

<CodeRail>

## Examples

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

```bash
curl -X POST https://api.zenpayz.com/payment/api/v1/off-ramp/sell/checkout \
  -H "Content-Type: application/json" \
  -d '{
    "intentId": "ri_1710345678000_a1b2c3d4e5f6g7h8",
    "cryptoCurrency": "USDT",
    "chain": "tron",
    "fiatCurrency": "USD",
    "cryptoAmount": 20,
    "fiatAmount": 19.78,
    "rate": 0.999,
    "totalFee": 0.62
  }'
```

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

```javascript
const response = await fetch(
  'https://api.zenpayz.com/payment/api/v1/off-ramp/sell/checkout',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      intentId: 'ri_1710345678000_a1b2c3d4e5f6g7h8',
      cryptoCurrency: 'USDT',
      chain: 'tron',
      fiatCurrency: 'USD',
      cryptoAmount: 20,
      fiatAmount: 19.78,
      rate: 0.999,
      totalFee: 0.62,
    }),
  }
);

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

console.log(`Send ${data.expectedCryptoAmount} ${data.currency} to:`);
console.log(`Address: ${data.depositAddress}`);
if (data.memo) console.log(`Memo: ${data.memo}`);
console.log(`Chain: ${data.chain}`);
console.log(`Deposit ID: ${data.cryptoDepositId}`);

// Display to customer with QR code, countdown timer, etc.
```

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

```python
import requests

response = requests.post(
    "https://api.zenpayz.com/payment/api/v1/off-ramp/sell/checkout",
    json={
        "intentId": "ri_1710345678000_a1b2c3d4e5f6g7h8",
        "cryptoCurrency": "USDT",
        "chain": "tron",
        "fiatCurrency": "USD",
        "cryptoAmount": 20,
        "fiatAmount": 19.78,
        "rate": 0.999,
        "totalFee": 0.62,
    },
)

data = response.json()["data"]
print(f"Send {data['expectedCryptoAmount']} {data['currency']} to:")
print(f"Address: {data['depositAddress']}")
print(f"Chain: {data['chain']}")
print(f"Deposit ID: {data['cryptoDepositId']}")
```

  </TabItem>
</Tabs>

</CodeRail>

## Two-Phase Sell Flow

```
Phase 1 (this endpoint)          Phase 2
┌──────────────────────┐         ┌──────────────────────┐
│ POST sell/checkout   │         │ GET  payout-preview   │
│ → deposit address    │         │ → required fields     │
│                      │         │                       │
│ Customer sends crypto│   ──►   │ POST sell/payout      │
│ System confirms      │         │ → fiat transfer       │
└──────────────────────┘         └──────────────────────┘
```

## Next Steps

- [Get Payout Preview](/docs/rest-api/endpoints/ramp/payout-preview) — Discover required beneficiary fields (Phase 2a)
- [Submit Sell Payout](/docs/rest-api/endpoints/ramp/sell-payout) — Execute the fiat payout (Phase 2b)
- [Off-Ramp Flow](/docs/examples/off-ramp-flow) — Complete sell integration guide
