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

# Customers API — manage payment customers

> Create, update, and verify customers who send or receive payments through Dubu Pay. Manage KYC tiers, balances, and transaction ledgers.

Customers represent the end users who interact with your payment flows — they can receive NGN virtual bank accounts, undergo KYC verification to unlock higher transaction limits, and maintain a balance ledger you can query at any time. All customer resources are scoped to your merchant account; customers created by one merchant are never visible to another.

## Authentication

All endpoints require either a Bearer token or an API key.

```
Authorization: Bearer <access_token>
```

```
X-Api-Key: dubu_sk_live_...
```

***

## Create a customer

`POST https://api.dubupay.com/api/v1/customers`

Creates a new customer record. The email address must be unique within your merchant account.

### Request body

<ParamField body="email" type="string" required>
  A valid email address for the customer. Must be unique within your merchant account.
</ParamField>

<ParamField body="first_name" type="string" required>
  The customer's first name. Between 1 and 100 characters.
</ParamField>

<ParamField body="last_name" type="string" required>
  The customer's last name. Between 1 and 100 characters.
</ParamField>

### Response

<ResponseField name="success" type="boolean">
  `true` when the request succeeds.
</ResponseField>

<ResponseField name="data" type="object">
  The created customer object.

  <Expandable title="data fields">
    <ResponseField name="id" type="string">
      Unique UUID for the customer.
    </ResponseField>

    <ResponseField name="email" type="string">
      The customer's email address.
    </ResponseField>

    <ResponseField name="first_name" type="string">
      The customer's first name.
    </ResponseField>

    <ResponseField name="last_name" type="string">
      The customer's last name.
    </ResponseField>

    <ResponseField name="kyc_tier" type="string">
      Current KYC tier. One of `TIER_0`, `TIER_1`, `TIER_2`.
    </ResponseField>

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

### Example

```bash theme={null}
curl -X POST https://api.dubupay.com/api/v1/customers \
  -H "X-Api-Key: dubu_sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "email": "ada.obi@example.com",
    "first_name": "Ada",
    "last_name": "Obi"
  }'
```

***

## List customers

`GET https://api.dubupay.com/api/v1/customers`

Returns a paginated list of customers belonging to your merchant account. Use cursor-based pagination for large datasets.

### Query parameters

<ParamField query="limit" type="number">
  Maximum number of customers to return. Positive integer, up to 200. Defaults to 20.
</ParamField>

<ParamField query="cursor" type="string">
  Pagination cursor from the previous response's `next_cursor` field.
</ParamField>

<ParamField query="email" type="string">
  Filter by exact email address.
</ParamField>

### Example

```bash theme={null}
curl "https://api.dubupay.com/api/v1/customers?limit=50" \
  -H "X-Api-Key: dubu_sk_live_..."
```

***

## Get a customer

`GET https://api.dubupay.com/api/v1/customers/:id`

Retrieves a single customer by their UUID.

### Path parameters

<ParamField path="id" type="string" required>
  The customer's UUID.
</ParamField>

### Example

```bash theme={null}
curl "https://api.dubupay.com/api/v1/customers/cus_01HXYZ" \
  -H "X-Api-Key: dubu_sk_live_..."
```

***

## Update a customer

`PATCH https://api.dubupay.com/api/v1/customers/:id`

Updates the customer's name. At least one of `first_name` or `last_name` must be provided.

### Path parameters

<ParamField path="id" type="string" required>
  The customer's UUID.
</ParamField>

### Request body

<ParamField body="first_name" type="string">
  Updated first name. Between 1 and 100 characters.
</ParamField>

<ParamField body="last_name" type="string">
  Updated last name. Between 1 and 100 characters.
</ParamField>

<Note>
  At least one of `first_name` or `last_name` must be included in the request body.
</Note>

### Example

```bash theme={null}
curl -X PATCH "https://api.dubupay.com/api/v1/customers/cus_01HXYZ" \
  -H "X-Api-Key: dubu_sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"last_name": "Okonkwo"}'
```

***

## Submit Tier 1 KYC

`POST https://api.dubupay.com/api/v1/customers/:id/tier1-verification`

Submits a customer's BVN (Bank Verification Number) and a selfie image to initiate Tier 1 identity verification. Tier 1 unlocks basic transaction limits.

### Path parameters

<ParamField path="id" type="string" required>
  The customer's UUID.
</ParamField>

### Request body

<ParamField body="bvn" type="string" required>
  The customer's 11-digit Bank Verification Number. Must contain only digits.
</ParamField>

<ParamField body="image_url" type="string" required>
  A publicly accessible URL to a selfie or portrait photo of the customer.
</ParamField>

### Example

```bash theme={null}
curl -X POST "https://api.dubupay.com/api/v1/customers/cus_01HXYZ/tier1-verification" \
  -H "X-Api-Key: dubu_sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "bvn": "12345678901",
    "image_url": "https://cdn.example.com/selfies/ada-obi.jpg"
  }'
```

***

## Submit Tier 2 KYC

`POST https://api.dubupay.com/api/v1/customers/:id/tier2-verification`

Submits full KYC documentation for Tier 2 verification. Tier 2 unlocks higher limits and is required for permanent virtual accounts. You must provide residential address, government-issued identification, and declarations about the customer's financial profile.

### Path parameters

<ParamField path="id" type="string" required>
  The customer's UUID.
</ParamField>

### Request body

