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

# Create customer

> Register a person once and reuse their customer_id for every later verification.

```http theme={null}
POST /api/account/integration/kyc/customer
```

Creates a customer — the persistent record of one person in your account. Call this the
first time you verify someone, store the returned `customer_id`, and reuse it for every
transaction that person ever runs.

<Info>
  Reusing `customer_id` is what enables face comparison against the enrolled face and
  consistency checks against previously extracted document data. Creating a new customer
  per verification silently disables both.
</Info>

## Request

<ParamField header="Authorization" type="string" required>
  `Bearer {access_token}` — see [Authentication](/api-reference/authentication).
</ParamField>

<ParamField body="external_customer_id" type="string" required>
  Your own identifier for this person — a user id, an account number, whatever you key on.
  Returned back to you on the response and useful for reconciliation.
</ParamField>

<ParamField body="email" type="string">
  The person's email address. Optional.
</ParamField>

<ParamField body="phone_number" type="string">
  The person's phone number in E.164 format, for example `+5491122334455`. Optional.
</ParamField>

<ParamField body="face_reference_image" type="string">
  A photo of the person's face. Optional. When provided, the customer is created with an enrolled reference face, which is treated as valid. Later transactions compare the captured face against it.

  Send the plain base64 of the image file: standard alphabet, without a `data:image/...;base64,` prefix and without line breaks. JPEG or PNG only, up to 4 MB before encoding. Other formats, such as HEIC or WebP, are rejected.
</ParamField>

## Response

<ResponseField name="customer_id" type="string (UUID)">
  The chmod identifier for this person. **Persist this.**
</ResponseField>

<ResponseField name="external_customer_id" type="string">
  Echoed back from the request.
</ResponseField>

<ResponseField name="created_at" type="string (ISO-8601)">
  When the customer was created.
</ResponseField>

## Example

<CodeGroup>
  ```bash cURL lines theme={null}
  curl -X POST https://{your-api-host}/api/account/integration/kyc/customer \
    -H "Authorization: Bearer $ACCESS_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
      "external_customer_id": "user_84213",
      "email": "ana@example.com",
      "phone_number": "+5491122334455"
    }'
  ```

  ```typescript Node.js lines theme={null}
  const res = await fetch(`${CHMOD_API_URL}/api/account/integration/kyc/customer`, {
    method: "POST",
    headers: {
      Authorization:  `Bearer ${accessToken}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      external_customer_id: user.id,
      email:                user.email,
      phone_number:         user.phone,
    }),
  });

  const { customer_id } = await res.json();
  await db.users.update(user.id, { chmodCustomerId: customer_id });
  ```

  ```python Python lines theme={null}
  res = requests.post(
      f"{CHMOD_API_URL}/api/account/integration/kyc/customer",
      headers={"Authorization": f"Bearer {access_token}"},
      json={
          "external_customer_id": str(user.id),
          "email":                user.email,
          "phone_number":         user.phone,
      },
  )
  customer_id = res.json()["customer_id"]
  ```
</CodeGroup>

```json Response lines theme={null}
{
  "external_customer_id": "user_84213",
  "customer_id": "4a63b11c-803d-4126-bf91-d5f8290ff0a5",
  "created_at": "2026-09-10T14:22:00.000Z"
}
```

## Errors

A `400` on this endpoint means nothing was created. See [Errors](/api-reference/errors) for the response body.

| Cause | What to do |
| - | - |
| A customer with this `external_customer_id` already exists in your account | Reuse the `customer_id` you stored when you created it. Do not retry. |
| `face_reference_image` is not valid base64, is not a JPEG or PNG, or is larger than 4 MB | Fix the image and send the request again. |

## Customer status

Every customer carries a status that chmod maintains, and it participates in the analysis
of every transaction:

| Status | Effect on a transaction |
| - | - |
| `ACTIVE` | Normal. No issue emitted. |
| `SUSPICIOUS` | A `CUSTOMER_SUSPICIOUS` warning is emitted. Does not change the decision. |
| `BLOCKED` | A `CUSTOMER_BLOCKED` rejection is emitted. The transaction is `REJECTED`. |

## Next

<Card title="Create transaction" icon="circle-plus" href="/api-reference/transactions/create-transaction">
  Open a verification for this customer and get the SDK token.
</Card>


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