Compatibility API (/v1) server identity
POST /v1/identify · operationId compatIdentify
For developers: your server sends this request with a server key; it is not a button in the dashboard.
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.
Associates server-verified userId and/or accountId (each at most 512 characters). Success is exactly {"status":"accepted"}. Replacing an established identity returns 409 session_reinit_required. No automatic retries. The request body is closed: sessionToken with userId (and optional accountId), or sessionToken with accountId alone.
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.
Request body
Content-Type: application/json (required)
- Shape 1 of 2
sessionToken(string, required) · minLength 1, pattern\S: Browser SDK session token. Missing, empty or non-string is 400 bad_request; malformed, over 250 characters, shaped like a key or not signed by this collector is 401 unauthorized; a token this collector issued whose session expired, was revoked or was removed is 409 session_reinit_required.userId(string, required) · minLength 1, maxLength 512, pattern\SaccountId(string, optional) · minLength 1, maxLength 512, pattern\S- Shape 2 of 2
sessionToken(string, required) · minLength 1, pattern\S: Browser SDK session token. Missing, empty or non-string is 400 bad_request; malformed, over 250 characters, shaped like a key or not signed by this collector is 401 unauthorized; a token this collector issued whose session expired, was revoked or was removed is 409 session_reinit_required.accountId(string, required) · minLength 1, maxLength 512, pattern\S
{
"sessionToken": "PASTE_BROWSER_SESSION_TOKEN",
"userId": "usr_123",
"accountId": "acct_456"
}Responses
- 200: Accepted · body
object - 400: The request is invalid (invalid JSON, an unknown property, a missing or empty sessionToken, an invalid actionId or ID, or a body over 131072 bytes). Fix the request before sending it again. · body
BadRequestError - 401: The server key is missing, invalid or not sent with the Bearer scheme, or the session token is invalid: malformed, over 250 characters, shaped like a key, or not signed by this collector. Check the key, then replace only the session token. · body
UnauthorizedError - 403: The server key and session token belong to different Sites, or the call came from a browser page on the public collector origin. · body
ForbiddenError - 404: Unknown path or wrong method. · body
NotFoundError - 409: The session token was issued by this collector but can no longer be verified: its session expired, was revoked (for example on consent withdrawal) or was removed, or identify tried to replace an established identity. Start a new browser session and get a new token; do not resend the old one. · body
SessionReinitRequiredError - 429: Too many requests from one client IP. Wait for Retry-After. · body
RateLimitedError· headersRetry-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
status("accepted", 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 explains each code and what to do.
Example
/v1/identifyServer key · run it from your backendEdit the JSON and the examples below update. Nothing is sent from this page.
curl -sS -X POST 'https://app.trytelltale.dev/v1/identify' \
-H "Authorization: Bearer $TELLTALE_SERVER_KEY" \
-H 'Content-Type: application/json' \
--data '{"sessionToken":"PASTE_BROWSER_SESSION_TOKEN","userId":"usr_123","accountId":"acct_456"}'const response = await fetch("https://app.trytelltale.dev/v1/identify", {
method: "POST",
headers: {
Authorization: 'Bearer ' + process.env.TELLTALE_SERVER_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
"sessionToken": "PASTE_BROWSER_SESSION_TOKEN",
"userId": "usr_123",
"accountId": "acct_456"
}),
signal: AbortSignal.timeout(5000)
});
const result = await response.json();Machine-readable contract: openapi.json. Request builder: the API explorer shows every operation as curl; it sends requests only on a local dashboard.