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

# Quickstart

> Create and send your first payout through the Yala API.

## Prerequisites

* An active Yala sandbox account. Request access from your Yala relationship manager or by emailing [developers@useyala.com](mailto:developers@useyala.com).
* A sandbox API key (`x-api-key`) with `CAN_INITIATE_PAYMENT` permission.
* A registered business with funded wallets in the currencies you plan to send.
* Currency pairs enabled in your dashboard.

<Note>
  Newly generated API keys can take up to 20-30 minutes to fully propagate. During this window, requests may return `403 Forbidden`.
</Note>

<Tip>
  **New to Yala?** Read the [End-to-End Integration Flow](/guides/end-to-end-flow) guide first to understand how to integrate payout APIs into your application for your end users.
</Tip>

## 1. Configure environments

<AccordionGroup>
  <Accordion icon="server" title="Choose the right base URL">
    | Environment | Base URL                                                    |
    | ----------- | ----------------------------------------------------------- |
    | Production  | `https://gateway.useyala.com/v1/payout-api/payouts`         |
    | Sandbox     | `https://gateway.staging.useyala.com/v1/payout-api/payouts` |

    **Sandbox tip:** Use `gateway.staging.useyala.com` when testing against the sandbox app.
  </Accordion>

  <Accordion icon="key" title="Store your API key securely">
    Save the `x-api-key` in your secret manager and inject it at runtime. Avoid hardcoding keys in source control.
  </Accordion>
</AccordionGroup>

## 2. Check wallet balances

Before requesting quotes or initiating payouts, check your available balances by currency:

```bash theme={null}
curl https://gateway.staging.useyala.com/v1/payout-api/payouts/wallets \
  -H "x-api-key: <SANDBOX_API_KEY>"
```

For full request/response fields and examples, see [Get Wallet Balances](/api-reference/endpoint/get-wallets).

## 3. Enable currency pairs

Before creating payouts, enable currency pairs in your Yala dashboard. Only enabled pairs are available via API.

```bash theme={null}
# Check enabled pairs
curl https://gateway.staging.useyala.com/v1/payout-api/payouts/pairs \
  -H "x-api-key: <SANDBOX_API_KEY>"
```

## 4. Get payment methods and rates

Call the methods endpoint to get available payment methods, current rates, and required beneficiary fields for your corridor.

```bash theme={null}
curl "https://gateway.staging.useyala.com/v1/payout-api/payouts/methods?sourceCurrency=NGN&destinationCurrency=CNY&destinationCountryCode=CHN" \
  -H "x-api-key: <SANDBOX_API_KEY>"
```

**Response includes:**

* Current exchange rate
* Available payment methods (e.g., ALIPAY, WECHAT, SWIFT)
* Required and optional beneficiary fields for each method
* Fees and settlement times

<Tip>
  Use the `requiredFields` array to dynamically render your payout form based on the selected payment method.
</Tip>

## 5. Upload a supporting document

For most payouts, attach an invoice before the payment can be processed. **Withdrawals**—transfers to your business's own account or to a UBO's account—do not require an invoice.

You can attach documents **when initiating** the payout or **after** via PATCH, as long as the payout has not finished processing.

**How upload works:** You call Yala once for a presigned URL, **PUT the file directly to S3** (not to Yala), then pass the returned `documentUrl` when initiating or patching the payout.

```javascript theme={null}
// 1. Get presigned URL from Yala (JSON only — no file bytes)
const uploadMeta = await fetch(
  'https://gateway.staging.useyala.com/v1/payout-api/payouts/documents/upload-url',
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': apiKey,
    },
    body: JSON.stringify({
      filename: 'invoice.pdf',
      contentType: 'application/pdf',
    }),
  }
);
const { uploadUrl, documentUrl, headers } = await uploadMeta.json();

// 2. PUT file bytes to S3 (Amazon — not Yala)
const fileBuffer = await fs.readFile('invoice.pdf');
await fetch(uploadUrl, {
  method: 'PUT',
  headers,
  body: fileBuffer,
});

// 3. Use documentUrl on POST /initiate (step 6) or PATCH /:id/documents later
```

See [Uploading Supporting Documents](/guides/uploading-supporting-documents) for both flows (before or after initiate).

## 6. Initiate the payout

**Important:** You must generate an `Idempotency-Key` **client-side** before making the request. This prevents duplicate payouts if the request is retried.

```javascript theme={null}
// Generate idempotency key (client-side)
const idempotencyKey = crypto.randomUUID();
// OR use your order ID: `order-${orderId}`
```

```bash theme={null}
curl https://gateway.staging.useyala.com/v1/payout-api/payouts/initiate \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
  -H "x-api-key: <SANDBOX_API_KEY>" \
  -d '{
    "sourceAmount": 10000,
    "sourceCurrency": "NGN",
    "destinationCurrency": "CNY",
    "destinationCountryCode": "CHN",
    "method": "ALIPAY",
    "beneficiary": {
      "accountName": "Li Wei",
      "accountCurrency": "CNY",
      "alipayId": "user@alipay.com",
      "address": "123 Main St",
      "city": "Beijing",
      "postCode": "100000"
    },
    "narration": "Payment for services",
    "supportingDocument": "<documentUrl from upload-url step, or omit and attach later>"
  }'
```

**Response includes:**

* `id` - **Save this payout ID** for tracking status
* `status` - Initial status (`PENDING`)
* Conversion details (exchange rate, amounts)
* `payoutRef` - Human-readable reference

