---
title: "KYC (new)"
---
Know Your Customer (KYC) verification confirms a customer's identity before you create an account or activate certain features. Gravv requires KYC to comply with financial regulations and prevent fraud.

You can submit documents for verification using two methods: a dedicated interface or the API. Whichever method you use, check the outcome with the [Get applicant verification status](/api-reference/kyc/get-v1-customers-customer-id-kyc-status) endpoint.

## Required documents

Individual customers must provide a selfie and one government-issued identity document:

- Passport
- National ID card
- Driver's license

Business customers must provide the business's registration certificate. Before you start verification for a business, complete KYC verification for every associated person linked to it.

## Submit through a dedicated interface

Use the [Start KYC verification](/api-reference/kyc/post-v1-customers-kyc-start) endpoint to have a customer upload their identity documents (IDs) through a dedicated interface. The endpoint requires only the customer's ID:

```bash title="Basic request"
curl --request POST \
     --url https://api.gravv.xyz/v1/customers/kyc/start \
     --header 'Api-Key: <API_KEY>' \
     --header 'Idempotency-Key: order_789_attempt_1' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "customer_id": "c239895a-0436-4287-a37a-c2664f68d187"
}
'
```

You'll receive a response that includes the verification status and a `web_url` link. Share this link with the customer so they can upload their ID documents:

```json title="Basic response"
{
  "data": {
    "review_status": "pending",
    "status": "success",
    "web_url": "https://in.kyc.com/websdk/p/Cz3WKRuxvlmuS2kp"
  },
  "error": null
}
```

## Submit through the API

To submit documents through the API, Base64-encode each document, upload it with the [Upload document](/api-reference/kyc/post-v1-customers-kyc-upload-document) endpoint, then call the [Initiate server-to-server verification](/api-reference/kyc/post-v1-customers-kyc-start-s2s) endpoint.

### Upload documents

Upload each required document with the [Upload document](/api-reference/kyc/post-v1-customers-kyc-upload-document) endpoint. Encode the document in Base64 and send it as the `content` value. The `Idempotency-Key` header is required.

```bash title="Upload passport request"
curl --request POST \
     --url https://api.gravv.xyz/v1/customers/kyc/upload-document \
     --header 'Api-Key: <API_KEY>' \
     --header 'Idempotency-Key: passport_upload_001' \
     --header 'content-type: application/json' \
     --data '
{
  "customer_id": "aabe0a33-6716-42e2-bbca-7abf1a8bd91c",
  "metadata": {
    "idDocType": "PASSPORT",
    "idDocSubType": "FRONT_SIDE",
    "country": "NGA",
    "firstName": "John",
    "lastName": "Doe",
    "number": "A12345678",
    "issuedDate": "2020-01-15",
    "validUntil": "2030-01-15"
  },
  "content": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAY...",
  "filename": "passport_front.jpg"
}
'
```

A successful upload returns a confirmation:

```json title="Upload passport response"
{
  "data": {
    "status": "success",
    "customer_id": "aabe0a33-6716-42e2-bbca-7abf1a8bd91c",
    "document_type": "PASSPORT",
    "country": "NGA",
    "message": "Document saved. Use /start-s2s to submit for verification."
  },
  "error": null
}
```

The `metadata` object describes the document. All `idDocType` and `idDocSubType` values are uppercase, and `country` is a 3-letter uppercase ISO code.

| Field          | Required for                                     | Description                                                                                                                         |
| :------------- | :----------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------- |
| `idDocType`    | All documents                                    | Document type. Individual customers: `PASSPORT`, `ID_CARD`, `DRIVERS`, or `SELFIE`. Business customers: `REGISTRATION_CERTIFICATE`. |
| `country`      | All documents                                    | Issuing country as a 3-letter uppercase ISO code, such as `NGA`.                                                                    |
| `idDocSubType` | Identity documents                               | Document side: `FRONT_SIDE` or `BACK_SIDE`. Omit for `SELFIE`.                                                                      |
| `number`       | Identity documents and registration certificates | Document identification number.                                                                                                     |
| `issuedDate`   | Identity documents                               | Issue date in `YYYY-MM-DD` format.                                                                                                  |
| `validUntil`   | Identity documents                               | Expiration date in `YYYY-MM-DD` format.                                                                                             |
| `firstName`    | Identity documents                               | First name as shown on the document.                                                                                                |
| `lastName`     | Identity documents                               | Last name as shown on the document.                                                                                                 |
| `middleName`   | Optional                                         | Middle name as shown on the document.                                                                                               |
| `dob`          | Optional                                         | Date of birth in `YYYY-MM-DD` format.                                                                                               |
| `placeOfBirth` | Optional                                         | Place of birth as shown on the document.                                                                                            |

Keep these requirements in mind:

- The maximum document size is 10 MB.
- The `filename` extension and the decoded `content` type must agree, and must be `.jpg`, `.jpeg`, `.png`, or `.pdf`.
- A selfie must be an image (JPEG or PNG); PDF selfies are rejected.
- Omit the `idDocSubType` field for selfie uploads.

