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

# Verification Sessions

> Create v2 verification sessions, redirect users, and read completion through polling or Server-Sent Events.

Verification sessions let your app start a Dock verification flow and receive the completed Discord to Roblox link without webhooks.

## Flow

<Steps>
  <Step title="Create a session">
    Call `POST /v2/sessions` with your `pid`, your internal `clientId`, and optional `guildId`.
  </Step>

  <Step title="Redirect the user">
    Send the user to `data.verifyUrl`.
  </Step>

  <Step title="Wait for completion">
    Read `GET /v2/sessions/:id?wait=25` or open `GET /v2/sessions/:id/stream`.
  </Step>

  <Step title="Store the result">
    When `status` becomes `completed`, store `result.discordId`, `result.robloxId`, and your original `clientId`.
  </Step>
</Steps>

```mermaid theme={null}
sequenceDiagram
  participant App
  participant Dock
  participant User

  App->>Dock: POST /v2/sessions
  Dock-->>App: id, clientId, verifyUrl
  App->>User: Redirect to verifyUrl
  User->>Dock: Complete verification
  App->>Dock: GET /v2/sessions/:id?wait=25
  Dock-->>App: completed result
```

## Create a session

```http theme={null}
POST /v2/sessions
```

<ParamField body="pid" type="string" required>
  Public Identifier attached to your API key. The `pid` must belong to the authenticated API key.
</ParamField>

<ParamField body="clientId" type="string" required>
  Your internal user, session, or checkout ID. Dock returns it with the session so you can map completion back to your system.
</ParamField>

<ParamField body="guildId" type="string">
  Optional Discord guild ID for flows that need guild context.
</ParamField>

<ParamField header="Idempotency-Key" type="string">
  Optional key for safely retrying session creation with the same body.
</ParamField>

```bash cURL theme={null}
curl --request POST \
  --url "https://api.docksys.xyz/v2/sessions" \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: verify-user-123" \
  --data '{
    "pid": "PID-ABC12345",
    "clientId": "user_123",
    "guildId": "987654321098765432"
  }'
```

```json 200 OK theme={null}
{
  "status": 200,
  "data": {
    "id": "vsn_A1b2C3d4E5f6G7h8J9k0L1",
    "pid": "PID-ABC12345",
    "clientId": "user_123",
    "guildId": "987654321098765432",
    "status": "pending",
    "statusReason": null,
    "expiresAt": "2026-05-07T00:05:00.000Z",
    "verifyUrl": "https://api.docksys.xyz/v2/verifications/discord?pid=PID-ABC12345&sid=vsn_A1b2C3d4E5f6G7h8J9k0L1",
    "reusedExisting": false
  },
  "meta": {
    "requestId": "req_abc123",
    "version": "2.0.0"
  },
  "timestamp": "2026-05-07T00:00:00.000Z"
}
```

## Read a session

```http theme={null}
GET /v2/sessions/:id
```

<ParamField path="id" type="string" required>
  Session ID returned as `data.id` by session creation.
</ParamField>

<ParamField query="wait" type="number">
  Optional long-poll wait in seconds. Maximum `25`.
</ParamField>

```bash Long-poll theme={null}
curl --request GET \
  --url "https://api.docksys.xyz/v2/sessions/vsn_A1b2C3d4E5f6G7h8J9k0L1?wait=25" \
  --header "Authorization: Bearer YOUR_API_KEY"
```

## Stream a session

```http theme={null}
GET /v2/sessions/:id/stream
```

The stream uses Server-Sent Events and sends `session` events. The connection closes when the session reaches a terminal state or after the stream limit.

```javascript Browser or Node SSE theme={null}
const source = new EventSource(
  "https://api.docksys.xyz/v2/sessions/vsn_A1b2C3d4E5f6G7h8J9k0L1/stream",
);

source.addEventListener("session", (event) => {
  const session = JSON.parse(event.data);

  if (session.status === "completed") {
    console.log(session.result);
    source.close();
  }
});
```

<Note>
  Browser `EventSource` cannot set custom Authorization headers. If you need API-key auth from a browser, proxy the stream through your backend.
</Note>

## Session states

| State       | Meaning                                                      |
| ----------- | ------------------------------------------------------------ |
| `pending`   | The user has not completed verification yet.                 |
| `completed` | Verification completed and `result` is populated.            |
| `expired`   | The session reached its 5-minute lifetime before completion. |

## Completed result

```json Completed session theme={null}
{
  "id": "vsn_A1b2C3d4E5f6G7h8J9k0L1",
  "pid": "PID-ABC12345",
  "clientId": "user_123",
  "guildId": "987654321098765432",
  "status": "completed",
  "statusReason": null,
  "createdAt": "2026-05-07T00:00:00.000Z",
  "expiresAt": "2026-05-07T00:05:00.000Z",
  "terminalAt": "2026-05-07T00:01:12.000Z",
  "verifyUrl": "https://api.docksys.xyz/v2/verifications/discord?pid=PID-ABC12345&sid=vsn_A1b2C3d4E5f6G7h8J9k0L1",
  "result": {
    "discordId": "123456789012345678",
    "robloxId": "156319135",
    "verifiedAt": "2026-05-07T00:01:12.000Z",
    "linkChanged": false,
    "previousRobloxId": null,
    "linkVersion": 1,
    "linkHash": "sha256-link-marker"
  }
}
```

<ResponseField name="result.linkChanged" type="boolean">
  `true` when the same Discord user was previously linked to a different Roblox account in your PID dataset.
</ResponseField>

<ResponseField name="result.previousRobloxId" type="string | null">
  Previous Roblox ID when `linkChanged` is `true`.
</ResponseField>

## Limits

| Guardrail             | Value                      |
| --------------------- | -------------------------- |
| Session lifetime      | 5 minutes                  |
| Create burst          | 6 sessions                 |
| Create refill         | 1 session every 10 seconds |
| Minimum poll interval | 2 seconds                  |
| Maximum `wait`        | 25 seconds                 |
| Stream max duration   | 30 seconds                 |
| Free poll cap         | 60 polls                   |
| Premium poll cap      | 150 polls                  |
