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

# Get started with customers

> Create your first customer and read it back, in under ten minutes.

This page creates one individual customer in sandbox and reads it back. It does not open an account or move money.

## Before you start

You need a sandbox API key (`sk_test_…`) on a **business** client. See [authentication](/guides/authentication) if you do not have one yet.

```bash theme={null}
export SAKAWAVE_API_KEY='sk_test_replace_with_your_key'
export SAKAWAVE_BASE_URL='https://sandbox-api.sakawave.example'
```

## 1. Create the customer

Eight fields are required for an individual: `type`, `jurisdiction`, `externalReference`, `email`, `phoneNumber`, `address`, `firstName`, and `lastName`. Within `address`, `line1`, `city`, and `country` are required. Everything else is optional.

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url "$SAKAWAVE_BASE_URL/v1/customers" \
    --header "Authorization: Bearer $SAKAWAVE_API_KEY" \
    --header "Content-Type: application/json" \
    --header "X-Request-ID: get_started_customer_001" \
    --data '{
      "type": "individual",
      "jurisdiction": "NG",
      "externalReference": "cust_1001",
      "email": "ada@example.com",
      "phoneNumber": "+2348012345678",
      "address": {
        "line1": "14 Marina Road",
        "city": "Lagos",
        "state": "Lagos",
        "postalCode": "100001",
        "country": "NG"
      },
      "firstName": "Ada",
      "lastName": "Okafor"
    }'
  ```

  ```ts Node.js theme={null}
  const response = await fetch(`${process.env.SAKAWAVE_BASE_URL}/v1/customers`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.SAKAWAVE_API_KEY}`,
      'Content-Type': 'application/json',
      'X-Request-ID': 'get_started_customer_001',
    },
    body: JSON.stringify({
      type: 'individual',
      jurisdiction: 'NG',
      externalReference: 'cust_1001',
      email: 'ada@example.com',
      phoneNumber: '+2348012345678',
      address: {
        line1: '14 Marina Road',
        city: 'Lagos',
        state: 'Lagos',
        postalCode: '100001',
        country: 'NG',
      },
      firstName: 'Ada',
      lastName: 'Okafor',
    }),
  });

  const customer = await response.json();
  if (!response.ok) {
    throw new Error(`${response.status}: ${customer.code} — ${customer.message}`);
  }

  console.log(customer.id);
  ```

  ```python Python theme={null}
  import os
  import requests

  response = requests.post(
      f"{os.environ['SAKAWAVE_BASE_URL']}/v1/customers",
      json={
          "type": "individual",
          "jurisdiction": "NG",
          "externalReference": "cust_1001",
          "email": "ada@example.com",
          "phoneNumber": "+2348012345678",
          "address": {
              "line1": "14 Marina Road",
              "city": "Lagos",
              "state": "Lagos",
              "postalCode": "100001",
              "country": "NG",
          },
          "firstName": "Ada",
          "lastName": "Okafor",
      },
      headers={
          "Authorization": f"Bearer {os.environ['SAKAWAVE_API_KEY']}",
          "X-Request-ID": "get_started_customer_001",
      },
      timeout=30,
  )
  customer = response.json()
  if not response.ok:
      raise RuntimeError(f"{response.status_code}: {customer.get('code')} — {customer.get('message')}")

  print(customer["id"])
  ```
</CodeGroup>

A `201` returns the stored customer:

```json theme={null}
{
  "id": "01K2Z3AB4C5D6E7F8G9HJKMNPQ",
  "type": "individual",
  "jurisdiction": "NG",
  "externalReference": "cust_1001",
  "displayName": "Ada Okafor",
  "name": "Ada Okafor",
  "firstName": "Ada",
  "middleName": null,
  "lastName": "Okafor",
  "email": "ada@example.com",
  "phoneNumber": "+2348012345678",
  "dateOfBirth": null,
  "gender": null,
  "address": {
    "line1": "14 Marina Road",
    "line2": null,
    "city": "Lagos",
    "state": "Lagos",
    "postalCode": "100001",
    "country": "NG"
  },
  "tier": 1,
  "hasBvn": false,
  "hasNin": false,
  "hasPassport": false,
  "hasDriversLicence": false,
  "hasTaxId": false,
  "hasRegistrationNumber": false,
  "createdAt": "2026-08-14T09:00:00.000Z",
  "updatedAt": "2026-08-14T09:00:00.000Z"
}
```

## 2. Check three things

This is the part worth ten minutes.

1. **`id` is the identifier from here on.** Store it. It is opaque; never construct or parse one.
2. **The response is the stored form, not your input.** Send `"email": "Ada@Example.com "` and you get back `ada@example.com`. Text is trimmed, `email` is lowercased, `jurisdiction` and `address.country` are uppercased. Compare against the response.
3. **`name` and `displayName` were composed for you.** You sent first and last names; Sakawave joined them.

## 3. Read it back

```bash theme={null}
curl --request GET \
  --url "$SAKAWAVE_BASE_URL/v1/customers/$CUSTOMER_ID" \
  --header "Authorization: Bearer $SAKAWAVE_API_KEY"
```

Or find it by the reference you chose, without having stored the ID:

```bash theme={null}
curl --request GET \
  --url "$SAKAWAVE_BASE_URL/v1/customers?externalReference=cust_1001" \
  --header "Authorization: Bearer $SAKAWAVE_API_KEY"
```

## If it failed

| Status | `code` | What to do |
| - | - | - |
| `400` | `validation_failed` | Read `errors[]`. Every failing field is listed at once, each with a `field` and a `path`. |
| `400` | `validation_failed` with `disposable_email_not_allowed` in `errors[].code` | The email domain is disposable or temporary. Ask for a permanent address. |
| `401` | `INVALID_API_KEY` | Wrong environment, revoked key, expired key, or an IP outside the key's allowlist. |
| `409` | `client_not_a_business` | The key belongs to a client that is not a business. Customers are a business-client feature. |
| `409` | `customer_already_exists` | This `externalReference` is already in use by one of your active customers. |

## Next

* [Open a wallet account for this customer](/tutorials/create-customer-and-account)
* [Setup and configuration](/services/customers/setup-and-configuration) — limits, environments, and webhooks
* [Use cases](/services/customers/use-cases) — sync, search, offboarding


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.