---
title: "Initiate server-to-server KYC verification"
description: "Initiates KYC verification for a customer using previously uploaded documents in a server-to-server (s2s) flow. This is step 2 of the S2S KYC process. Before calling this endpoint, you must first upload all required documents using the Upload Document endpoint."
protocol: rest
method: POST
endpoint: "/v1/risk/start-kyc-s2s"
baseUrl: "https://api.gravv.xyz"
group: "Risk (deprecated)"
deprecated: true
auth:
  label: "Api-Key"
  name: "Api-Key"
  in: header
---

# Initiate server-to-server KYC verification

<span class="api-deprecated-badge">Deprecated</span>

<Endpoint method="POST" path="/v1/risk/start-kyc-s2s" />

Initiates KYC verification for a customer using previously uploaded documents in a server-to-server (s2s) flow.
This is step 2 of the S2S KYC process. Before calling this endpoint, you must first upload all required 
documents using the Upload Document endpoint.
## Possible outcomes
The following are the possible outcomes:
- **Full success:** All documents uploaded and verification initiated
- **Missing documents:** Returns error with list of missing required documents
- **Partial success:** Some documents failed to upload, returns WebSDK link for customer to complete manually

## Headers

<ParamField name="Idempotency-Key" header="Idempotency-Key" type="string" required>
  Required for POST requests. Reuse only for an identical retry.
</ParamField>

## Request Body

<ParamField name="customer_id" body="customer_id" type="string" required>
  Customer ID to initiate KYC verification for. Documents must be uploaded for this customer before calling this endpoint.
</ParamField>

### Request Examples

<RequestExample>

```json title="IndividualKYC"
{
  "customer_id": "aabe0a33-6716-42e2-bbca-7abf1a8bd91c"
}
```

```json title="BusinessKYB"
{
  "customer_id": "b84d9a52-2978-43e5-9b86-eac9839e1146"
}
```

</RequestExample>

## Responses

| Status | Description |
| --- | --- |
| `200` | KYC S2S process response |
| `400` | Missing required documents |
| `404` | Customer not found |

### 200 response


One of the following variants:

<Expandable title="Variant 1">
  <ResponseField name="data" type="object" required>

    <Expandable title="properties">
      <ResponseField name="status" type="string" required>
        Request status. `"success"` indicates all documents were uploaded and verification has been initiated.

        Possible values: `success`
      </ResponseField>

      <ResponseField name="applicant_id" type="string" required>
        Opaque identifier for the applicant in the verification system
      </ResponseField>

    </Expandable>
  </ResponseField>

  <ResponseField name="error" type="any" required>
    Error information if the request failed
  </ResponseField>

</Expandable>

<Expandable title="Variant 2">
  <ResponseField name="data" type="object" required>

    <Expandable title="properties">
      <ResponseField name="status" type="string" required>
        `"partial_success"` — some documents failed to upload automatically. The customer must complete verification via the `web_url`.

        Possible values: `partial_success`
      </ResponseField>

      <ResponseField name="applicant_id" type="string" required>
        Opaque identifier for the applicant in the verification system
      </ResponseField>

      <ResponseField name="web_url" type="string" required>
        WebSDK URL for the customer to manually complete document upload
      </ResponseField>

      <ResponseField name="failed_documents" type="object[]" required>
        List of documents that failed to upload automatically

        <Expandable title="properties">
          <ResponseField name="doc_type" type="string">

            Possible values: `passport`, `id_card`, `drivers_license`, `selfie`, `registration_certificate`
          </ResponseField>

          <ResponseField name="reason" type="string">
          </ResponseField>

        </Expandable>
      </ResponseField>

      <ResponseField name="message" type="string">
        Instruction message for next steps
      </ResponseField>

    </Expandable>
  </ResponseField>

  <ResponseField name="error" type="any" required>
  </ResponseField>

</Expandable>

<ResponseExample>

```json title="FullSuccess"
{
  "data": {
    "status": "success",
    "applicant_id": "apl_example_123"
  },
  "error": null
}
```

```json title="PartialSuccess"
{
  "data": {
    "status": "partial_success",
    "applicant_id": "apl_example_123",
    "web_url": "https://verify.gravv.xyz/websdk/p/sbx_example_token",
    "failed_documents": [
      {
        "doc_type": "selfie",
        "reason": "Upload failed"
      }
    ],
    "message": "Some documents could not be uploaded automatically. Complete verification using the provided link."
  },
  "error": null
}
```

</ResponseExample>

### 400 response

<ResponseField name="data" type="any" required>
  Always null for error responses
</ResponseField>

<ResponseField name="error" type="string" required>
  Human-readable error message
</ResponseField>

<ResponseField name="error" type="object">

  <Expandable title="properties">
    <ResponseField name="code" type="string">

      Possible values: `missing_documents`
    </ResponseField>

    <ResponseField name="message" type="string">
    </ResponseField>

    <ResponseField name="details" type="object">

      <Expandable title="properties">
        <ResponseField name="missing_documents" type="string[]">

          Possible values: `passport`, `id_card`, `drivers_license`, `selfie`, `registration_certificate`
        </ResponseField>

      </Expandable>
    </ResponseField>

  </Expandable>
</ResponseField>

<ResponseExample>

```json title="MissingDocuments"
{
  "data": null,
  "error": {
    "code": "missing_documents",
    "message": "Required documents have not been uploaded for this customer",
    "details": {
      "missing_documents": [
        "passport",
        "selfie"
      ]
    }
  }
}
```

</ResponseExample>

### 404 response

<ResponseField name="data" type="any" required>
  Always null for error responses
</ResponseField>

<ResponseField name="error" type="string" required>
  Human-readable error message
</ResponseField>

<ResponseField name="error" type="any">

  <Expandable title="properties">
    <ResponseField name="code" type="any">
    </ResponseField>

    <ResponseField name="message" type="any">
    </ResponseField>

  </Expandable>
</ResponseField>

<ResponseExample>

```json title="Response"
{
  "data": null,
  "error": {
    "code": "not_found",
    "message": "Customer not found",
    "details": {}
  }
}
```

</ResponseExample>

## Authorization

- **ApiKeyAuth**