<ParamField body="residential_address" type="object" required>
  The customer's current home address.

  <Expandable title="residential_address fields">
    <ParamField body="street_line_1" type="string" required>
      Primary street address line.
    </ParamField>

    <ParamField body="city" type="string" required>
      City name.
    </ParamField>

    <ParamField body="subdivision" type="string" required>
      State, province, or region.
    </ParamField>

    <ParamField body="postal_code" type="string" required>
      Postal or ZIP code.
    </ParamField>

    <ParamField body="country" type="string" required>
      ISO 3166-1 alpha-3 country code (e.g., `NGA`).
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="nationality" type="string" required>
  ISO 3166-1 alpha-3 country code for the customer's nationality (e.g., `NGA`).
</ParamField>

<ParamField body="birth_date" type="string" required>
  Date of birth in `YYYY-MM-DD` format.
</ParamField>

<ParamField body="identifying_information" type="array" required>
  At least one government-issued identity document.

  <Expandable title="document fields">
    <ParamField body="type" type="string" required>
      Document type. One of `passport`, `drivers_license`, `national_id`.
    </ParamField>

    <ParamField body="issuing_country" type="string" required>
      ISO 3166-1 alpha-3 country code of the issuing country.
    </ParamField>

    <ParamField body="number" type="string">
      Document number (optional).
    </ParamField>

    <ParamField body="expiration" type="string">
      Expiry date in `YYYY-MM-DD` format.
    </ParamField>

    <ParamField body="image_front" type="string" required>
      URL to the front-side image of the document.
    </ParamField>

    <ParamField body="image_back" type="string">
      URL to the back-side image of the document (optional).
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="source_of_funds" type="string" required>
  Where the customer's funds originate. One of: `company_funds`, `ecommerce_reseller`, `gambling_proceeds`, `gifts`, `government_benefits`, `inheritance`, `investments_loans`, `pension_retirement`, `salary`, `sale_of_assets_real_estate`, `savings`, `someone_elses_funds`.
</ParamField>

<ParamField body="account_purpose" type="string" required>
  The intended purpose of the account. One of: `charitable_donations`, `ecommerce_retail_payments`, `investment_purposes`, `operating_a_company`, `other`, `payments_to_friends_or_family_abroad`, `personal_or_living_expenses`, `protect_wealth`, `purchase_goods_and_services`, `receive_payment_for_freelancing`, `receive_salary`.
</ParamField>

<ParamField body="expected_monthly_payments_usd" type="string" required>
  Expected monthly USD transaction volume. One of: `0_4999`, `5000_9999`, `10000_49999`, `50000_plus`.
</ParamField>

<ParamField body="acting_as_intermediary" type="boolean" required>
  Whether the customer is acting as a payment intermediary on behalf of another party.
</ParamField>

<ParamField body="employment_status" type="string" required>
  Employment status. One of: `employed`, `homemaker`, `retired`, `self_employed`, `student`, `unemployed`.
</ParamField>

<ParamField body="most_recent_occupation" type="string" required>
  Occupation category. One of: `BUSINESS_ADMIN`, `STEM`, `HEALTHCARE_SOCIAL`, `EDUCATION_ARTS_MEDIA`, `SERVICE_PUBLIC_SAFETY`, `TRADES_LABOR`.
</ParamField>

<ParamField body="documents" type="array">
  Optional supporting documents (e.g., proof of address, proof of source of funds).

  <Expandable title="document fields">
    <ParamField body="file" type="string" required>
      URL to the supporting document file.
    </ParamField>

    <ParamField body="purposes" type="array" required>
      Purposes this document satisfies. At least one of: `proof_of_address`, `proof_of_source_of_funds`.
    </ParamField>
  </Expandable>
</ParamField>

***

## Get customer balance

`GET https://api.dubupay.com/api/v1/customers/:id/balance`

Returns the current balance held for a customer across all currencies.

### Path parameters

<ParamField path="id" type="string" required>
  The customer's UUID.
</ParamField>

### Response

<ResponseField name="data" type="object">
  Balance breakdown for the customer.

  <Expandable title="data fields">
    <ResponseField name="ngn" type="string">
      Current NGN balance as a decimal string.
    </ResponseField>

    <ResponseField name="usd" type="string">
      Current USD-equivalent balance as a decimal string.
    </ResponseField>

    <ResponseField name="updated_at" type="string">
      ISO 8601 timestamp of the last balance update.
    </ResponseField>
  </Expandable>
</ResponseField>

### Example

```bash theme={null}
curl "https://api.dubupay.com/api/v1/customers/cus_01HXYZ/balance" \
  -H "X-Api-Key: dubu_sk_live_..."
```

***

## Get customer ledger

`GET https://api.dubupay.com/api/v1/customers/:id/ledger`

Returns a paginated transaction history (ledger) for a customer, showing credits and debits over time.

### Path parameters

<ParamField path="id" type="string" required>
  The customer's UUID.
</ParamField>

### Response

<ResponseField name="data" type="array">
  List of ledger entries.

  <Expandable title="entry fields">
    <ResponseField name="id" type="string">
      Unique ledger entry ID.
    </ResponseField>

    <ResponseField name="type" type="string">
      Entry type, e.g., `CREDIT` or `DEBIT`.
    </ResponseField>

    <ResponseField name="amount" type="string">
      Transaction amount as a decimal string.
    </ResponseField>

    <ResponseField name="currency" type="string">
      Currency code, e.g., `NGN`.
    </ResponseField>

    <ResponseField name="description" type="string">
      Human-readable description of the transaction.
    </ResponseField>

    <ResponseField name="created_at" type="string">
      ISO 8601 timestamp.
    </ResponseField>
  </Expandable>
</ResponseField>

### Example

```bash theme={null}
curl "https://api.dubupay.com/api/v1/customers/cus_01HXYZ/ledger" \
  -H "X-Api-Key: dubu_sk_live_..."
```
