> ## 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.

# Overview

> Understand the v2 response envelope, endpoint families, errors, versioning, and migration path from v1.

API v2 is the recommended Dock API for new projects. It keeps the same core product model as v1 while improving consistency, bulk behavior, caching, error handling, and response metadata.

## Endpoint families

<Columns cols={2}>
  <Card title="Lookups" icon="search">
    Resolve Discord IDs, Roblox IDs, verification status, and Premium alt detection.
  </Card>

  <Card title="Bulk lookups" icon="list">
    Send arrays of IDs and receive ordered per-item results.
  </Card>

  <Card title="Verification sessions" icon="shield">
    Create sessions, redirect users, and read completion by polling or SSE.
  </Card>

  <Card title="Writes" icon="pencil">
    Update links, remove links, and delete data in your API-key scope.
  </Card>
</Columns>

## Response envelope

Every v2 JSON response uses one shape.

<Tabs>
  <Tab title="Success">
    ```json theme={null}
    {
      "status": 200,
      "data": {
        "discordId": "123456789012345678",
        "robloxId": "156319135",
        "resolved": {
          "roblox": null,
          "discord": null
        }
      },
      "meta": {
        "requestId": "req_abc123",
        "version": "2.0.0",
        "rateLimit": {
          "limit": 1,
          "remaining": 0,
          "resetAt": "2026-05-07T00:00:01.000Z",
          "retryAfter": null,
          "scope": "api_key",
          "bucket": "second"
        },
        "tier": "free"
      },
      "timestamp": "2026-05-07T00:00:00.000Z"
    }
    ```
  </Tab>

  <Tab title="Error">
    ```json theme={null}
    {
      "status": 404,
      "error": {
        "code": "LINK_NOT_FOUND",
        "message": "No linked Roblox account was found for that Discord ID.",
        "details": null
      },
      "meta": {
        "requestId": "req_abc123",
        "version": "2.0.0",
        "rateLimit": {
          "limit": 1,
          "remaining": 0,
          "resetAt": "2026-05-07T00:00:01.000Z",
          "retryAfter": null,
          "scope": "api_key",
          "bucket": "second"
        }
      },
      "timestamp": "2026-05-07T00:00:00.000Z"
    }
    ```
  </Tab>
</Tabs>

## Envelope fields

<ResponseField name="status" type="number" required>
  HTTP status code mirrored in the response body.
</ResponseField>

<ResponseField name="data" type="object | array | null">
  Successful response payload. Present when the request succeeds.
</ResponseField>

<ResponseField name="error.code" type="string">
  Stable machine-readable error code. Present when the request fails.
</ResponseField>

<ResponseField name="error.message" type="string">
  Human-readable error message safe to log or show in developer tooling.
</ResponseField>

<ResponseField name="meta.requestId" type="string" required>
  Request ID for support, logs, and debugging.
</ResponseField>

<ResponseField name="meta.version" type="string" required>
  v2 implementation version. Current value is `2.0.0`.
</ResponseField>

<ResponseField name="meta.rateLimit" type="object" required>
  Active rate-limit context when available.
</ResponseField>

<ResponseField name="timestamp" type="string" required>
  ISO 8601 timestamp generated by Dock.
</ResponseField>

## Common error codes

| Code                     | Meaning                                                   |
| ------------------------ | --------------------------------------------------------- |
| `BAD_REQUEST`            | The request could not be parsed or understood.            |
| `MISSING_PARAMETER`      | A required query, path, or body value is missing.         |
| `INVALID_PARAMETER`      | A supplied value has the wrong format.                    |
| `INVALID_BODY`           | The JSON body is missing or invalid.                      |
| `INVALID_API_KEY`        | The API key is missing, invalid, expired, or revoked.     |
| `INVALID_SESSION`        | The dashboard session is missing or expired.              |
| `FORBIDDEN`              | The key or session does not have access.                  |
| `PREMIUM_REQUIRED`       | Premium access is required.                               |
| `LINK_NOT_FOUND`         | No matching account link exists.                          |
| `SESSION_NOT_FOUND`      | The verification session does not exist for this key.     |
| `SESSION_EXPIRED`        | The verification session expired.                         |
| `RATE_LIMITED`           | The key or route is temporarily limited.                  |
| `SHARED_IP_RATE_LIMITED` | Shared IP or origin abuse protection limited the request. |
| `BULK_LIMIT_EXCEEDED`    | The request exceeded a bulk input limit.                  |
| `CONFLICT`               | The request conflicts with existing state.                |
| `INTERNAL_ERROR`         | Dock could not complete the request.                      |

## Versioning

Use the URL version for API routing:

```text theme={null}
/v2/discord
/v2/roblox
/v2/sessions
```

Dock also supports a dated contract header for compatible routes:

```http theme={null}
Dock-Version: 2026-01-01
```

If the header is omitted, Dock currently defaults to `2026-01-01`.

## v1 migration notes

<AccordionGroup>
  <Accordion title="Responses">
    v1 returns route-specific response shapes. v2 always returns `status`, `data` or `error`, `meta`, and `timestamp`.
  </Accordion>

  <Accordion title="Errors">
    v1 error messages can vary by route. v2 uses stable error codes for client
    logic.
  </Accordion>

  <Accordion title="Resolved data">
    v2 makes `resolved` explicit and defaults it to `false`. Request
    `resolved=true` only when you need expanded profiles.
  </Accordion>

  <Accordion title="Bulk">
    v2 bulk endpoints use `POST` bodies, preserve input order, and return per-item errors instead of failing the whole request for missing links.
  </Accordion>
</AccordionGroup>

<Note>
  v1 remains available for existing integrations. New work should use v2 unless
  you are maintaining an older client.
</Note>
