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

# API Integration Guide

> Integrate iframe-based verification into your product with the Partner API.

The Partner API lets you run verification inside your own product. Your user verifies an account in a secured, iframe-based browser session, and you receive cryptographically attested proof of the result. Credentials never reach Cr3dentials servers.

This guide covers the end-to-end flow. For exact request and response schemas, use the interactive [API Reference](/api-reference/introduction).

## Authentication

Every Partner API request authenticates with your API key:

```
x-api-key: your_api_key_here
```

Or with a bearer token:

```
Authorization: Bearer your_api_key_here
```

Requests with a body must send `Content-Type: application/json`. See [Authentication](/authentication) for full detail.

## Response envelope

Successful responses are wrapped in a standard envelope:

```json theme={null}
{
  "status": "success",
  "data": { }
}
```

Errors return the matching HTTP status with `{ "statusCode", "message" }`.

## The integration flow

<Steps>
  <Step title="List available platforms">
    Call `GET /partner/browser-platforms` to get the platforms you can verify. Use a platform's `id` as `platformId` when creating a session.
  </Step>

  <Step title="Pick the applicant's country">
    Call `GET /partner/supported-countries` for the list of supported countries. Add `?country=ZA` for its regions, and `?country=ZA&region=gauteng` for its cities. Use these values for `location`.
  </Step>

  <Step title="Create a browser session">
    `POST /partner/browser-session` with a `platformId` and a **required** `location` (where your applicant is). Optionally set `receiverData`, `expiresInHours`, `externalReferenceId`, `preferredRegion`, and `generateAttestation`. To have Cr3dentials send the verification link to your applicant, also set `notificationPlatformId` (plus optional `senderName`/`emailTemplateId`). You receive an `embedUrl` and the resolved `location`.
  </Step>

  <Step title="Embed the session">
    Load the `embedUrl` in an iframe. The user logs in and completes verification inside the isolated browser.
  </Step>

  <Step title="Receive the result">
    Either poll `GET /partner/browser-session/{id}` or register a [webhook](/essentials/webhooks) in the Partner Portal to be notified when the session reaches a terminal status. On success you get `extractedData` (and `hasAttestation: true` when `generateAttestation` was set).
  </Step>
</Steps>

```bash theme={null}
curl -X POST https://app.cr3dentials.xyz/v1/partner/browser-session \
  -H "x-api-key: $CR3D_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platformId": 1,
    "receiverData": { "name": "John Doe", "email": "john@example.com" },
    "location": { "country": "ZA", "city": "johannesburg" },
    "expiresInHours": 24,
    "generateAttestation": true,
    "externalReferenceId": "user_abc123"
  }'
```

<Tip>
  Want Cr3dentials to email or WhatsApp the verification link for you? Call
  `GET /partner/notification-platforms` for the available channels, then pass a
  channel's `id` as `notificationPlatformId` along with a contact in `receiverData`
  — optionally with `senderName` (your business name). For email channels, call
  `GET /partner/email-templates` and pass an approved template's `id` as
  `emailTemplateId`. Omit all of this to deliver the `embedUrl` yourself.
</Tip>

<Warning>
  **`location` is required.** Set it to where your applicant actually is (`country` as an
  ISO-3166 alpha-2 code, plus optional `region`/`city`). The verification browser then runs
  from a residential IP in that country, so the provider sign-in looks like it came from your
  user — not a foreign datacenter. Use only values returned by `GET /partner/supported-countries`.
</Warning>

## Session lifecycle

A session moves through these statuses. Poll the session or use [webhooks](/essentials/webhooks) to track it.

| Status            | Description                                                  |
| ----------------- | ------------------------------------------------------------ |
| `CREATED`         | Session created, browser environment not yet assigned.       |
| `INITIALIZING`    | Browser environment spinning up.                             |
| `READY`           | Browser ready, waiting for the user to connect.              |
| `CONNECTED`       | User connected via iframe and can interact with the browser. |
| `LOADING_TREE`    | Session agent is loading the verification workflow.          |
| `RUNNING`         | Executing verification steps.                                |
| `AWAITING_USER`   | Waiting for user action (login, 2FA, security questions).    |
| `COLLECTING_DATA` | Extracting account data after successful login.              |
| `VERIFYING`       | Generating cryptographic attestation.                        |

**Terminal statuses:** `COMPLETED`, `PARTIAL_COMPLETE`, `ERROR`, `CANCELLED`, `TERMINATED`. A webhook is delivered when any terminal status is reached.

<Note>
  `GET /partner/browser-session/{id}` never returns the full attestation object. The
  `hasAttestation` flag indicates a cryptographic proof exists for the session.
</Note>

## Debugging failed sessions

When a session ends in `ERROR`, fetch a video recording of the browser to see what your
applicant encountered.

```bash theme={null}
curl https://app.cr3dentials.xyz/v1/partner/browser-session/{id}/recording \
  -H "x-api-key: $CR3D_API_KEY"
```

The response reports the recording's processing `status`. Once it is `completed`,
`recordingUrl` holds a presigned MP4 link:

```json theme={null}
{
  "status": "success",
  "data": {
    "status": "completed",
    "recordingUrl": "https://.../recording.mp4?X-Amz-Signature=...",
    "error": null
  }
}
```

<Note>
  Recordings are only available for sessions in the `ERROR` state. The `recordingUrl` is
  presigned and expires about 7 days after it is issued, so fetch it when you need it rather
  than storing it. If `status` is `pending` or `in_progress`, the recording is still
  processing — poll again shortly.
</Note>

## Next steps

<CardGroup cols={2}>
  <Card title="API Reference" icon="code" href="/api-reference/introduction">
    Every endpoint, parameter, and schema with interactive examples.
  </Card>

  <Card title="Webhooks" icon="bell" href="/essentials/webhooks">
    Receive verification results in real time.
  </Card>

  <Card title="Rate limits" icon="gauge" href="/essentials/rate-limits">
    Limits and how to handle them.
  </Card>

  <Card title="Authentication" icon="key" href="/authentication">
    API key headers and key management.
  </Card>
</CardGroup>
