# KYC and Profile Data Requirements



A user must complete their profile before they can start identity verification or transact. Rather than tracking that yourself, ask Paytrie: `GET /v2/users/{userId}/requirements` returns every requirement with its status, and names the exact fields anything outstanding is waiting on. You submit those fields with `PATCH /v2/users/{userId}` and read the requirements again.

Use this page as a planning reference for what the requirements mean. The live response is what counts — which requirements apply varies by user, and the set changes as compliance rules change. Render whatever the API returns rather than hardcoding a list of steps.

## Before you start [#before-you-start]

These endpoints act on a specific user, so they need both credentials:

* Your API key, sent as `x-api-key`.
* An access token for that user, sent as `Authorization: Bearer`.

Create the user first with `POST /v2/users`, then obtain an access token for them through [Authentication](/v2/authentication) — send a login code to their email, and exchange the code they give you for a token. Tokens are valid for one hour.

<Callout type="warn">
  Calling these endpoints with only an API key returns `401 Authorization
    header missing or invalid`.
</Callout>

## Read a user's requirements [#read-a-users-requirements]

```bash
curl -X GET "https://api.paytrie.com/v2/users/550e8400-e29b-41d4-a716-446655440000/requirements" \
  -H "x-api-key: your-api-key" \
  -H "Authorization: Bearer <access-token>"
```

```json
{
  "success": true,
  "data": {
    "requirements": {
      "emailVerification": { "status": "satisfied", "requiredFields": [] },
      "personalInfo": { "status": "satisfied", "requiredFields": [] },
      "address": { "status": "satisfied", "requiredFields": [] },
      "occupation": { "status": "satisfied", "requiredFields": [] },
      "additionalInfo": {
        "status": "pending",
        "requiredFields": [
          "olderUserInfo.sourceOfFunds",
          "olderUserInfo.intendedUseOfUSDC",
          "olderUserInfo.walletProvider",
          "olderUserInfo.walletAddress",
          "olderUserInfo.howDidYouHear",
          "olderUserInfo.whoReferredYou",
          "olderUserInfo.previousCryptoExperience"
        ]
      },
      "kyc": { "status": "pending", "requiredFields": [] }
    }
  }
}
```

<Card title="API Reference: Get a user's requirements" href="/v2/api-reference/users/getUserRequirements" icon="arrow-right-left">
  View complete request parameters and response schema
</Card>

### Status [#status]

| Value        | Meaning                                                                                                  |
| ------------ | -------------------------------------------------------------------------------------------------------- |
| `pending`    | The user still has to act. Where the requirement is field-driven, `requiredFields` names what to submit. |
| `processing` | Paytrie is reviewing what was submitted. No action is needed from you or the user.                       |
| `satisfied`  | Nothing further is needed.                                                                               |

### Reason [#reason]

Some requirements carry a `reason` when the status alone does not say enough.

| Value                    | Meaning                                             |
| ------------------------ | --------------------------------------------------- |
| `documentUploadRequired` | Paytrie needs identity documents uploaded directly. |
| `manualReview`           | A person at Paytrie is reviewing the submission.    |
| `verificationFailed`     | Identity verification did not pass.                 |

### Required fields [#required-fields]

`requiredFields` lists what is still outstanding as dot-paths into the `PATCH /v2/users/{userId}` body, so you can submit them back exactly as they are returned. It is empty when a requirement is already satisfied, or when it is not field-driven — `kyc` is completed through the verification flow rather than by submitting fields.

## What each requirement means [#what-each-requirement-means]

| Requirement         | Satisfied by                                                                                                                                         |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `emailVerification` | Set automatically for users created through the API                                                                                                  |
| `phoneVerification` | Set automatically for users created through the API                                                                                                  |
| `disclosure`        | The integrator passing `false` for both `pep` and `tpd`, meaning the user is not a Politically Exposed Person and is not a Third-Party Determination |
| `personalInfo`      | `firstName`, `lastName`, `dob`                                                                                                                       |
| `address`           | `addressLine1`, `city`, `province`, `postalCode`                                                                                                     |
| `occupation`        | `occupation`                                                                                                                                         |
| `additionalInfo`    | The `olderUserInfo` fields, for users aged 50 or over at signup                                                                                      |
| `kyc`               | Completing identity verification, or importing a [reusable KYC result](/v2/integrations/sumsub-kyc)                                                  |
| `kycRefresh`        | Re-confirming details once the annual refresh window elapses                                                                                         |

`additionalInfo` is the one integrations meet unexpectedly. It applies only to users who were 50 or over when they signed up, and it blocks the KYC link until it is filled in — `GET /v2/users/{userId}/kyc-url` returns `422` while it is outstanding.

## Submit the outstanding fields [#submit-the-outstanding-fields]

Send whatever the requirements response named. Every field is optional, so you can submit them all at once or a few at a time.

```bash
curl -X PATCH "https://api.paytrie.com/v2/users/550e8400-e29b-41d4-a716-446655440000" \
  -H "x-api-key: your-api-key" \
  -H "Authorization: Bearer <access-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "olderUserInfo": {
      "sourceOfFunds": "Salary",
      "intendedUseOfUSDC": "Savings",
      "walletProvider": "MetaMask"
    }
  }'
```

Reading the requirements again narrows `requiredFields` to what is still missing:

```json
"additionalInfo": {
  "status": "pending",
  "requiredFields": [
    "olderUserInfo.walletAddress",
    "olderUserInfo.howDidYouHear",
    "olderUserInfo.whoReferredYou",
    "olderUserInfo.previousCryptoExperience"
  ]
}
```

Repeat until nothing is pending except `kyc`, then generate the verification link.

<Callout type="warn">
  Unknown or misplaced keys are rejected with a `422` rather than ignored.
  Submitting `sourceOfFunds` at the top level instead of nested under
  `olderUserInfo` returns `Unrecognized keys`, so a mistake fails loudly
  instead of appearing to succeed.
</Callout>

<Card title="API Reference: Update a user" href="/v2/api-reference/users/updateUser" icon="arrow-right-left">
  View complete request parameters and response schema
</Card>

## Updating a user's information [#updating-a-users-information]

`PATCH` is also how you update a user's details after they are created — for example when verification fails because an address no longer matches their identity document. Submit the corrected fields and generate a new verification link.
