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

# Getting User KYC Data

> Access user identity verification details and document images via the SIS API with dual authentication

## Overview

The <Tooltip headline="SIS" tip="Sumvin Identity Service — the B2B API that exchanges signed Stamped Mandates for JWTs." cta="Glossary →" href="/glossary">SIS</Tooltip> exposes two read-only endpoints for third-party consumers to access a user's <Tooltip headline="KYC" tip="Know Your Customer — identity verification that feeds attestation claims onto credentials." cta="Glossary →" href="/glossary">KYC</Tooltip> verification data:

* **KYC Details** — verification status, personal information, document metadata, and rejection details
* **Document Images** — binary image data for each submitted identity document

<Snippet file="product-term-disambiguation.mdx" />

Both endpoints require dual authentication: an API key with `get_kyc` scope and a <Tooltip headline="Stamped Mandate" tip="A signed authorisation a user grants for specific scoped actions — delivered on the wire as a PINT." cta="Glossary →" href="/glossary">Stamped Mandate</Tooltip> with `sr:us:pint:identity:kyc_read` scope. A Stamped Mandate is delivered over the API as a `PINT` (header `x-sumvin-pint-token`), so the dual-auth flow below works in PINT terms.

## Prerequisites

* SIS API key with `get_kyc` scope
* User's `external_id` (from SRI lookup or user creation)
* PINT token with `sr:us:pint:identity:kyc_read` scope (obtained via [Token Exchange](/identity/token-exchange))

## Authentication

Every request to the KYC endpoints must include both authentication credentials:

```mermaid theme={null}
sequenceDiagram
    participant Consumer as 3P Consumer
    participant SIS as SIS API

    Consumer->>SIS: Authorization: Bearer <api-key>
    Consumer->>SIS: x-sumvin-pint-token: <pint-jwt>
    SIS->>SIS: Validate API key (get_kyc scope)
    SIS->>SIS: Validate PINT token (sr:us:pint:identity:kyc_read scope)
    SIS-->>Consumer: KYC data
```

| Header                | Value              | Purpose                                              |
| --------------------- | ------------------ | ---------------------------------------------------- |
| `Authorization`       | `Bearer <api-key>` | API key with `get_kyc` scope                         |
| `x-sumvin-pint-token` | `<jwt>`            | PINT token with `sr:us:pint:identity:kyc_read` scope |

## Step 1: Obtain a PINT Token

Exchange a signed PINT for a JWT, requesting the `sr:us:pint:identity:kyc_read` scope:

```bash theme={null}
curl -X POST https://sis.sumvin.com/v0/sis/token/pint \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "pint": {
      "wallet": "0xE23c9A70BC749EBddd8c78a864fd911D04E9e992",
      "nonce": 42,
      "statement": "KYC data access for partner X",
      "scopes": ["sr:us:pint:identity:kyc_read"],
      "resources": [],
      "maxAmount": 0,
      "maxAmountToken": "0x0000000000000000000000000000000000000000",
      "expiresAt": 1740000000
    },
    "signature": "0x...",
    "audience": "partner-x.example.com"
  }'
```

The response includes a `token` field containing the PINT JWT. Use this as the `x-sumvin-pint-token` header value in subsequent requests.

## Step 2: Look Up the User

Use the SRI lookup endpoint to resolve a user and obtain their `external_id`:

```bash theme={null}
curl https://sis.sumvin.com/v0/users/{sri} \
  -H "Authorization: Bearer <your-api-key>"
```

The `external_id` from the response is used as `{user_id}` in the KYC endpoints below.

## Step 3: Get KYC Details

Fetch the user's verification status, personal information, and document metadata:

```bash theme={null}
curl https://sis.sumvin.com/v0/users/user-abc123/kyc \
  -H "Authorization: Bearer <your-api-key>" \
  -H "x-sumvin-pint-token: <pint-jwt>"
```

### Response — 200 OK

```json theme={null}
{
  "status": "approved",
  "verified_at": 1704067200000,
  "rejected_at": null,
  "started_at": 1704060000000,
  "personal_info": {
    "first_name": "Jane",
    "last_name": "Smith",
    "date_of_birth": "1990-05-15",
    "nationality": "GBR",
    "country_of_residence": "GBR"
  },
  "documents": [
    {
      "document_type": "PASSPORT",
      "country": "GBR",
      "status": "approved",
      "submitted_at": null,
      "image_ids": ["img-abc123", "img-def456"]
    }
  ],
  "verification_complete": true,
  "verification_passed": true,
  "rejection": null,
  "_links": {
    "self": { "href": "/v0/users/user-abc123/kyc" }
  }
}
```

### Response Fields

