> ## Documentation Index
> Fetch the complete documentation index at: https://developer.quickei.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Execute Payout

> Send a payout to a Quickei user wallet

Execute a payout to credit a Quickei user's wallet. Your merchant wallet is debited and the recipient's wallet is credited instantly.

## Parameters

You can execute a payout in two ways: using a `quote_id` from a previous quote, or by providing the lookup and amount parameters directly.

<ParamField body="quote_id" type="string">
  The quote ID from the [Quote](/partner-api/04-quote) endpoint. If provided, the payout uses the locked exchange rate and fees from the quote. When using `quote_id`, you do not need to provide `lookup_token`, `amount`, `sender_currency`, or `receiver_currency`.
</ParamField>

<ParamField body="lookup_token" type="string">
  The token from the [Lookup](/partner-api/03-lookup) endpoint identifying the recipient. Required if `quote_id` is not provided.
</ParamField>

<ParamField body="amount" type="number">
  Amount to send from your merchant wallet. Must be greater than 0. Required if `quote_id` is not provided.
</ParamField>

<ParamField body="sender_currency" type="string">
  ISO 4217 currency code of your merchant wallet (e.g. `EUR`). Max 10 characters. Required if `quote_id` is not provided.
</ParamField>

<ParamField body="receiver_currency" type="string">
  ISO 4217 currency code of the recipient's wallet (e.g. `XAF`). Max 10 characters. Required if `quote_id` is not provided.
</ParamField>

<ParamField body="reference" type="string" required>
  Your internal reference for this payout (max 255 characters). Must be unique per merchant account.
</ParamField>

<ParamField body="idempotency_key" type="string" required>
  A unique key (max 64 characters) to prevent duplicate payouts. If a payout with the same key already exists, the original payout is returned.
</ParamField>

<ParamField body="description" type="string">
  Optional description visible in the transaction history (max 500 characters).
</ParamField>

## With Quote ID (Recommended)

Using a `quote_id` locks in the exchange rate and fees from the quote.

```bash theme={null}
curl -X POST https://quickei.io/api/partner/sandbox/v1/payout \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "quote_id": "f7e6d5c4-b3a2-1098-7654-321fedcba098",
    "reference": "PAYROLL-2026-03-001",
    "idempotency_key": "payout_inv_2026_0042",
    "description": "March 2026 salary"
  }'
```

## Without Quote ID (Direct)

If you skip the quote step, Quickei calculates the rate and fees at execution time.

```bash theme={null}
curl -X POST https://quickei.io/api/partner/sandbox/v1/payout \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "lookup_token": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "amount": 100.00,
    "sender_currency": "EUR",
    "receiver_currency": "XAF",
    "reference": "REM-78901",
    "idempotency_key": "payout_inv_2026_0043",
    "description": "Transfer from ExampleRemit"
  }'
```

## Success Response `200`

```json theme={null}
{
  "message": {
    "success": ["Payout completed successfully."]
  },
  "data": {
    "payout": {
      "payout_id": "POAB1C2D3E",
      "reference": "PAYROLL-2026-03-001",
      "amount": 100.00,
      "currency": "EUR",
      "fee": 2.50,
      "total_deducted": 102.50,
      "exchange_rate": 655.957,
      "receiver_amount": 65595.70,
      "receiver_currency": "XAF",
      "status": "completed",
      "description": "March 2026 salary",
      "trx_id": "PP8274619350",
      "created_at": "2026-03-29T14:01:15+00:00",
      "processed_at": "2026-03-29T14:01:15+00:00"
    }
  }
}
```

<ResponseField name="payout.payout_id" type="string">
  Unique payout identifier (format: `PO` + 8 random alphanumeric characters). Use this to check status via [`GET /payout/{id}`](/partner-api/06-status).
</ResponseField>

<ResponseField name="payout.reference" type="string">
  Your internal reference as provided in the request.
</ResponseField>

<ResponseField name="payout.amount" type="number">
  The amount sent (before fees).
