> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.withverifa.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.withverifa.com/_mcp/server.

# Sessions

> The session lifecycle, statuses, and API operations.

A **session** represents a single verification attempt. Every interaction with
Verifa starts by creating a session — it tracks the user through capture,
processing, and the final decision.

> **Note**
>
> **Environment isolation**: Verifa keys are environment-scoped. A live key
> (`vk_live_*`) cannot fetch sandbox sessions (or identities/workflows) and
> vice versa — mismatched requests return 404. Use the matching key for the
> environment you want to query.

## Session lifecycle

```
pending → capturing → processing → completed
                                 → under_review
                                 → awaiting_external
          ↓
        expired
```

### Statuses

| Status              | Description                                                                         |
| ------------------- | ----------------------------------------------------------------------------------- |
| `pending`           | Created. Waiting for the user to open the capture URL.                              |
| `capturing`         | The user has started the capture flow and is uploading documents.                   |
| `processing`        | Capture is complete. The workflow engine is running checks.                         |
| `completed`         | All checks finished. See the session result for the decision.                       |
| `expired`           | The capture token expired before the user completed the flow (default: 20 minutes). |
| `failed`            | An unrecoverable error occurred during workflow execution.                          |
| `awaiting_external` | Workflow is paused at an external gate, waiting for your API callback.              |
| `under_review`      | The workflow flagged this session for manual human review.                          |
| `sandbox_pending`   | Sandbox session waiting for you to select an outcome.                               |

### Terminal vs. active statuses

**Active:** `pending`, `capturing`, `processing`, `awaiting_external`,
`under_review`, `sandbox_pending`

**Terminal:** `completed`, `expired`, `failed`

Once a session reaches a terminal status, its result is final and cannot change
(except through manual review of `under_review` sessions).

## Creating a session

```bash
curl -X POST https://api.withverifa.com/api/v1/sessions \
  -H "X-API-Key: vk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "external_ref": "user_abc123",
    "country": "US",
    "workflow_id": "workflow_custom_kyc",
    "metadata": {
      "plan": "premium",
      "signup_source": "mobile"
    },
    "redirect_url": "https://your-app.com/verify/complete"
  }'
```

### Request parameters

