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

# Document Verification

> Verify corporate documents such as certificates of incorporation or shareholder certificates.

Verify corporate documents such as certificates of incorporation or shareholder certificates. The API extracts company information and validates shareholder details against user-provided data.

## Supported document types

| Document type                   | Description                                                                                         |
| ------------------------------- | --------------------------------------------------------------------------------------------------- |
| `KybCertificateOfIncorporation` | Certificate of incorporation, articles of association, or similar formation documents               |
| `KybOwnershipDocument`          | Shareholder certificate, ownership registry extract, or similar documents listing beneficial owners |

## Step 1: Create an applicant

Create an applicant to associate the verification with.

<Tabs>
  <Tab title="Curl">
    ```bash theme={null}
    export API_KEY=<YOUR_API_KEY>

    curl -H "ds-api-token: $API_KEY" \
      -H "Content-Type: application/json" \
      -X POST "https://api.dataspike.io/api/v3/applicants" \
      --data '{"external_id": "company-123"}'
    ```

    Response:

    ```json theme={null}
    {
      "id": "01827ed4-c928-7a3c-9a30-7ab7cc169d11"
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import requests

    API_KEY = "<YOUR_API_KEY>"
    BASE = "https://api.dataspike.io"
    HEADERS = {"ds-api-token": API_KEY, "Content-Type": "application/json"}

    resp = requests.post(f"{BASE}/api/v3/applicants", headers=HEADERS, json={"external_id": "company-123"})
    applicant_id = resp.json()["id"]
    ```
  </Tab>
</Tabs>

## Step 2: Upload a document

Upload the corporate document using the file upload endpoint. Note the returned `document_id` — you will pass it to the verification request.

<Tabs>
  <Tab title="Curl">
    ```bash theme={null}
    APPLICANT_ID="01827ed4-c928-7a3c-9a30-7ab7cc169d11"

    curl -H "ds-api-token: $API_KEY" \
      -X POST "https://api.dataspike.io/api/v3/upload/$APPLICANT_ID" \
      -F "file=@certificate_of_incorporation.pdf" \
      -F "document_type=kyb_certificate_of_incorporation"
    ```

    Response:

    ```json theme={null}
    {
      "document_id": "019c9c39-0b8a-7aa4-a5c0-abc123def456"
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    with open("certificate_of_incorporation.pdf", "rb") as f:
        resp = requests.post(
            f"{BASE}/api/v3/upload/{applicant_id}",
            headers={"ds-api-token": API_KEY},
            files={"file": f},
            data={"document_type": "kyb_certificate_of_incorporation"},
        )
    document_id = resp.json()["document_id"]
    ```
  </Tab>
</Tabs>

## Step 3: Submit verification request

Submit the document for KYB verification. Optionally provide shareholder data to validate against extracted information from the document.

<Tabs>
  <Tab title="Curl">
    ```bash theme={null}
    curl -H "ds-api-token: $API_KEY" \
      -H "Content-Type: application/json" \
      -X POST "https://api.dataspike.io/api/v4/kyb/$APPLICANT_ID/verify-document" \
      --data '{
        "documents": [
          {
            "doc_path": "019c9c39-0b8a-7aa4-a5c0-abc123def456",
            "document_type": "KybCertificateOfIncorporation"
          }
        ],
        "user_provided_data": {
          "shareholders": [
            {
              "name": "John Doe",
              "first_name": "John",
              "last_name": "Doe",
              "nationality": "US"
            }
          ]
        }
      }'
    ```

    Response (HTTP 202):

    ```json theme={null}
    {
      "request_id": "019c9e79-8f48-73e1-86e3-317a95f43178",
      "status": "initial"
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    resp = requests.post(
        f"{BASE}/api/v4/kyb/{applicant_id}/verify-document",
        headers=HEADERS,
        json={
            "documents": [
                {"doc_path": document_id, "document_type": "KybCertificateOfIncorporation"}
            ],
            "user_provided_data": {
                "shareholders": [
                    {"name": "John Doe", "first_name": "John", "last_name": "Doe", "nationality": "US"}
                ]
            },
        },
    )
    request_id = resp.json()["request_id"]
    ```
  </Tab>