**What happens:**

1. **Debit is always from the source currency wallet**—your NGN wallet is debited by the total (source amount + fees).
2. System handles FX conversion automatically
3. Payout created with status `PENDING`

<Tip>
  **Idempotency-Key is required.** If the request fails (network error, timeout), retry with the **same key + same body**. The API will return the original payout (no duplicate created).
</Tip>

## 7. Track payout status

Query payout status using the payout ID from the initiate response:

```bash theme={null}
curl https://gateway.staging.useyala.com/v1/payout-api/payouts/{payoutId} \
  -H "x-api-key: <SANDBOX_API_KEY>"
```

**Status values (same in API responses and webhooks):**

* `PENDING` - Payout created or awaiting approval; additional info submitted and under review; not yet sent for processing
* `ADDITIONAL_INFO_REQUIRED` - Additional information has been requested for this payout
* `PROCESSING` - Payout is being processed (ops, bank, or treasury)
* `SUCCESSFUL` - Completed; funds have been sent
* `FAILED` - Processing failed (e.g. bank failure)
* `REJECTED` - Rejected (e.g. compliance, initiation checks, or bank)

<Tip>
  **Subscribe to webhooks** for real-time status updates:

  1. Activate webhook notifications in your Yala dashboard
  2. Configure your webhook endpoint URL
  3. Receive `payout.status.changed.v1` events when status changes

  The webhook payload includes the payout `id` so you can match it with your records.
</Tip>

## Complete Example

```javascript theme={null}
// 1. Generate idempotency key
const idempotencyKey = crypto.randomUUID();

// 2. Get methods and rates
const methodsResponse = await fetch(
  'https://gateway.staging.useyala.com/v1/payout-api/payouts/methods?sourceCurrency=NGN&destinationCurrency=CNY&destinationCountryCode=CHN',
  {
    headers: { 'x-api-key': apiKey }
  }
);
const { methods, rate } = await methodsResponse.json();
console.log(`Rate: ${rate.rate}, Methods: ${methods.map(m => m.code).join(', ')}`);

// 3. Create payout
const payoutResponse = await fetch(
  'https://gateway.staging.useyala.com/v1/payout-api/payouts/initiate',
  {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Idempotency-Key': idempotencyKey,  // Client-generated
      'x-api-key': apiKey,
    },
    body: JSON.stringify({
      sourceAmount: 10000,
      sourceCurrency: 'NGN',
      destinationCurrency: 'CNY',
      destinationCountryCode: 'CHN',
      method: 'ALIPAY',
      beneficiary: {
        accountName: 'Li Wei',
        accountCurrency: 'CNY',
        alipayId: 'user@alipay.com',
        address: '123 Main St',
        city: 'Beijing',
        postCode: '100000',
      },
      narration: 'Payment for services',
      supportingDocument: 'https://example.com/invoice.pdf',
    }),
  }
);

const payout = await payoutResponse.json();
console.log(`Payout created: ID=${payout.id}, Status=${payout.status}`);

// 4. Save payout.id for tracking
const payoutId = payout.id; // Use this ID to track status

// 5. Check status (or subscribe to webhooks for real-time updates)
const statusResponse = await fetch(
  `https://gateway.staging.useyala.com/v1/payout-api/payouts/${payoutId}`,
  {
    headers: { 'x-api-key': apiKey }
  }
);
const status = await statusResponse.json();
console.log(`Current status: ${status.status}`);
```

## Testing with Postman

<Note>
  **Quick start:** Import the ready-to-use Postman collection with all payout API endpoints pre-configured at [https://docs.useyala.com/resources/postman.json](https://docs.useyala.com/resources/postman.json).
</Note>

The Postman collection includes:

* All payout API endpoints (pairs, methods, **wallets**, quote, **document upload-url**, S3 PUT, initiate, get status, add documents)
* A **Supporting documents** folder for upload-url, S3 PUT, and PATCH documents
* Pre-configured headers (`x-api-key`, `Idempotency-Key`)
* Scripts that save `documentUrl` and `payoutId` to collection variables
* Example request bodies (initiate sample includes SWIFT-required beneficiary fields for the NGN to USD USA corridor)

**Setup:**

1. In Postman, select **Import** and use `https://docs.useyala.com/resources/postman.json`
2. Create environment with:
   * `YALA_BASE_URL_LOCAL`: `https://gateway.staging.useyala.com/v1/payout-api/payouts` (sandbox)
   * `YALA_PAYOUT_API_KEY`: Your API key
3. Select the environment and start testing

## Next steps

<CardGroup cols={2}>
  <Card title="End-to-End Flow" icon="diagram-project" href="/guides/end-to-end-flow">
    Understand how to integrate payout APIs into your application.
  </Card>

  <Card title="Idempotency guide" icon="key" href="/api-reference/endpoint/initiate#idempotency">
    Learn how to generate and use Idempotency-Key headers.
  </Card>

  <Card title="Get methods endpoint" icon="list" href="/api-reference/endpoint/get-methods">
    Understand how to get rates and required fields.
  </Card>

  <Card title="Error handling" icon="triangle-exclamation" href="/guides/errors">
    Handle validation failures and rate limiting gracefully.
  </Card>

  <Card title="Payout initiation" icon="paper-plane" href="/api-reference/endpoint/initiate">
    Review complete endpoint documentation.
  </Card>
</CardGroup>