A business customer uploads a registration certificate, which may be a formation document or an ownership document. The `idDocType` value is always `REGISTRATION_CERTIFICATE`:

```bash title="Upload registration certificate request"
curl --request POST \
     --url https://api.gravv.xyz/v1/customers/kyc/upload-document \
     --header 'Api-Key: <API_KEY>' \
     --header 'Idempotency-Key: reg_cert_upload_001' \
     --header 'content-type: application/json' \
     --data '
{
  "customer_id": "c84d9a52-2978-43e5-9b86-eac9839e1147",
  "metadata": {
    "idDocType": "REGISTRATION_CERTIFICATE",
    "country": "NGA",
    "number": "RC123456"
  },
  "content": "JVBERi0xLjcKJ...",
  "filename": "registration_certificate.pdf"
}
'
```

### Initiate verification

After uploading all required documents, call the [Initiate server-to-server verification](/api-reference/kyc/post-v1-customers-kyc-start-s2s) endpoint using the customer's id:

```bash title="Initiate verification request"
curl --request POST \
     --url https://api.gravv.xyz/v1/customers/kyc/start-s2s \
     --header 'Api-Key: <API_KEY>' \
     --header 'Idempotency-Key: kyc_initiate_001' \
     --header 'content-type: application/json' \
     --data '
{
  "customer_id": "aabe0a33-6716-42e2-bbca-7abf1a8bd91c"
}
'
```

Gravv starts the review and delivers the outcome through a webhook.

The API response for a pending verification is as follows:

```json title="Initiate verification response"
{
  "data": {
    "status": "pending",
    "message": "KYC verification initiated. Status will be updated via webhook."
  },
  "error": null
}
```

For a business customer, the request fails if no registration certificate has been uploaded:

```json title="Missing registration certificate response"
{
  "data": null,
  "error": {
    "code": "INVALID_REQUEST",
    "message": "business customers must upload a REGISTRATION_CERTIFICATE document before starting KYC verification"
  }
}
```

## Check verification status

Whether the customer completed verification through the dedicated interface or the API, check the outcome with the [Get applicant verification status](/api-reference/kyc/get-v1-customers-customer-id-kyc-status) endpoint. Gravv also notifies you through a webhook when the review finishes.

While the review is in progress, the value of the `reviewStatus` field is `pending` and there's no `reviewResult` field:

```json title="Pending status response"
{
  "data": {
    "reviewStatus": "pending",
    "priority": 0
  },
  "error": null
}
```

Once the review finishes, `reviewStatus` is `completed` and `reviewResult` holds the decision:

```json title="Approved status response"
{
  "data": {
    "reviewStatus": "completed",
    "reviewResult": {
      "reviewAnswer": "approved"
    },
    "reviewDate": "2026-06-19 21:59:00+0000",
    "priority": 0
  },
  "error": null
}
```

A rejected review lists the reason codes in `rejectLabels`, and `reviewRejectType` indicates whether the customer can resubmit:

```json title="Rejected status response"
{
  "data": {
    "reviewStatus": "completed",
    "reviewResult": {
      "reviewAnswer": "rejected",
      "rejectLabels": [
        "BAD_SELFIE",
        "SCREENSHOTS",
        "UNSATISFACTORY_PHOTOS"
      ],
      "reviewRejectType": "RETRY"
    },
    "reviewDate": "2026-06-19 20:44:19+0000",
    "priority": 0
  },
  "error": null
}
```

The status `data` object contains:

- `reviewStatus`: `pending` while the review is in progress, or `completed` once a decision is returned.
- `reviewResult`: the decision, present once the review is completed.
  - `reviewAnswer`: `approved` or `rejected`.
  - `rejectLabels`: reason codes for a rejection, present only when `reviewAnswer` is `rejected`.
  - `reviewRejectType`: the rejection category, such as `RETRY`, present only when `reviewAnswer` is `rejected`.
- `reviewDate`: the decision timestamp, present once the review is completed.
- `priority`: the applicant's review priority.

## Get uploaded documents

To see which documents a customer has uploaded, call the [Get KYC document data](/api-reference/kyc/get-v1-customers-customer-id-kyc-documents) endpoint. It returns the metadata for each uploaded document:

```json title="Uploaded documents response"
{
  "data": {
    "customer_id": "aabe0a33-6716-42e2-bbca-7abf1a8bd91c",
    "documents": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "IDType": "PASSPORT",
        "IDSubType": "FRONT_SIDE",
        "IDNumber": "A12345678",
        "IssuingCountry": "NGA",
        "IssuedDate": "2020-01-01",
        "ExpiryDate": "2030-01-01",
        "has_front_image": true,
        "has_back_image": false,
        "OriginalFilename": "passport_front.jpg"
      }
    ],
    "count": 1
  },
  "error": null
}
```