| Field                   | Type            | Description                                                                      |
| ----------------------- | --------------- | -------------------------------------------------------------------------------- |
| `status`                | string          | Current KYC status: `pending`, `in_progress`, `approved`, `retry`, or `rejected` |
| `verified_at`           | integer or null | Approval timestamp (epoch milliseconds)                                          |
| `rejected_at`           | integer or null | Rejection timestamp (epoch milliseconds)                                         |
| `started_at`            | integer or null | When verification was initiated (epoch milliseconds)                             |
| `personal_info`         | object or null  | Identity information extracted from documents                                    |
| `documents`             | array           | Submitted documents with metadata and image references                           |
| `verification_complete` | boolean         | Whether all required documents have been submitted                               |
| `verification_passed`   | boolean         | Whether verification passed all checks                                           |
| `rejection`             | object or null  | Rejection details, if applicable                                                 |

### Personal Info

| Field                  | Type   | Description                               |
| ---------------------- | ------ | ----------------------------------------- |
| `first_name`           | string | First name from identity document         |
| `last_name`            | string | Last name from identity document          |
| `date_of_birth`        | string | Date of birth (YYYY-MM-DD)                |
| `nationality`          | string | Nationality (ISO 3166-1 alpha-3)          |
| `country_of_residence` | string | Country of residence (ISO 3166-1 alpha-3) |

### Documents

| Field           | Type             | Description                                                            |
| --------------- | ---------------- | ---------------------------------------------------------------------- |
| `document_type` | string           | Type of document: `PASSPORT`, `ID_CARD`, `DRIVERS`, `RESIDENCE_PERMIT` |
| `country`       | string           | Issuing country (ISO 3166-1 alpha-3)                                   |
| `status`        | string           | Document verification status                                           |
| `submitted_at`  | integer or null  | Submission timestamp (epoch milliseconds)                              |
| `image_ids`     | array of strings | Image identifiers for fetching document images                         |

### Rejection

| Field       | Type    | Description                                                      |
| ----------- | ------- | ---------------------------------------------------------------- |
| `can_retry` | boolean | `true` if the user can resubmit, `false` for terminal rejections |
| `message`   | string  | Human-readable rejection reason                                  |

## Step 4: Fetch Document Images

Document images are fetched individually using the `image_ids` from the KYC details response.

```bash theme={null}
curl https://sis.sumvin.com/v0/users/user-abc123/kyc/document/img-abc123 \
  -H "Authorization: Bearer <your-api-key>" \
  -H "x-sumvin-pint-token: <pint-jwt>" \
  --output document.jpg
```

<Warning>
  The response is binary image data (`image/jpeg`, `image/png`, etc.), not JSON. Set your HTTP client to handle binary responses.
</Warning>

* Response includes `Cache-Control: private, max-age=300`
* Images are streamed directly from the upstream provider
* Content type is set in the `Content-Type` response header

## Complete Example

```python theme={null}
import httpx

BASE = "https://sis.sumvin.com"
HEADERS = {
    "Authorization": "Bearer <your-api-key>",
    "x-sumvin-pint-token": "<pint-jwt>",
}

# 1. Get KYC details
kyc = httpx.get(f"{BASE}/v0/users/{user_id}/kyc", headers=HEADERS).json()

# 2. Check status
if kyc["status"] != "approved":
    print(f"KYC not approved: {kyc['status']}")

# 3. Download document images
for doc in kyc["documents"]:
    for image_id in doc["image_ids"]:
        resp = httpx.get(
            f"{BASE}/v0/users/{user_id}/kyc/document/{image_id}",
            headers=HEADERS,
        )
        with open(f"{image_id}.jpg", "wb") as f:
            f.write(resp.content)
```

## Error Handling

All errors follow [RFC 7807 Problem Details](/introduction#error-responses):

| Status | Code           | Meaning                                                 | Action                                    |
| ------ | -------------- | ------------------------------------------------------- | ----------------------------------------- |
| 401    | `PINT-401-003` | Missing `x-sumvin-pint-token` header                    | Include a valid PINT token                |
| 401    | `PINT-401-004` | Invalid or malformed PINT token                         | Check token format and expiry             |
| 401    | `PINT-401-006` | The PINT behind this token was revoked by the user      | Request new consent from the user         |
| 403    | `PINT-403-003` | PINT token missing `sr:us:pint:identity:kyc_read` scope | Request token with correct scope          |
| 403    | `SIS-403-001`  | API key missing `get_kyc` scope                         | Contact account manager for scope upgrade |
| 404    | `SRI-404-001`  | User not found                                          | Verify `user_id` is correct               |
| 404    | `KYC-404-001`  | No KYC record for user                                  | User has not started verification         |
| 502    | `KYC-502-001`  | Upstream provider unavailable                           | Retry after short delay                   |

## Next Steps

| Concern        | Where to go                                    | When                                              |
| -------------- | ---------------------------------------------- | ------------------------------------------------- |
| Scope catalog  | [Scopes reference](/identity/scopes)           | When scoping what a PINT may do                   |
| SIS auth       | [SIS authentication](/identity/authentication) | When provisioning API keys                        |
| Token exchange | [Token exchange](/identity/token-exchange)     | When minting the PINT JWTs this endpoint consumes |