</ResponseField>

<ResponseField name="payout.currency" type="string">
  The sender currency code.
</ResponseField>

<ResponseField name="payout.fee" type="number">
  Total fee charged (fixed + percentage).
</ResponseField>

<ResponseField name="payout.total_deducted" type="number">
  Total debited from your merchant wallet (`amount + fee`).
</ResponseField>

<ResponseField name="payout.exchange_rate" type="number">
  Applied exchange rate from sender to receiver currency.
</ResponseField>

<ResponseField name="payout.receiver_amount" type="number">
  Amount credited to the recipient's wallet.
</ResponseField>

<ResponseField name="payout.receiver_currency" type="string">
  The recipient's currency code.
</ResponseField>

<ResponseField name="payout.status" type="string">
  Payout status: `completed`, `pending`, or `failed`.
</ResponseField>

<ResponseField name="payout.trx_id" type="string">
  Quickei internal transaction ID.
</ResponseField>

<ResponseField name="payout.created_at" type="string">
  ISO 8601 timestamp when the payout was created.
</ResponseField>

<ResponseField name="payout.processed_at" type="string">
  ISO 8601 timestamp when the payout was processed. `null` if still pending.
</ResponseField>

## Idempotency

The `idempotency_key` prevents duplicate payouts. If you send the same key twice:

* The original payout is returned with `"duplicate": true`
* No additional funds are moved
* The response status is `200`

```json theme={null}
{
  "message": {
    "success": ["Payout already processed."]
  },
  "data": {
    "duplicate": true,
    "payout": {
      "payout_id": "POAB1C2D3E",
      "reference": "PAYROLL-2026-03-001",
      "amount": 100.00,
      "currency": "EUR",
      "fee": 2.50,
      "total_deducted": 102.50,
      "exchange_rate": 655.957,
      "receiver_amount": 65595.70,
      "receiver_currency": "XAF",
      "status": "completed",
      "description": "March 2026 salary",
      "trx_id": "PP8274619350",
      "created_at": "2026-03-29T14:01:15+00:00",
      "processed_at": "2026-03-29T14:01:15+00:00"
    }
  }
}
```

<Warning>
  Always include an `idempotency_key`. Without it, the request will be rejected (it is required). The `reference` must also be unique per merchant account -- a duplicate reference will be rejected even with a new idempotency key.
</Warning>

## Error Responses

| Status | Message                                      | Cause                                                                                |
| ------ | -------------------------------------------- | ------------------------------------------------------------------------------------ |
| `400`  | Invalid or expired quote.                    | The `quote_id` has expired (older than 5 minutes) or does not belong to your account |
| `400`  | Invalid or expired lookup token.             | The `lookup_token` has expired (older than 10 minutes)                               |
| `400`  | Insufficient balance.                        | Merchant wallet balance is less than `total_deducted`                                |
| `400`  | Currency EUR is not authorized for payouts.  | Currency not enabled for payouts on your account                                     |
| `400`  | Amount exceeds per-transaction limit         | Amount exceeds the per-transaction limit for this currency                           |
| `400`  | Daily payout limit exceeded                  | Daily payout volume limit reached for this currency                                  |
| `400`  | Monthly payout limit exceeded                | Monthly payout volume limit reached for this currency                                |
| `400`  | Duplicate reference.                         | A different payout already uses this `reference`                                     |
| `400`  | Recipient not found or inactive.             | The user account is deactivated                                                      |
| `400`  | Recipient wallet not found for currency: XAF | Recipient has no wallet in the specified receiver currency                           |
| `422`  | Validation error                             | Missing required fields                                                              |
| `401`  | Invalid API credentials.                     | Bad or missing Bearer token                                                          |

<Accordion title="What happens if a payout fails mid-execution?">
  Payouts are atomic. If any step fails (debit, credit, or ledger entry), the entire transaction is rolled back. Your merchant wallet is not debited and the recipient receives nothing. You can safely retry with the same `idempotency_key`.
</Accordion>
