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

# Create and Manage Verification Links

> Create single-use verification links to share via email, WhatsApp, SMS, or QR code and monitor verification status in real time.

A verification link is a single-use URL that launches the VU Identity Link experience on the end user's device. You create the link on your backend, share it through any channel, and then monitor the associated verification lifecycle through webhooks or polling.

## Link types

VU Identity Link supports two flow types:

| Type | Description | Use case |
| - | - | - |
| `FULL FLOW` | Document capture (front and back) followed by liveness detection and facial biometric comparison. | High-assurance identity verification, KYC onboarding. |
| `ID ONLY` | Document capture (front and back) only, without liveness or facial biometrics. | Low-friction document verification, age checks. |

## Create a link

Call `POST /links` with the flow type and optional configuration fields.

### Request body

```json theme={null}
{
  "type": "FULL FLOW",
  "callbackUrl": "https://your-app.com/callback",
  "externalUserId": "user-12345",
  "adaptiveFlow": true,
  "metadata": {
    "campaign": "summer-onboarding",
    "region": "LATAM"
  }
}
```

| Field | Type | Required | Description |
| - | - | - | - |
| `type` | string | Yes | `FULL FLOW` or `ID ONLY`. |
| `callbackUrl` | string | No | URL to redirect the user after completing the flow. |
| `externalUserId` | string | No | Your internal user identifier, echoed in webhooks and verification results. |
| `adaptiveFlow` | boolean | No | Lets this link skip document capture and re-verify a returning customer with a selfie alone. See [Adaptive flow](#adaptive-flow). |
| `metadata` | object | No | Arbitrary key-value pairs attached to the link and copied to the verification record. |

### Response

```json theme={null}
{
  "linkId": "550e8400-e29b-41d4-a716-446655440000",
  "linkUrl": "https://identity.vu-one.com/verify/550e8400-e29b-41d4-a716-446655440000",
  "verificationId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
}
```

| Field | Description |
| - | - |
| `linkId` | UUID of the link. Use it to query link details. |
| `linkUrl` | Share this URL with the end user. |
| `verificationId` | UUID of the verification session. Use it to poll status or read results. |

## Adaptive flow

Introduced in version 2.2.0, adaptive flow lets a customer who has verified before re-verify with **a selfie alone**, skipping the document capture.

`adaptiveFlow` is a tri-state field on `POST /links`:

| Value sent | Behavior |
| - | - |
| Omitted | Follows the company setting (`linkConfig.adaptiveFlow`), which is off unless you enable it. |
| `true` | This link may resolve to the selfie-only branch even when the company setting is off. |
| `false` | This link always runs the full document flow, even on a company that enabled the setting. |

<Warning>
  Omitting the field and sending `false` are **not** the same thing. `false` is an explicit override that guarantees the full document flow.
</Warning>

<Warning>
  `adaptiveFlow` requires `externalUserId` to have any effect. Without that identifier there is no way to look up the previous verification, and the link silently runs the full flow.
</Warning>

If you do not know the `externalUserId` at link creation, the user can supply it mid-flow through the public `PATCH /verifications/identify` endpoint. See [Identify a user mid-flow](/en/identity-link/kyc#identify-a-user-mid-flow).

The branch actually resolved for a verification is exposed as `method` on `GET /verifications/{id}/status?include=operationGuid`, with values `FACE` (adaptive branch) or `DOCUMENT` (full flow).

## Share the link

The `linkUrl` can be delivered through any channel:

* **Email**: Embed the URL in a verification email template.
* **WhatsApp / SMS**: Send the URL as a text message with a short explanation.
* **QR code**: Generate a QR code from `linkUrl` for in-person or kiosk scenarios.
* **In-app**: Deep-link into a mobile app that opens the URL in a web view.

<Tip>
  Links are single-use. Once a user opens the link and begins the flow, it cannot be reused by another person. If the user abandons the flow, create a new link.
</Tip>

## List and retrieve links

### List all links

```bash theme={null}
curl -X GET https://api.identity.vu-one.com/api/v1/links \
  -H "Authorization: Bearer <token>"
```

Returns an array of objects with the same shape as `GET /links/{id}`.

### Get a specific link

```bash theme={null}
curl -X GET https://api.identity.vu-one.com/api/v1/links/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer <token>"
```

```json theme={null}
{
  "_id": "550e8400-e29b-41d4-a716-446655440000",
  "verificationId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
  "active": true,
  "expiresAt": "2026-08-23T14:00:00Z",
  "createdAt": "2026-08-22T14:00:00Z",
  "callbackUrl": "https://your-app.com/callback",
  "externalUserId": "user-12345",
  "metadata": { "campaign": "summer-onboarding" },
  "defaultTemplateVersion": "2026-07-01",
  "adaptiveFlow": true,
  "company": {
    "name": "Acme Inc.",
    "antiSpoofing": true,
    "color": "#ff4e08",
    "plan": "PRO",
    "handoffMode": "suggest",
    "gateRules": {
      "version": "2026-07-01",
      "rules": [
        {
          "id": "ios-legacy",
          "reason": "unsupported_os",
          "match": { "formFactor": "mobile", "platform": "ios", "osVersionMax": "14" }
        }
      ]
    },
    "locationPermission": "optional"
  }
}
```

| Field | Type | Description |
| - | - | - |
| `_id` | uuid | Link identifier. |
| `verificationId` | uuid | Associated verification. |
| `active` | boolean | Whether the link is still usable. |
| `expiresAt` | date-time | Expiry timestamp. |
| `createdAt` | date-time | Creation timestamp. |
| `callbackUrl` | string | Configured redirect URL. |
| `externalUserId` | string | Your internal user identifier. |
| `metadata` | object | Metadata you sent at creation. |
| `defaultTemplateVersion` | string, nullable | Version of the globally active default gate-rule template. Global state, identical for every company. `null` when no template is active. |
| `adaptiveFlow` | boolean | The **resolved** branch for this link (`link.adaptiveFlow` if sent, otherwise the company setting). Never the tri-state value accepted by `POST /links`. |
| `company.name` | string | Company name. |
| `company.antiSpoofing` | boolean | Whether anti-spoofing checks are active. |
| `company.color` | string | Brand color. |
| `company.plan` | string | Subscribed plan. |
| `company.handoffMode` | string | Whether the company offers device hand-off and how insistently: `never`, `suggest`, or `require`. Defaults to `never`. |
| `company.gateRules` | object | Resolved, read-only rule set deciding which device cohorts are gated. Admin-managed, never accepted on a `PATCH`. |
| `company.locationPermission` | string | Effective location-permission policy: `never`, `optional`, or `required`. Always resolved server-side. |

<Note>
  `gateRules` is read-only. Each rule carries `id`, `reason`, and a `match` block with `formFactor`, `platform`, and `osVersionMax`.
</Note>

## Company configuration

Two company settings directly affect the links you create:

| Field | Default | Description |
| - | - | - |
| `linkConfig.expirationTime` | 1 | How long a new link stays valid. |
| `linkConfig.adaptiveFlow` | `false` | Whether links may resolve to the selfie-only branch when the link itself does not override it. |

Read and update both through `GET /users/me/company` and `PATCH /users/me/company`. When a link expires before use, any attempt to open it returns an error and you must create a new link.

## Code examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.identity.vu-one.com/api/v1/links \
    -H "Authorization: Bearer <token>" \
    -H "Content-Type: application/json" \
    -d '{
      "type": "FULL FLOW",
      "externalUserId": "user-12345",
      "adaptiveFlow": true,
      "callbackUrl": "https://your-app.com/callback"
    }'
  ```

  ```js JavaScript theme={null}
  const response = await fetch('https://api.identity.vu-one.com/api/v1/links', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer <token>',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      type: 'FULL FLOW',
      externalUserId: 'user-12345',
      adaptiveFlow: true,
      callbackUrl: 'https://your-app.com/callback',
    }),
  });

  const data = await response.json();
  console.log(data.linkUrl);
  ```
</CodeGroup>

## Next steps

* Query verification results after the user completes the flow in the [KYC Results](/en/identity-link/kyc) guide.
* Receive real-time notifications by setting up [Webhooks](/en/identity-link/webhooks).
* Understand biometric checks in the [Liveness](/en/identity-link/liveness) guide.


## Related topics

- [Identity Link API: Integration Guide](/en/identity-link/introduction.md)
- [Identity Link Webhooks: Verification Lifecycle Events](/en/identity-link/webhooks.md)
- [Quickstart: your first identity verification](/en/quickstart.md)
- [Identity Link API Error Codes and Responses](/en/identity-link/errors.md)
- [Authenticate with OAuth2 Client Credentials](/en/identity-link/authentication.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.