| Field            | Type    | Required | Description                                                                                                     |
| ---------------- | ------- | -------- | --------------------------------------------------------------------------------------------------------------- |
| `external_ref`   | string  | No       | Your internal user ID. Links the session to an identity.                                                        |
| `country`        | string  | No       | ISO 3166-1 alpha-2 country code. Scopes geo-dependent checks.                                                   |
| `workflow_id`    | string  | No       | Workflow to run. Uses the org default if omitted.                                                               |
| `metadata`       | object  | No       | Arbitrary key-value pairs stored with the session.                                                              |
| `redirect_url`   | string  | No       | URL to redirect the user to after capture completes.                                                            |
| `checks`         | array   | No       | Override the workflow's check list for this session.                                                            |
| `send_email`     | boolean | No       | Send the capture link to the user's email.                                                                      |
| `applicant_name` | string  | No       | Pre-fill the applicant name for the email.                                                                      |
| `fields`         | object  | No       | Pre-fill the capture form with known applicant data. See [Pre-filling capture data](#pre-filling-capture-data). |

### Response

```json
{
  "id": "session_abc123",
  "status": "pending",
  "capture_url": "https://app.withverifa.com/verify/tok_...",
  "qr_code_data_url": "data:image/png;base64,...",
  "is_sandbox": false,
  "created_at": "2026-02-01T12:00:00Z",
  "expires_at": "2026-02-01T12:20:00Z"
}
```

The `capture_url` contains a single-use token that expires after 20 minutes. The
`qr_code_data_url` is a base64-encoded PNG of the capture URL, useful for
displaying a QR code for mobile users.

## Pre-filling capture data

If you already know some applicant data — from a signup form, an internal CRM,
or a prior session — pass it under `fields` to seed the verification record.
Values are stored encrypted at rest and become available to risk signals and
workflow conditions.

```bash
curl -X POST https://api.withverifa.com/api/v1/sessions \
  -H "X-API-Key: vk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "wf_abc123",
    "external_ref": "user_42",
    "fields": {
      "first_name": "Jane",
      "last_name": "Doe",
      "date_of_birth": "1990-01-15",
      "email": "jane@example.com",
      "phone": "+15551234567",
      "ssn": "123-45-6789",
      "address_line1": "1 Main St",
      "address_city": "San Francisco",
      "address_state": "CA",
      "address_zip": "94103",
      "address_country": "US"
    }
  }'
```

| Field             | Type   | Description                                                   |
| ----------------- | ------ | ------------------------------------------------------------- |
| `first_name`      | string | Applicant's first name.                                       |
| `last_name`       | string | Applicant's last name.                                        |
| `date_of_birth`   | string | ISO 8601 date (`YYYY-MM-DD`).                                 |
| `email`           | string | Email address.                                                |
| `phone`           | string | Phone number (E.164 recommended).                             |
| `ssn`             | string | US Social Security Number — 9 digits, dashes/spaces accepted. |
| `address_line1`   | string | Street address line 1.                                        |
| `address_line2`   | string | Street address line 2.                                        |
| `address_city`    | string | City.                                                         |
| `address_state`   | string | State or subdivision.                                         |
| `address_zip`     | string | Postal code.                                                  |
| `address_country` | string | ISO 3166-1 alpha-2 country code.                              |

> **Note**
>
> Pre-filling does **not** skip capture steps. The applicant still completes the
> capture flow; pre-filled values feed risk signals and workflow conditions, and
> will populate the form as it's rendered.

## Field name aliases

To ease migration from other identity platforms, `POST /api/v1/sessions`
accepts alternative names for every parameter and inside `fields`. Like the
rest of the Verifa API, you can send keys in `snake_case`, `kebab-case`, or
`camelCase` — they're all normalised internally. The endpoint also accepts a
JSON:API-style envelope (`{"data": {"attributes": {...}}}`) — the inner
`attributes` object is treated as the request body, and any sibling keys
outside `attributes` are ignored.

```bash
curl -X POST https://api.withverifa.com/api/v1/sessions \
  -H "X-API-Key: vk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "type": "inquiry",
      "attributes": {
        "inquiry-template-id": "wf_abc123",
        "reference-id": "user_42",
        "fields": {
          "name-first": "Jane",
          "name-last": "Doe",
          "birthdate": "1990-01-15",
          "email-address": "jane@example.com",
          "phone-number": "+15551234567",
          "social-security-number": "123-45-6789",
          "address-street-1": "1 Main St",
          "address-city": "San Francisco",
          "address-subdivision": "CA",
          "address-postal-code": "94103",
          "address-country-code": "US"
        }
      }
    }
  }'
```

### Alias reference

| Canonical                | Alias                           |
| ------------------------ | ------------------------------- |
| `workflow_id`            | `inquiry-template-id`           |
| `external_ref`           | `reference-id`                  |
| `fields.first_name`      | `fields.name-first`             |
| `fields.last_name`       | `fields.name-last`              |
| `fields.date_of_birth`   | `fields.birthdate`              |
| `fields.email`           | `fields.email-address`          |
| `fields.phone`           | `fields.phone-number`           |
| `fields.ssn`             | `fields.social-security-number` |
| `fields.address_line1`   | `fields.address-street-1`       |
| `fields.address_line2`   | `fields.address-street-2`       |
| `fields.address_city`    | `fields.address-city`           |
| `fields.address_state`   | `fields.address-subdivision`    |
| `fields.address_zip`     | `fields.address-postal-code`    |
| `fields.address_country` | `fields.address-country-code`   |

Responses always use the canonical shape regardless of which payload form you
send.

## Listing sessions

```bash
curl "https://api.withverifa.com/api/v1/sessions?status=completed&limit=25&offset=0" \
  -H "X-API-Key: vk_live_your_key_here"
```

### Filters

| Parameter | Type    | Description                                   |
| --------- | ------- | --------------------------------------------- |
| `status`  | string  | Filter by session status.                     |
| `limit`   | integer | Max results per page (default: 50, max: 100). |
| `offset`  | integer | Number of items to skip.                      |

### Response

```json
{
  "data": [...],
  "pagination": {
    "total": 142,
    "limit": 25,
    "offset": 0
  }
}
```

## Retrieving a session

```bash
curl https://api.withverifa.com/api/v1/sessions/session_abc123 \
  -H "X-API-Key: vk_live_your_key_here"
```

Returns the full session object including status, metadata, tags, and linked
review case information.

## Session operations

### Resume an expired session

Re-issue a capture token for an expired or abandoned session:

```bash
curl -X POST https://api.withverifa.com/api/v1/sessions/session_abc123/resume \
  -H "X-API-Key: vk_live_your_key_here"
```

Returns a new `capture_url` with a fresh token. The original documents and
progress are preserved.

### Expire a session manually

Force-expire an active session:

```bash
curl -X POST https://api.withverifa.com/api/v1/sessions/session_abc123/expire \
  -H "X-API-Key: vk_live_your_key_here"
```

### Reprocess a session

Re-run the verification workflow on a completed session:

```bash
curl -X POST https://api.withverifa.com/api/v1/sessions/session_abc123/reprocess \
  -H "X-API-Key: vk_live_your_key_here"
```

Useful after updating workflow rules — the original documents are re-evaluated
against the current workflow configuration.

### Update metadata

```bash
curl -X PATCH https://api.withverifa.com/api/v1/sessions/session_abc123 \
  -H "X-API-Key: vk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "external_ref": "updated_user_id",
    "metadata": { "tier": "gold" }
  }'
```

### View documents

Retrieve signed URLs for the uploaded documents:

```bash
curl https://api.withverifa.com/api/v1/sessions/session_abc123/documents \
  -H "X-API-Key: vk_live_your_key_here"
```

```json
{
  "data": [
    {
      "doc_type": "id_front",
      "mime_type": "image/jpeg",
      "url": "https://api.withverifa.com/.../id_front?expires=...&sig=...",
      "expires_in": 300
    },
    {
      "doc_type": "selfie",
      "mime_type": "image/jpeg",
      "url": "https://api.withverifa.com/.../selfie?expires=...&sig=...",
      "expires_in": 300
    }
  ]
}
```

Document URLs are HMAC-signed and expire after 5 minutes (configurable). See
[Data Access](/api-details/data-access) for details.

### View risk assessment

```bash
curl https://api.withverifa.com/api/v1/sessions/session_abc123/risk \
  -H "X-API-Key: vk_live_your_key_here"
```

Returns the fraud signal assessment including risk score, risk level, and
triggered signals. See [Fraud Signals](/best-practices/fraud-signals) for details.

## Session result

The session result is a separate object containing the verification outcome.
Fetch it after the session reaches `completed` or `under_review`:

```bash
curl https://api.withverifa.com/api/v1/sessions/session_abc123/result \
  -H "X-API-Key: vk_live_your_key_here"
```

### Result statuses

| Status         | Description                                          |
| -------------- | ---------------------------------------------------- |
| `passed`       | All checks passed. Approved automatically.           |
| `failed`       | One or more checks failed. Rejected by the workflow. |
| `needs_review` | Requires manual review before a decision.            |
| `approved`     | Approved by a human reviewer.                        |
| `rejected`     | Rejected by a human reviewer.                        |
| `error`        | A processing error occurred.                         |

## Data subject access export

Export all decrypted PII and document URLs for a session in a single JSON
document — used to satisfy GDPR Article 15 access requests:

```bash
curl https://api.withverifa.com/api/v1/sessions/session_abc123/export \
  -H "X-API-Key: vk_live_your_key_here"
```

Documents in the export include 24-hour TTL signed download URLs. The call is
audit-logged as `api.session.export`. See [Data Access](/api-details/data-access) for
the equivalent identity-level export.

## Session redaction

Delete all PII and document images for a session:

```bash
curl -X DELETE https://api.withverifa.com/api/v1/sessions/session_abc123/data \
  -H "X-API-Key: vk_live_your_key_here"
```

Redaction is permanent and irreversible. See [Data Retention](/api-details/data-retention)
for automatic retention policies and GDPR compliance.

## Webhooks

Sessions fire these webhook events:

| Event                       | When                                          |
| --------------------------- | --------------------------------------------- |
| `session.created`           | Session was created.                          |
| `session.started`           | User opened the capture URL.                  |
| `session.expired`           | Capture token expired.                        |
| `session.approved`          | Session was approved (auto or manual).        |
| `session.declined`          | Session was rejected.                         |
| `session.requires-review`   | Session needs manual review.                  |
| `session.awaiting_external` | Workflow paused at external gate.             |
| `session.redacted`          | PII and documents were permanently deleted.   |
| `session.retention-expired` | Retention window elapsed; data auto-redacted. |

## Related

* [Verifications & Checks](/core-concepts/verifications-checks) — What checks run
  during a session
* [Workflows](/core-concepts/workflows) — How verification steps are orchestrated
* [Identities](/core-concepts/identities) — How sessions link to persistent identity
  records