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

# Verify Customer

> Run identity verification and AML screening for a customer in a single call.

## Endpoint

```
POST /api/onboarding/verify_customer
```

## Request

### Headers

| Header           | Value              | Required |
| ---------------- | ------------------ | -------- |
| `x-access-token` | Your API key       | Yes      |
| `Content-Type`   | `application/json` | Yes      |

### Body Parameters

| Parameter         | Type   | Required | Description                                                                                            |
| ----------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------ |
| `country`         | string | Yes      | Country of the customer. Supported: `nigeria`, `kenya`, `ghana`, `uganda`, `rwanda`                    |
| `identifier`      | string | Yes      | The customer's ID number (e.g. BVN, NIN, National ID)                                                  |
| `identifier_type` | string | No       | Overrides the country default. See [supported values](/v3/onboarding/introduction#supported-countries) |

### Example

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://adhere-api.smartcomply.com/api/onboarding/verify_customer \
    -H "x-access-token: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "country": "nigeria",
      "identifier": "12345678901"
    }'
  ```

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

  response = requests.post(
      "https://adhere-api.smartcomply.com/api/onboarding/verify_customer",
      headers={"x-access-token": "YOUR_API_KEY"},
      json={
          "country": "nigeria",
          "identifier": "12345678901",
      },
  )
  print(response.json())
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://adhere-api.smartcomply.com/api/onboarding/verify_customer", {
    method: "POST",
    headers: {
      "x-access-token": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      country: "nigeria",
      identifier: "12345678901",
    }),
  });
  const data = await response.json();
  ```
</CodeGroup>

## Response

