<!-- ZenPays documentation · https://docs.zenpayz.com/docs/rest-api/endpoints/payout-intents/create-payout-intent -->

# Create Payout Intent

Create a payout intent. Returns the fields you need to collect before confirming the payout.

<Diagram
  slug="payout-flow"
  alt="A payout intent returns the beneficiary fields that corridor requires. You confirm within 30 minutes, supplying those fields, and funds are held. The payout is sent to the provider, and on the provider callback the held funds are debited and the intent succeeds."
  caption="How a payout is confirmed, sent and debited"
/>

<EndpointHeader verb="POST" path="/payment/api/v1/payout-intents" />

## Request

### Headers

<ParamTable
  label="Header"
  rows={[
    { name: "Authorization", required: true, desc: "`Bearer {api_key}`" },
    { name: "X-Signature", required: true, desc: "HMAC-SHA256 signature" },
    { name: "X-Timestamp", required: true, desc: "ISO 8601 timestamp" },
    { name: "X-Secret-Salt", required: true, desc: "Secret salt for HMAC validation" },
    { name: "Content-Type", required: true, desc: "`application/json`" },
    { name: "X-Idempotency-Key", desc: "Unique key to prevent duplicates" },
  ]}
/>

### Body Parameters

<ParamTable
  rows={[
    { name: "amount", type: "number", required: true, desc: "Payout amount (must be > 0)" },
    { name: "currency", type: "string", required: true, desc: "Currency code (e.g. `USD`, `INR`, `USDT`)" },
    { name: "country", type: "string", desc: "ISO 3166-1 alpha-2 country code" },
    { name: "beneficiaryName", type: "string", required: true, desc: "Beneficiary full name" },
    { name: "beneficiaryEmail", type: "string", desc: "Beneficiary email" },
    { name: "beneficiaryPhone", type: "string", desc: "Beneficiary phone" },
    { name: "payoutType", type: "string", desc: "`bank_transfer`, `upi`, `imps`, `neft`, `rtgs`" },
    { name: "purpose", type: "string", desc: "Purpose (e.g. `PAYOUT`, `SALARY`, `REFUND`)" },
    { name: "description", type: "string", desc: "Description" },
    { name: "customerId", type: "string", desc: "Your customer ID" },
    { name: "webhookUrl", type: "string", desc: "URL for payout status webhooks" },
    { name: "metadata", type: "object", desc: "Custom key-value pairs (e.g. `{ \"order_no\": \"ORD-001\" }`). Echoed back in all webhook callbacks for this payout." },
  ]}
/>

## Response

### Success (200 OK)

```json
{
  "success": true,
  "data": {
    "intentId": "poi_xxxxx",
    "status": "requires_confirmation",
    "amount": 10000,
    "currency": "INR",
    "beneficiaryName": "John Doe",
    "requiredFields": [
      {
        "fieldName": "beneficiaryAccount",
        "label": "Account Number",
        "type": "text",
        "required": true,
        "placeholder": "Bank account number"
      },
      {
        "fieldName": "beneficiaryIfsc",
        "label": "IFSC Code",
        "type": "text",
        "required": true,
        "placeholder": "e.g. HDFC0001234"
      }
    ],
    "optionalFields": [
      {
        "fieldName": "beneficiaryEmail",
        "label": "Email",
        "type": "text",
        "required": false
      }
    ],
    "expiresAt": "2024-01-15T11:00:00.000Z",
    "createdAt": "2024-01-15T10:30:00.000Z"
  }
}
```

For crypto payouts (e.g. `currency: "USDT"`), the required fields will be:

```json
{
  "requiredFields": [
    {
      "fieldName": "chain",
      "label": "Network / Chain",
      "type": "select",
      "required": true,
      "options": ["ethereum", "tron", "bitcoin", "solana", "polygon"]
    },
    {
      "fieldName": "walletAddress",
      "label": "Wallet Address",
      "type": "text",
      "required": true
    }
  ]
}
```

### Error Responses

<ErrorTable
  rows={[
    { code: "PAYOUT_INTENT_CREATE_FAILED", status: "400", message: "Invalid request or insufficient wallet balance" },
    { code: "UNAUTHORIZED", status: "401", message: "Invalid API key" },
  ]}
/>

<CodeRail>

## Examples

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

```bash
curl -X POST https://api.zenpayz.com/payment/api/v1/payout-intents \
  -H "Authorization: Bearer zp_test_xxxxx" \
  -H "X-Timestamp: 2024-01-15T10:30:00.000Z" \
  -H "X-Signature: a1b2c3d4e5f6..." \
  -H "X-Secret-Salt: your_secret_salt" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 10000,
    "currency": "INR",
    "country": "IN",
    "beneficiaryName": "John Doe",
    "beneficiaryEmail": "john@example.com",
    "purpose": "PAYOUT"
  }'
```

  </TabItem>
  <TabItem value="sdk" label="SDK">

```javascript
const intent = await zenpays.payouts.createPayoutIntent({
  amount: 10000,
  currency: 'INR',
  country: 'IN',
  beneficiaryName: 'John Doe',
  beneficiaryEmail: 'john@example.com',
  purpose: 'PAYOUT',
})

// Now collect the required fields from intent.requiredFields
console.log(intent.requiredFields)
```

  </TabItem>
</Tabs>

</CodeRail>

## How It Works

1. You send basic payout details (amount, currency, beneficiary name)
2. ZenPays returns the **exact fields** you need to collect
3. You collect those fields from your user or your system
4. You [confirm the intent](/docs/rest-api/endpoints/payout-intents/confirm-payout-intent) with those fields
5. The payout is executed

The intent expires after **30 minutes**. If not confirmed, create a new one.

## Related Endpoints

- [Confirm Payout Intent](/docs/rest-api/endpoints/payout-intents/confirm-payout-intent)
- [Get Payout Intent](/docs/rest-api/endpoints/payout-intents/get-payout-intent)
- [List Payout Intents](/docs/rest-api/endpoints/payout-intents/list-payout-intents)
