Retroactive Attack Insights API
The Retroactive Attack Insights (RAI) API delivers session intelligence from retrospectively detected bot attacks as a structured, programmatic feed. Use it to integrate RAI data directly into your SIEM, SOAR, data lake, or risk model without parsing CSV attachments from Zendesk tickets.
For an overview of the RAI feature itself, see the Retroactive Attack Insights Knowledge Base article.
Base URL
https://client-api.arkoselabs.comAll RAI API endpoints are prefixed with /api/rai/v1.
Versioning
The RAI API uses two version identifiers:
- URL version (
v1in the path) signals breaking changes to endpoints, request shapes, or authentication. - Schema version (
schema_versionfield in responses and objects, currentlyrai-v1) signals non-breaking additions. Consumers should tolerate new fields appearing in responses without a URL version bump.
Authentication
The RAI API uses the OAuth 2.0 client credentials flow, backed by Auth0.
Obtaining credentials
Create client_id and client_secret pair via Arkose Command Center. You can do this by navigating to the sidebar > Manage > API Access > Tokens > Create Token. Select Retroactive Attack Insights API.
Treat each client_secret like a password. Store credentials in a secret manager, never embed them in client-side code, and never commit them to source control.
Authenticating requests
- Exchange your
client_idandclient_secretfor an access token by callingPOST /api/rai/v1/authorize. - Send the returned
access_tokenas aBearertoken in theAuthorizationheader on every subsequent request. - Cache the token until it expires (
expires_inis returned in seconds), then re-authorise.
Pagination
List endpoints (List cohorts, List cohort sessions, List sessions) return cursor-paginated results. To iterate:
- Issue an initial request with your filters and (optionally) a
page_size(1-1000). - Read the result array from the response.
- If
next_page_tokenis present and non-empty, repeat the request withpage_tokenset to that value. - Stop when
next_page_tokenis empty or absent.
Filter and path parameters must not change between paginated requests. Treat next_page_token as opaque; do not parse or modify it.
Errors
All RAI API endpoints return errors using a consistent envelope:
{
"error": {
"code": "invalid_window",
"message": "to must be no more than 30 days after from",
"request_id": "req_01HE9G4Q2X8YJZK3M7N5P0RTAV"
}
}| Field | Type | Description |
|---|---|---|
error.code | string | Stable, machine-readable error code. Use for branching logic. |
error.message | string | Human-readable description. May change between releases. |
error.request_id | string | Unique identifier for the request. Include this when contacting Arkose Support. |
Error code reference
The following table lists every error code the API may return. Each endpoint section summarises which codes apply to that endpoint.
| Status | Code | When returned |
|---|---|---|
400 | invalid_request | Request body is malformed or missing required fields. |
400 | invalid_page_size | page_size is outside the 1-1000 range. |
400 | invalid_page_token | page_token is malformed or has expired. |
400 | invalid_window | from/to are missing, malformed, or the window exceeds 30 days. |
400 | invalid_filter | One of the optional filter parameters is malformed. |
400 | missing_public_key | No public_key was supplied. |
401 | unauthorized | Missing, expired, or invalid access token (or invalid client_id/client_secret on POST /authorize). |
403 | forbidden | Authenticated, but not authorised to use this endpoint or resource. |
403 | forbidden_public_key | Caller is not authorised for one or more of the supplied public_key values. |
404 | not_found | The requested resource does not exist or is outside the caller's scope. |
500 | internal | Internal error. Retry with exponential backoff. If the error persists, contact Arkose Support with the request_id. |
Schemas
Cohort
A cohort represents a group of sessions retrospectively identified as related to a confirmed attack, grouped by the detection signal (telltale) that flagged them.
| Field | Type | Description |
|---|---|---|
cohort_id | string | Unique identifier for the cohort. |
public_key | string | Customer public key the cohort belongs to. |
customer_name | string | Customer display name. |
cohort_window_start | string (RFC 3339) | Start of the time window containing the cohort's sessions. |
cohort_window_end | string (RFC 3339) | End of the time window. |
created_at | string (RFC 3339) | Timestamp the cohort record was created. |
session_count | integer | Total number of sessions in the cohort. |
tagged_session_count | integer | Number of sessions in the cohort tagged by the associated telltale(s). |
anomaly_ids | array of integer | Anomaly IDs that triggered the retrospective scan. |
telltale_ids | array of integer | Telltale IDs associated with the cohort. |
telltale_names | array of string | Display names of the associated telltales. |
telltale_owner_categories | array of string | Owner categories for the telltales. |
zendesk_ticket_id | string | ID of the Zendesk ticket created to deliver the CSV equivalent of this cohort. |
zendesk_ticket_url | string | Direct link to the Zendesk ticket. |
schema_version | string | Schema version of the cohort record. |
Session
A session represents an individual request session retrospectively associated with a cohort.
| Field | Type | Description |
|---|---|---|
session_id | string | Unique identifier for the session. |
session_created | string (RFC 3339) | Timestamp the session was created. |
public_key | string | Customer public key the session belongs to. |
cohort_id | string | Cohort the session is associated with. |
anomaly_id | integer | Anomaly ID linked to the cohort that surfaced this session. |
original_ticket_id | string | ID of the original Zendesk attack ticket whose telltale led to this session being retrospectively identified. |
attack_label | string | Label categorising the attack (for example, retroactive_attack). |
client_theme | string | Client theme used when the Arkose challenge was presented. |
render_type | string | Rendering classification of the session client. |
risk_score | number | Numeric risk score assigned by Arkose. |
risk_band | string | Categorical risk band (for example, high). |
risk_category | string | Risk classification (for example, bot, human). |
custom_risk_score | number | Customer-specific risk score, if configured. |
suspicion_flags | array of string | Discrete suspicion signals raised on the session. |
tagged_by_telltale | boolean | true if the session was directly tagged by one of the cohort's telltales, false if it sits in the cohort window but was not directly tagged. |
telltale_names | array of string | Names of telltales associated with the session. |
verify | object (Verify) | Outcome of the Arkose challenge presented to the session, if any. |
schema_version | string | Schema version of the session record. |
Verify
The outcome of an Arkose challenge presented to a session.
| Field | Type | Description |
|---|---|---|
security_level | string | Security level of the challenge presented (for example, default, enhanced). |
solved | boolean | true if the session solved the challenge. |
verified | boolean | true if the session passed Arkose verification end-to-end. A session can have solved: true and verified: false when the puzzle was completed but other signals failed verification. |
Endpoints
Authorize
POST /api/rai/v1/authorize
Exchanges customer client_id and client_secret for an Auth0 access token used on protected RAI endpoints.
Authentication: None.
Request body
application/json
| Field | Type | Required | Description |
|---|---|---|---|
client_id | string | Yes | Client identifier issued by Arkose. |
client_secret | string | Yes | Client secret issued by Arkose. |
Response: 200 OK
200 OK| Field | Type | Description |
|---|---|---|
access_token | string | Bearer token. Include as Authorization: Bearer <access_token> on protected endpoints. |
expires_in | integer | Token lifetime in seconds. |
token_type | string | Token type. Always Bearer. |
Errors
| Status | Codes |
|---|---|
400 | invalid_request |
401 | unauthorized |
500 | internal |
See Error code reference for code definitions.
Example
curl https://client-api.arkoselabs.com/api/rai/v1/authorize \
--request POST \
--header 'Content-Type: application/json' \
--data '{
"client_id": "abc123",
"client_secret": "secret-value"
}'{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6...",
"expires_in": 3600,
"token_type": "Bearer"
}List cohorts
GET /api/rai/v1/cohorts
Returns cohorts for one or more caller-owned public keys. See Pagination for iteration.
Authentication: Required.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
from | string (RFC 3339) | Yes | Start of the time window. |
to | string (RFC 3339) | Yes | End of the time window. No more than 30 days after from. |
public_key | string (repeatable) | Yes | Customer public key to filter on. Repeat to query multiple keys. |
page_size | integer (1-1000) | No | Number of cohorts per page. |
page_token | string | No | Pagination cursor. |
cohort_id | string | No | Filter by cohort ID. |
anomaly_id | integer | No | Filter by anomaly ID. |
telltale_id | integer | No | Filter by telltale ID. |
min_session_count | integer | No | Exclude cohorts with fewer than this many sessions. |
Response: 200 OK
200 OK| Field | Type | Description |
|---|---|---|
cohorts | array of Cohort | Page of cohort records. |
next_page_token | string | Pagination cursor for the next page. |
schema_version | string | Schema version of the response. |
Errors
| Status | Codes |
|---|---|
400 | invalid_page_size, invalid_page_token, invalid_window, invalid_filter, missing_public_key |
401 | unauthorized |
403 | forbidden, forbidden_public_key |
500 | internal |
Example
curl 'https://client-api.arkoselabs.com/api/rai/v1/cohorts?from=2026-06-01T00:00:00Z&to=2026-06-30T00:00:00Z&public_key=11111111-1111-1111-1111-111111111111&page_size=100&min_session_count=10' \
--header 'Authorization: Bearer <ACCESS_TOKEN>'{
"cohorts": [
{
"cohort_id": "cohort-123",
"public_key": "11111111-1111-1111-1111-111111111111",
"customer_name": "Acme Corp",
"cohort_window_start": "2026-06-15T10:00:00Z",
"cohort_window_end": "2026-06-15T11:00:00Z",
"created_at": "2026-06-15T11:05:23Z",
"session_count": 1842,
"tagged_session_count": 1730,
"anomaly_ids": [1],
"telltale_ids": [1],
"telltale_names": ["ip-detection-signal-acme-001"],
"telltale_owner_categories": ["threat-research"],
"zendesk_ticket_id": "10001",
"zendesk_ticket_url": "https://arkoselabs.zendesk.com/agent/tickets/10001",
"schema_version": "rai-v1"
}
],
"next_page_token": "eyJ2IjoxfQ",
"schema_version": "rai-v1"
}Get cohort
GET /api/rai/v1/cohorts/{cohort_id}
Returns a single Cohort by its ID.
Authentication: Required.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
cohort_id | string | Yes | Cohort identifier. |
Response: 200 OK
200 OKReturns a Cohort object.
Errors
| Status | Codes |
|---|---|
401 | unauthorized |
403 | forbidden |
404 | not_found |
500 | internal |
Example
curl 'https://client-api.arkoselabs.com/api/rai/v1/cohorts/cohort-123' \
--header 'Authorization: Bearer <ACCESS_TOKEN>'{
"cohort_id": "cohort-123",
"public_key": "11111111-1111-1111-1111-111111111111",
"customer_name": "Acme Corp",
"cohort_window_start": "2026-06-15T10:00:00Z",
"cohort_window_end": "2026-06-15T11:00:00Z",
"created_at": "2026-06-15T11:05:23Z",
"session_count": 1842,
"tagged_session_count": 1730,
"anomaly_ids": [1],
"telltale_ids": [1],
"telltale_names": ["ip-detection-signal-acme-001"],
"telltale_owner_categories": ["threat-research"],
"zendesk_ticket_id": "10001",
"zendesk_ticket_url": "https://arkoselabs.zendesk.com/agent/tickets/10001",
"schema_version": "rai-v1"
}List cohort sessions
GET /api/rai/v1/cohorts/{cohort_id}/sessions
Returns the sessions belonging to a specific cohort. The cohort itself defines the implicit scope (public key, time window, and telltale association), so this endpoint accepts only pagination parameters. See Pagination for iteration.
Authentication: Required.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
cohort_id | string | Yes | Cohort identifier. |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
page_size | integer (1-1000) | No | Number of sessions per page. |
page_token | string | No | Pagination cursor. |
Response: 200 OK
200 OK| Field | Type | Description |
|---|---|---|
sessions | array of Session | Page of session records. |
next_page_token | string | Pagination cursor for the next page. |
schema_version | string | Schema version of the response. |
Errors
| Status | Codes |
|---|---|
400 | invalid_page_size, invalid_page_token |
401 | unauthorized |
403 | forbidden |
404 | not_found |
500 | internal |
Example
curl 'https://client-api.arkoselabs.com/api/rai/v1/cohorts/cohort-123/sessions?page_size=100' \
--header 'Authorization: Bearer <ACCESS_TOKEN>'{
"sessions": [
{
"session_id": "22222222-2222-2222-2222-222222222222",
"session_created": "2026-06-15T10:32:14Z",
"public_key": "11111111-1111-1111-1111-111111111111",
"cohort_id": "cohort-123",
"anomaly_id": 1001,
"original_ticket_id": "96335",
"attack_label": "retroactive_attack",
"client_theme": "default",
"render_type": "browser",
"risk_score": 0.92,
"risk_band": "high",
"risk_category": "bot",
"custom_risk_score": 0.78,
"suspicion_flags": ["ip_anomaly", "automation_signature"],
"tagged_by_telltale": true,
"telltale_names": ["ip-detection-signal-acme-001"],
"verify": {
"security_level": "enhanced",
"solved": true,
"verified": false
},
"schema_version": "rai-v1"
}
],
"next_page_token": "eyJ2IjoxfQ",
"schema_version": "rai-v1"
}List sessions
GET /api/rai/v1/sessions
Returns sessions across cohorts for one or more caller-owned public keys. Use this endpoint when ingesting all retroactively identified sessions for a given time window into a downstream system, without first listing the cohorts. See Pagination for iteration.
Authentication: Required.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
from | string (RFC 3339) | Yes | Start of the time window. |
to | string (RFC 3339) | Yes | End of the time window. No more than 30 days after from. |
public_key | string (repeatable) | Yes | Customer public key to filter on. Repeat to query multiple keys. |
page_size | integer (1-1000) | No | Number of sessions per page. |
page_token | string | No | Pagination cursor. |
cohort_id | string | No | Filter by cohort ID. |
anomaly_id | integer | No | Filter by anomaly ID. |
telltale_id | integer | No | Filter by telltale ID. |
Response: 200 OK
200 OK| Field | Type | Description |
|---|---|---|
sessions | array of Session | Page of session records. |
next_page_token | string | Pagination cursor for the next page. |
schema_version | string | Schema version of the response. |
Errors
| Status | Codes |
|---|---|
400 | invalid_page_size, invalid_page_token, invalid_window, invalid_filter, missing_public_key |
401 | unauthorized |
403 | forbidden, forbidden_public_key |
500 | internal |
Example
curl 'https://client-api.arkoselabs.com/api/rai/v1/sessions?from=2026-06-01T00:00:00Z&to=2026-06-30T00:00:00Z&public_key=11111111-1111-1111-1111-111111111111&page_size=100&telltale_id=1' \
--header 'Authorization: Bearer <ACCESS_TOKEN>'{
"sessions": [
{
"session_id": "22222222-2222-2222-2222-222222222222",
"session_created": "2026-06-15T10:32:14Z",
"public_key": "11111111-1111-1111-1111-111111111111",
"cohort_id": "cohort-123",
"anomaly_id": 1001,
"original_ticket_id": "96335",
"attack_label": "retroactive_attack",
"client_theme": "default",
"render_type": "browser",
"risk_score": 0.92,
"risk_band": "high",
"risk_category": "bot",
"custom_risk_score": 0.78,
"suspicion_flags": ["ip_anomaly", "automation_signature"],
"tagged_by_telltale": true,
"telltale_names": ["ip-detection-signal-acme-001"],
"verify": {
"security_level": "enhanced",
"solved": true,
"verified": false
},
"schema_version": "rai-v1"
}
],
"next_page_token": "eyJ2IjoxfQ",
"schema_version": "rai-v1"
}