# Compatibility API (/v1) session lookup

`GET /v1/sessions/{sessionId}` · operationId `compatGetSession`

For developers: your server sends this request with a server key; it is not a button in the dashboard. To see the same information without code, open **Sessions** in the dashboard.

> **Note:** This is the compatibility API (/v1): it keeps the request and response shapes of the v1 agent-verification API that existing integrations were built on, so such an integration works unchanged. New integrations should use the /api/v1 operations, which return reasons, decision, policy and attribution and work with the server adapter.

The v1 SessionResponse, exactly: {sessionId, status, identity, verdict}: status active or ended (consent withdrawn reads ended), verdict the action verdict (unknown after withdrawal), no score. Server key only, this Site only. Another Site’s session, an unknown, erased or deleted one and one past retention are all 404 session_not_found. Other methods are 405 (plain text, Allow: GET).

## Authentication

Send `Authorization: Bearer YOUR_SERVER_KEY` (siteServerKey: Site server key in Authorization: Bearer <key> (the scheme is case-insensitive and required; a bare key is 401). Shown once on creation or rotation. Publishable keys cannot authenticate). Keep the server key in server-only configuration; never send it to a browser.

## Parameters

- `sessionId` (path, string, required): The session ID the browser SDK returns (getSessionId()). A reference, not a credential.

## Responses

- **200**: Session result · body `CompatSession` · headers `Cache-Control`
- **400**: The session ID is malformed. · body `BadRequestError`
- **401**: The server key is missing, invalid or not sent with the Bearer scheme. · body `UnauthorizedError`
- **404**: The session is unknown, belongs to another Site, was erased or deleted, or is past its retention. Which one is never said. · body `SessionNotFoundError`
- **405**: Use GET (plain text; Allow: GET).
- **429**: Too many requests from one client IP. Wait for Retry-After. · body `RateLimitedError` · headers `Retry-After`
- **500**: The collector could not complete the request. Fail the protected action and do not retry automatically. · body `InternalError`
- **503**: A temporary Site configuration or browser session failure; the code names what is unavailable. Only verify may retry (three attempts, 0-250 ms then 0-500 ms jitter). · body `UnavailableBody`

### Success body fields

- `sessionId` (string, required)
- `status` ("active" | "ended", required)
- `identity` (CompatSessionUserIdentity | CompatSessionAccountIdentity | null, required)
- `verdict` ("human" | "agent" | "unknown", required)

Failures are not verdicts. Error bodies follow the `CompatError` schema: `error` is one of `bad_request`, `unauthorized`, `forbidden`, `not_found`, `session_reinit_required`, `rate_limited`, `internal_error`, `config_unavailable`, `session_unavailable`, `discovery_not_ready`, `discovery_unavailable`, `session_not_found`. [Errors and retries](/docs/errors) explains each code and what to do.

## Example

```sh tab=curl
curl -sS -X GET 'https://app.trytelltale.dev/v1/sessions/session_PASTE_SESSION_ID' \
  -H "Authorization: Bearer $TELLTALE_SERVER_KEY"
```

```js tab=fetch
const response = await fetch("https://app.trytelltale.dev/v1/sessions/session_PASTE_SESSION_ID", {
  method: "GET",
  headers: {
    Authorization: 'Bearer ' + process.env.TELLTALE_SERVER_KEY
  },
  signal: AbortSignal.timeout(5000)
});
const result = await response.json();
```

Machine-readable contract: [openapi.json](https://app.trytelltale.dev/openapi.json). Request builder: the [API explorer](/docs/api-explorer) shows every operation as curl; it sends requests only on a local dashboard.