</Tabs>

### Request body

| Field                                           | Type   | Required | Description                                                    |
| ----------------------------------------------- | ------ | -------- | -------------------------------------------------------------- |
| `documents`                                     | array  | Yes      | List of documents to verify                                    |
| `documents[].doc_path`                          | string | Yes      | Document ID returned from the upload endpoint                  |
| `documents[].document_type`                     | string | Yes      | One of `KybCertificateOfIncorporation`, `KybOwnershipDocument` |
| `user_provided_data`                            | object | No       | Shareholder data to validate against the document              |
| `user_provided_data.shareholders`               | array  | No       | List of shareholders to verify                                 |
| `user_provided_data.shareholders[].name`        | string | No       | Full name                                                      |
| `user_provided_data.shareholders[].first_name`  | string | No       | First name                                                     |
| `user_provided_data.shareholders[].last_name`   | string | No       | Last name                                                      |
| `user_provided_data.shareholders[].nationality` | string | No       | Country code (e.g. `US`)                                       |

## Step 4: Poll for the result

The verification takes approximately 15-30 seconds. Poll the result endpoint until the status changes from `initial`.

<Tabs>
  <Tab title="Curl">
    ```bash theme={null}
    REQUEST_ID="019c9e79-8f48-73e1-86e3-317a95f43178"

    curl -H "ds-api-token: $API_KEY" \
      "https://api.dataspike.io/api/v4/kyb/result/$REQUEST_ID"
    ```

    Example response (verified):

    ```json theme={null}
    {
      "request_id": "019c9e79-8f48-73e1-86e3-317a95f43178",
      "status": "verified",
      "verification_type": "document_verification",
      "response_data": {
        "result": {
          "status": "VERIFIED",
          "document_results": [
            {
              "status": "VERIFIED",
              "document": {
                "document_type": "KybCertificateOfIncorporation"
              },
              "extracted_shareholders": [
                {
                  "name": "John Doe",
                  "first_name": "John",
                  "last_name": "Doe",
                  "country": "US"
                }
              ]
            }
          ],
          "extracted_company_info": {
            "company_name": "Acme Corp.",
            "jurisdiction": "US",
            "address": "123 Main St, Dover, DE 19901"
          }
        }
      },
      "created_at": "2026-02-27T09:41:32.629118Z",
      "completed_at": "2026-02-27T09:42:02.004789Z"
    }
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    import time

    while True:
        resp = requests.get(f"{BASE}/api/v4/kyb/result/{request_id}", headers=HEADERS)
        result = resp.json()
        if result["status"] != "initial":
            break
        time.sleep(5)

    print(result)
    ```
  </Tab>
</Tabs>

## Verification errors

When a document verification returns `not_verified`, the `response_data.result.document_results[].errors` array contains one or more of the following error codes:

| Error code                          | Description                                                       |
| ----------------------------------- | ----------------------------------------------------------------- |
| `SHAREHOLDER_NAME_NOT_FOUND`        | A provided shareholder name was not found in the document         |
| `SHAREHOLDER_NAME_MISMATCH`         | A shareholder name was found but does not match the provided data |
| `SHAREHOLDER_NATIONALITY_MISMATCH`  | Shareholder nationality does not match                            |
| `DOCUMENT_UNREADABLE`               | The document could not be parsed or read                          |
| `DOCUMENT_TYPE_NOT_SUPPORTED`       | The document type is not supported                                |
| `DOCUMENTS_FROM_DIFFERENT_ENTITIES` | Multiple documents appear to belong to different companies        |
| `IRRELEVANT_DOCUMENT_PROVIDED`      | The provided document is not relevant for KYB verification        |