All responses return HTTP `200`. Use the `decision` field — not the HTTP status — to determine the onboarding outcome. See the [Decision Guide](/v3/onboarding/introduction#decision-guide) for how to act on each value.

<ResponseField name="status" type="string">
  Always `"success"` on a `200` response.
</ResponseField>

<ResponseField name="message" type="string">
  Always `"Customer onboarding completed"` on success.
</ResponseField>

<ResponseField name="data" type="object">
  <Expandable title="data fields" defaultOpen>
    <ResponseField name="onboarding_id" type="number">
      Unique ID for this onboarding record.
    </ResponseField>

    <ResponseField name="identity" type="object">
      Result of the identity verification step.

      <Expandable title="identity fields">
        <ResponseField name="verified" type="boolean">
          `true` if the identifier was successfully verified against the issuing authority.
        </ResponseField>

        <ResponseField name="identifier_type" type="string">
          The document type used, e.g. `"BVN"`, `"NIN"`, `"National ID"`.
        </ResponseField>

        <ResponseField name="first_name" type="string">
          Present when `verified: true`.
        </ResponseField>

        <ResponseField name="last_name" type="string">
          Present when `verified: true`.
        </ResponseField>

        <ResponseField name="middle_name" type="string">
          Present when `verified: true` and the provider returns a middle name.
        </ResponseField>

        <ResponseField name="date_of_birth" type="string">
          ISO-8601 date string. Present when `verified: true`.
        </ResponseField>

        <ResponseField name="gender" type="string">
          Present when `verified: true`.
        </ResponseField>

        <ResponseField name="phone" type="string">
          Present when `verified: true` and available from the provider.
        </ResponseField>

        <ResponseField name="error" type="string">
          Error message from the verification provider. Only present when `verified: false`.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="screening" type="object">
      AML screening results. Always returned in a consistent shape, even when screening was skipped.

      <Expandable title="screening fields">
        <ResponseField name="sanctions" type="array">
          Sanctions matches. Each entry contains `entity_name`, `recorded_date`, `country`, `sanction_body`, `sanction_types`, and `other_information`.
        </ResponseField>

        <ResponseField name="peps" type="array">
          PEP matches. Each entry contains `name`, `pep_types`, `gender`, `country`, `source`, and `political_post`.
        </ResponseField>

        <ResponseField name="adverse_media" type="array">
          Currently always `[]` — will be enabled as a configurable step in a future release.
        </ResponseField>

        <ResponseField name="risk_level" type="string">
          `"low"`, `"medium"`, or `"high"`.
        </ResponseField>

        <ResponseField name="note" type="string">
          Present only when screening was skipped. Explains why.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="decision" type="string">
      `"pass"`, `"review"`, or `"fail"`. See the [Decision Guide](/v3/onboarding/introduction#decision-guide).
    </ResponseField>
  </Expandable>
</ResponseField>

### Pass — identity verified, no matches

```json theme={null}
{
  "status": "success",
  "message": "Customer onboarding completed",
  "data": {
    "onboarding_id": 1024,
    "identity": {
      "verified": true,
      "identifier_type": "BVN",
      "first_name": "Amaka",
      "middle_name": "Chisom",
      "last_name": "Okafor",
      "date_of_birth": "1992-04-17",
      "gender": "Female",
      "phone": "08031234567"
    },
    "screening": {
      "sanctions": [],
      "peps": [],
      "adverse_media": [],
      "risk_level": "low"
    },
    "decision": "pass"
  }
}
```

### Review — identity verified, PEP match found

```json theme={null}
{
  "status": "success",
  "message": "Customer onboarding completed",
  "data": {
    "onboarding_id": 1025,
    "identity": {
      "verified": true,
      "identifier_type": "NIN",
      "first_name": "Emeka",
      "last_name": "Nwosu",
      "date_of_birth": "1985-11-02",
      "gender": "Male"
    },
    "screening": {
      "sanctions": [],
      "peps": [
        {
          "name": "Emeka Nwosu",
          "pep_types": ["role.pep", "pep-class-2"],
          "gender": "male",
          "source": "OpenSanctions",
          "country": "Nigeria",
          "political_post": ["Former State Commissioner"]
        }
      ],
      "adverse_media": [],
      "risk_level": "medium"
    },
    "decision": "review"
  }
}
```

### Fail — identity verification unsuccessful

```json theme={null}
{
  "status": "success",
  "message": "Customer onboarding completed",
  "data": {
    "onboarding_id": 1026,
    "identity": {
      "verified": false,
      "identifier_type": "BVN",
      "error": "Bank Verification Number (BVN) check failed: Invalid BVN provided"
    },
    "screening": {
      "sanctions": [],
      "peps": [],
      "adverse_media": [],
      "risk_level": "low",
      "note": "AML screening skipped: identity verification did not return a name"
    },
    "decision": "fail"
  }
}
```

### Error Responses

| HTTP Status | Message                                                               | Cause                                           |
| ----------- | --------------------------------------------------------------------- | ----------------------------------------------- |
| `401`       | `"Authorization token is missing"`                                    | No `x-access-token` header                      |
| `401`       | `"Authorization failed"`                                              | Token not recognised or expired                 |
| `403`       | `"Identity Verification suite isn't enabled for this branch"`         | Feature not activated — contact support         |
| `403`       | `"Your account hasn't been verified for Identity Verification Suite"` | Admin account pending verification              |
| `400`       | `"country is required"`                                               | Missing `country` field                         |
| `400`       | `"identifier is required"`                                            | Missing `identifier` field                      |
| `400`       | `"Unsupported country '…'. Supported: …"`                             | Invalid `country` value                         |
| `400`       | `"Unsupported identifier_type '…' for …. Supported: …"`               | Invalid `identifier_type` for the given country |


## OpenAPI

````yaml POST /api/onboarding/verify_customer
openapi: 3.0.3
info:
  title: Adhere API
  description: >-
    Identity verification, credit checks, transaction monitoring, and loan fraud
    detection across Africa.
  version: 3.0.0
servers:
  - url: https://adhere-api.smartcomply.com
    description: Production
security:
  - ApiKeyAuth: []
tags:
  - name: Nigeria KYC
  - name: Kenya KYC
  - name: Ghana KYC
  - name: Rwanda KYC
  - name: Uganda KYC
  - name: Biometrics
  - name: Individual Credit
  - name: Business Credit
  - name: Transaction Monitoring
  - name: Transaction Screening
  - name: Transaction KYC
  - name: Loan Fraud
  - name: User Journey
paths:
  /api/onboarding/verify_customer:
    post:
      tags:
        - Customer Onboarding
      summary: Verify Customer
      description: >-
        Combines identity verification and AML screening into a single call.
        Returns a consolidated risk decision alongside raw IVS and screening
        results.
      operationId: verifyCustomer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - country
                - identifier
              properties:
                country:
                  type: string
                  enum:
                    - nigeria
                    - kenya
                    - ghana
                    - uganda
                    - rwanda
                  example: nigeria
                  description: Country of the customer
                identifier:
                  type: string
                  example: '12345678901'
                  description: The ID number to verify (BVN, NIN, National ID, etc.)
                identifier_type:
                  type: string
                  example: bvn
                  description: >-
                    Overrides the country default. Nigeria: bvn, nin, vnin.
                    Others: national_id or ghana_id.
      responses:
        '200':
          description: Onboarding completed — check decision field for pass/review/fail
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: Feature not enabled for this branch or account not verified
components:
  responses:
    BadRequest:
      description: Bad Request
      content:
        application/json:
          schema:
            type: object
            properties:
              status:
                type: string
                example: failed
              data:
                type: array
                items: {}
              message:
                type: string
    Unauthorized:
      description: Unauthorized
      content:
        application/json:
          schema:
            type: object
            properties:
              status:
                type: string
                example: failed
              message:
                type: string
                example: Authentication credentials were not provided.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-access-token
      description: Your Adhere API secret key

````