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

# Quickstart

> Start building with Zuba in under 5 minutes

## Setup your environment

Learn how to update your docs locally and deploy them to the public.

### Prerequisites

Before you begin, ensure you have:

* A Zuba account with API access
* Your API credentials (API key and secret)
* Basic knowledge of REST APIs

### Get your API credentials

1. Log in to your [Zuba Test Dashboard](https://sandbox.zuba.com)
2. Navigate to **API Settings**
3. Click **Generate API Credentials**
4. Save your Client ID, Client Secret, and Token URL securely

See the [Authentication Guide](/authentication) for detailed instructions on obtaining access tokens.

<Warning>
  Never expose your Client Secret in client-side code or public repositories. Always keep it secure on your server.
</Warning>

### Rate Limits

The API enforces rate limits to ensure fair usage and platform stability:

| Limit     | Requests | Window     |
| --------- | -------- | ---------- |
| Burst     | 10       | per second |
| Sustained | 100      | per minute |
| Hourly    | 1,000    | per hour   |

If you exceed these limits, you'll receive a `429 Too Many Requests` response. Implement exponential backoff in your integration to handle rate limiting gracefully.

## Create your first beneficiary

Before sending payouts, you need to create a beneficiary with their banking details:

<CodeGroup>
  ```bash curl theme={"dark"}
  curl -X POST "https://api.sandbox.zuba.com/v1/beneficiaries" \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "John Doe",
      "email": "john.doe@example.com",
      "country": "US",
      "countrySubdivision": "NY",
      "address": "123 Main St",
      "city": "New York",
      "postcode": "10001",
      "accounts": [{
        "type": "bank_account",
        "currency": "USD",
        "data": {
          "accountNumber": "1234567890",
          "routingNumber": "021000021",
          "accountHolderName": "John Doe",
          "bankName": "Chase Bank"
        }
      }]
    }'
  ```

  ```javascript JavaScript theme={"dark"}
  const beneficiary = await fetch('https://api.sandbox.zuba.com/v1/beneficiaries', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      name: 'John Doe',
      email: 'john.doe@example.com',
      country: 'US',
      countrySubdivision: 'NY',
      address: '123 Main St',
      city: 'New York',
      postcode: '10001',
      accounts: [{
        type: 'bank_account',
        currency: 'USD',
        data: {
          accountNumber: '1234567890',
          routingNumber: '021000021',
          accountHolderName: 'John Doe',
          bankName: 'Chase Bank'
        }
      }]
    })
  });

  const beneficiaryData = await beneficiary.json();
  console.log(beneficiaryData);
  ```

  ```python Python theme={"dark"}
  import requests

  beneficiary = requests.post(
      'https://api.sandbox.zuba.com/v1/beneficiaries',
      headers={
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
          'Content-Type': 'application/json'
      },
      json={
          'name': 'John Doe',
          'email': 'john.doe@example.com',
          'country': 'US',
          'countrySubdivision': 'NY',
          'address': '123 Main St',
          'city': 'New York',
          'postcode': '10001',
          'accounts': [{
              'type': 'bank_account',
              'currency': 'USD',
              'data': {
                  'accountNumber': '1234567890',
                  'routingNumber': '021000021',
                  'accountHolderName': 'John Doe',
                  'bankName': 'Chase Bank'
              }
          }]
      }
  )

  beneficiary_data = beneficiary.json()
  print(beneficiary_data)
  ```

  ```java Java theme={"dark"}
  import java.net.http.*;
  import java.net.URI;
  import com.google.gson.Gson;
  import com.google.gson.JsonObject;
  import com.google.gson.JsonArray;

  HttpClient client = HttpClient.newHttpClient();

  JsonObject accountData = new JsonObject();
  accountData.addProperty("accountNumber", "1234567890");
  accountData.addProperty("routingNumber", "021000021");
  accountData.addProperty("accountHolderName", "John Doe");
  accountData.addProperty("bankName", "Chase Bank");

  JsonObject account = new JsonObject();
  account.addProperty("type", "bank_account");
  account.addProperty("currency", "USD");
  account.add("data", accountData);

  JsonArray accounts = new JsonArray();
  accounts.add(account);

  JsonObject requestBody = new JsonObject();
  requestBody.addProperty("name", "John Doe");
  requestBody.addProperty("email", "john.doe@example.com");
  requestBody.addProperty("country", "US");
  requestBody.addProperty("countrySubdivision", "NY");
  requestBody.addProperty("address", "123 Main St");
  requestBody.addProperty("city", "New York");
  requestBody.addProperty("postcode", "10001");
  requestBody.add("accounts", accounts);

  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.sandbox.zuba.com/v1/beneficiaries"))
      .header("Authorization", "Bearer YOUR_ACCESS_TOKEN")
      .header("Content-Type", "application/json")
      .POST(HttpRequest.BodyPublishers.ofString(new Gson().toJson(requestBody)))
      .build();

  HttpResponse<String> response = client.send(request,
      HttpResponse.BodyHandlers.ofString());

  JsonObject beneficiaryData = new Gson().fromJson(response.body(), JsonObject.class);
  System.out.println(beneficiaryData);
  ```
</CodeGroup>

## Check your account balance

Before sending payouts, ensure your account has sufficient funds. You can check your balance across all currencies:

<CodeGroup>
  ```bash curl theme={"dark"}
  curl -X GET "https://api.sandbox.zuba.com/v1/ledger/balances" \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
  ```

  ```javascript JavaScript theme={"dark"}
  const balances = await fetch('https://api.sandbox.zuba.com/v1/ledger/balances', {
    headers: {
      'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
    }
  });

  const balanceData = await balances.json();
  console.log(balanceData);
  ```

  ```python Python theme={"dark"}
  import requests

  balances = requests.get(
      'https://api.sandbox.zuba.com/v1/ledger/balances',
      headers={
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
      }
  )

  balance_data = balances.json()
  print(balance_data)
  ```

  ```java Java theme={"dark"}
  HttpClient client = HttpClient.newHttpClient();
  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.sandbox.zuba.com/v1/ledger/balances"))
      .header("Authorization", "Bearer YOUR_ACCESS_TOKEN")
      .GET()
      .build();

  HttpResponse<String> response = client.send(request,
      HttpResponse.BodyHandlers.ofString());

  JsonObject balanceData = new Gson().fromJson(response.body(), JsonObject.class);
  System.out.println(balanceData);
  ```
</CodeGroup>

<Note>
  If your account has zero balance, payouts will fail. Contact your account manager or use the dashboard to fund your account before proceeding.
</Note>

## Send your first payout

Now you can send a payout to your beneficiary. **RECOMMENDED:** Reference the beneficiary by ID (from the previous step). Note that `amount` is passed as a string to avoid floating-point precision issues.

**Currency Fields:** `inputCurrency` is the currency from your account you'll be paying from, while `currency` is what the beneficiary will receive (automatic conversion if different):

**Sender Types:** `senderInfo.type` is `'individual'` (default when omitted) for natural-person senders, or `'business'` for legal entities. The examples below use an individual sender; for a business sender, see [Business sender example](#business-sender-example).

<CodeGroup>
  ```bash curl theme={"dark"}
  curl -X POST "https://api.sandbox.zuba.com/v1/payouts" \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "clientRef": "PAYOUT-INV-001",
      "amount": "1000.00",
      "inputCurrency": "EUR",
      "currency": "NGN",
      "route": "bank_transfer",
      "senderInfo": {
        "firstName": "Jack",
        "lastName": "Jones",
        "address": "456 London Road",
        "city": "London",
        "postalCode": "SW1A 1AA",
        "country": "GB",
        "dateOfBirth": "1985-06-15"
      },
      "beneficiary": {
        "id": "BENEFICIARY_ID_FROM_PREVIOUS_STEP"
      },
      "reference": "Invoice #INV-001",
      "description": "Payment for marketing services"
    }'
  ```

  ```javascript JavaScript theme={"dark"}
  const payout = await fetch('https://api.sandbox.zuba.com/v1/payouts', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      clientRef: 'PAYOUT-INV-001',
      amount: '1000.00',
      inputCurrency: 'EUR',
      currency: 'NGN',
      senderInfo: {
        firstName: 'Jack',
        lastName: 'Jones',
        address: '456 London Road',
        city: 'London',
        postalCode: 'SW1A 1AA',
        country: 'GB',
        dateOfBirth: '1985-06-15'
      },
      route: 'bank_transfer',
      beneficiary: {
        id: beneficiaryData.id
      },
      reference: 'Invoice #INV-001',
      description: 'Payment for marketing services'
    })
  });

  const payoutData = await payout.json();
  console.log(payoutData);
  ```

  ```python Python theme={"dark"}
  import requests

  payout = requests.post(
      'https://api.sandbox.zuba.com/v1/payouts',
      headers={
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
          'Content-Type': 'application/json'
      },
      json={
          'clientRef': 'PAYOUT-INV-001',
          'amount': '1000.00',
          'inputCurrency': 'EUR',
  				'senderInfo': {
  					'firstName': 'Jack',
  					'lastName': 'Jones',
  					'address': '456 London Road',
  					'city': 'London',
  					'postalCode': 'SW1A 1AA',
  					'country': 'GB',
  					'dateOfBirth': '1985-06-15'
  				},
          'currency': 'NGN',
          'route': 'bank_transfer',
          'beneficiary': {
              'id': beneficiary_data['id']
          },
          'reference': 'Invoice #INV-001',
          'description': 'Payment for marketing services'
      }
  )

  payout_data = payout.json()
  print(payout_data)
  ```

  ```java Java theme={"dark"}
  JsonObject beneficiaryRef = new JsonObject();
  beneficiaryRef.addProperty("id", beneficiaryData.get("id").getAsString());

  JsonObject senderInfo = new JsonObject();
  senderInfo.addProperty("firstName", "Jack");
  senderInfo.addProperty("lastName", "Jones");
  senderInfo.addProperty("address", "456 London Road");
  senderInfo.addProperty("city", "London");
  senderInfo.addProperty("postalCode", "SW1A 1AA");
  senderInfo.addProperty("country", "GB");
  senderInfo.addProperty("dateOfBirth", "1985-06-15");

  JsonObject payoutRequest = new JsonObject();
  payoutRequest.addProperty("clientRef", "PAYOUT-INV-001");
  payoutRequest.addProperty("amount", "1000.00");
  payoutRequest.addProperty("inputCurrency", "EUR");
  payoutRequest.addProperty("currency", "NGN");
  payoutRequest.addProperty("route", "bank_transfer");
  payoutRequest.add("senderInfo", senderInfo);
  payoutRequest.add("beneficiary", beneficiaryRef);
  payoutRequest.addProperty("reference", "Invoice #INV-001");
  payoutRequest.addProperty("description", "Payment for marketing services");

  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.sandbox.zuba.com/v1/payouts"))
      .header("Authorization", "Bearer YOUR_ACCESS_TOKEN")
      .header("Content-Type", "application/json")
      .POST(HttpRequest.BodyPublishers.ofString(new Gson().toJson(payoutRequest)))
      .build();

  HttpResponse<String> response = client.send(request,
      HttpResponse.BodyHandlers.ofString());

  JsonObject payoutData = new Gson().fromJson(response.body(), JsonObject.class);
  System.out.println(payoutData);
  ```
</CodeGroup>

### Business sender example

When the sender is a legal entity rather than a natural person, set `senderInfo.type` to `'business'` and provide `companyName`, `registrationNumber`, and `country`. The `registrationNumber` is the company's official registration identifier and is used as the AML pivot for sanctions and UBO screening. Business senders do not carry `firstName`, `lastName`, or `dateOfBirth`.

<CodeGroup>
  ```bash curl theme={"dark"}
  curl -X POST "https://api.sandbox.zuba.com/v1/payouts" \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "clientRef": "PAYOUT-INV-002",
      "amount": "1000.00",
      "inputCurrency": "EUR",
      "currency": "NGN",
      "route": "bank_transfer",
      "senderInfo": {
        "type": "business",
        "companyName": "Acme Trading Ltd",
        "registrationNumber": "12345678",
        "address": "1 Finsbury Square",
        "city": "London",
        "postalCode": "EC2A 1AE",
        "country": "GB"
      },
      "beneficiary": {
        "id": "BENEFICIARY_ID_FROM_PREVIOUS_STEP"
      },
      "reference": "Invoice #INV-002",
      "description": "Payment for marketing services"
    }'
  ```

  ```javascript JavaScript theme={"dark"}
  const payout = await fetch('https://api.sandbox.zuba.com/v1/payouts', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      clientRef: 'PAYOUT-INV-002',
      amount: '1000.00',
      inputCurrency: 'EUR',
      currency: 'NGN',
      route: 'bank_transfer',
      senderInfo: {
        type: 'business',
        companyName: 'Acme Trading Ltd',
        registrationNumber: '12345678',
        address: '1 Finsbury Square',
        city: 'London',
        postalCode: 'EC2A 1AE',
        country: 'GB'
      },
      beneficiary: {
        id: beneficiaryData.id
      },
      reference: 'Invoice #INV-002',
      description: 'Payment for marketing services'
    })
  });
  ```

  ```python Python theme={"dark"}
  import requests

  payout = requests.post(
      'https://api.sandbox.zuba.com/v1/payouts',
      headers={
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN',
          'Content-Type': 'application/json'
      },
      json={
          'clientRef': 'PAYOUT-INV-002',
          'amount': '1000.00',
          'inputCurrency': 'EUR',
          'currency': 'NGN',
          'route': 'bank_transfer',
          'senderInfo': {
              'type': 'business',
              'companyName': 'Acme Trading Ltd',
              'registrationNumber': '12345678',
              'address': '1 Finsbury Square',
              'city': 'London',
              'postalCode': 'EC2A 1AE',
              'country': 'GB'
          },
          'beneficiary': {
              'id': beneficiary_data['id']
          },
          'reference': 'Invoice #INV-002',
          'description': 'Payment for marketing services'
      }
  )
  ```

  ```java Java theme={"dark"}
  JsonObject businessSenderInfo = new JsonObject();
  businessSenderInfo.addProperty("type", "business");
  businessSenderInfo.addProperty("companyName", "Acme Trading Ltd");
  businessSenderInfo.addProperty("registrationNumber", "12345678");
  businessSenderInfo.addProperty("address", "1 Finsbury Square");
  businessSenderInfo.addProperty("city", "London");
  businessSenderInfo.addProperty("postalCode", "EC2A 1AE");
  businessSenderInfo.addProperty("country", "GB");

  JsonObject businessPayoutRequest = new JsonObject();
  businessPayoutRequest.addProperty("clientRef", "PAYOUT-INV-002");
  businessPayoutRequest.addProperty("amount", "1000.00");
  businessPayoutRequest.addProperty("inputCurrency", "EUR");
  businessPayoutRequest.addProperty("currency", "NGN");
  businessPayoutRequest.addProperty("route", "bank_transfer");
  businessPayoutRequest.add("senderInfo", businessSenderInfo);
  businessPayoutRequest.add("beneficiary", beneficiaryRef);
  businessPayoutRequest.addProperty("reference", "Invoice #INV-002");
  businessPayoutRequest.addProperty("description", "Payment for marketing services");
  ```
</CodeGroup>

## Track payout status

You can check the status of your payout:

<CodeGroup>
  ```bash curl theme={"dark"}
  curl -X GET "https://api.sandbox.zuba.com/v1/payouts/YOUR_PAYOUT_ID" \
    -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
  ```

  ```javascript JavaScript theme={"dark"}
  const status = await fetch(`https://api.sandbox.zuba.com/v1/payouts/${payoutData.id}`, {
    headers: {
      'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
    }
  });

  const statusData = await status.json();
  console.log('Payout status:', statusData.status);
  ```

  ```python Python theme={"dark"}
  import requests

  status = requests.get(
      f'https://api.sandbox.zuba.com/v1/payouts/{payout_data["id"]}',
      headers={
          'Authorization': 'Bearer YOUR_ACCESS_TOKEN'
      }
  )

  status_data = status.json()
  print(f'Payout status: {status_data["status"]}')
  ```

  ```java Java theme={"dark"}
  String payoutId = payoutData.get("id").getAsString();

  HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://api.sandbox.zuba.com/v1/payouts/" + payoutId))
      .header("Authorization", "Bearer YOUR_ACCESS_TOKEN")
      .GET()
      .build();

  HttpResponse<String> response = client.send(request,
      HttpResponse.BodyHandlers.ofString());

  JsonObject statusData = new Gson().fromJson(response.body(), JsonObject.class);
  System.out.println("Payout status: " + statusData.get("status").getAsString());
  ```
</CodeGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Authentication" icon="key" href="/authentication">
    Learn about secure authentication methods
  </Card>

  <Card title="Webhooks" icon="webhook" href="/guides/webhooks">
    Set up real-time payment notifications
  </Card>

  <Card title="Batch Payouts" icon="layer-group" href="/guides/batch-payouts">
    Process multiple payments efficiently
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/introduction">
    Explore the complete API documentation
  </Card>
</CardGroup>
