List audit trail
US Region: https://public-api.sessionboard.com · EU Region: https://public-api-eu.sessionboard.com
Every recorded change to your organization's data — who changed which record,
which property, and (by default) the new value. action is
<subject_type>.<operation>, for example session.update. No retention limit.
Request example
curl --request GET \ --url 'https://public-api.sessionboard.com/v1/logs/audit-trail' \ --header 'x-access-token: <api-token>'const response = await fetch('https://public-api.sessionboard.com/v1/logs/audit-trail', { method: 'GET', headers: { "x-access-token": "<api-token>" },});
const data = await response.json();console.log(data);import requests
response = requests.request( "GET", "https://public-api.sessionboard.com/v1/logs/audit-trail", headers={ "x-access-token": "<api-token>" },)
print(response.json())<?php
$curl = curl_init();
curl_setopt_array($curl, [ CURLOPT_URL => "https://public-api.sessionboard.com/v1/logs/audit-trail", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "x-access-token: <api-token>", ],]);
$response = curl_exec($curl);curl_close($curl);
echo $response;package main
import ( "fmt" "io" "net/http")
func main() { req, _ := http.NewRequest("GET", "https://public-api.sessionboard.com/v1/logs/audit-trail", nil) req.Header.Add("x-access-token", "<api-token>")
res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))}HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://public-api.sessionboard.com/v1/logs/audit-trail")) .header("x-access-token", "<api-token>") .method("GET", HttpRequest.BodyPublishers.noBody()) .build();
HttpResponse<String> response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());Try it
Response headers
Authorizations
x-access-tokenstringheaderrequiredOrganization API token. Generate from Organization Settings → API Tokens.
Query parameters
cursorstringquerynext_cursorfrom the previous page. Store it after each page and send it back unchanged; it remembers your filters, so repeat the same filters with it.- Max length
2048
sincestring<date-time>queryWhere to start when you have no cursor. Defaults to 24 hours ago. Ignored when
cursoris sent.limitintegerqueryEvents per page.
- Default
500- Minimum
1- Maximum
1000
subject_typestringqueryComma-separated record types to include, for example
session,contact.- Example
"session,contact"
include_valuesbooleanquerySet
falseto omit changed values (details.value) — useful when the SIEM must not hold personal data.- Default
true
Responses
200application/json
One page of events, oldest first.
dataLogEvent[]requiredShow child attributes
idstringStable event id. Use it to de-duplicate if you replay a page.
streamstringWhich log the event came from —
api_requestfrom/v1/logs/api-requests,security_eventfrom/v1/logs/security-events,auditfrom/v1/logs/audit-trail.- Allowed values
"api_request", "security_event", "audit"
occurred_atstring<date-time>When the event happened.
ingested_atstring<date-time>When Sessionboard recorded it. Pages are ordered by this.
actionstringGET /v1/eventsfor API requests, the event type (for examplelogin.password_okorlogin.challenge_failed) for security events,<subject_type>.<operation>for the audit trail.- Example
"GET /v1/events"
outcomestring- Allowed values
"success", "failure", "unknown"
reasonstring | nullWhy it failed, when it did.
actorobjectShow child attributes
typestringapi_token,oauth_tokenoranonymousfor API requests;useroradminfor security events;user,systemorrule(an automation) for the audit trail.idstring | nullnamestring | nulltoken_hintstring | nullLast characters of the token id, for API requests.
user_emailstring | null
src_ipstring | nulluser_agentstring | nullstatusinteger | nullHTTP status, for API requests.
duration_msinteger | nullResponse time, for API requests.
targetobject | nullShow child attributes
typestring- Example
"event"
idstring
detailsobjectStream-specific fields (for example
sourceandrequest_idfor API requests,propertyandvaluefor the audit trail).
next_cursorstringrequiredSend this as
cursoron the next call. On an empty page it is the cursor you sent, so a caught-up poller keeps it and waits.has_morebooleanrequiredtruewhen more events are ready now — fetch again immediately.falsemeans wait before polling.
RateLimit-LimitintegerheaderRequests allowed in the current window.
RateLimit-RemainingintegerheaderRequests left in the current window.
400application/json
VALIDATION_ERROR for a bad parameter; INVALID_CURSOR for a cursor that is malformed or was issued for another stream or organization;
CURSOR_FILTER_MISMATCH when the filters differ from the ones the cursor was issued with;
SINCE_BEFORE_RETENTION when since is older than the stream keeps.
errorstring- Allowed values
"VALIDATION_ERROR", "INVALID_CURSOR", "CURSOR_FILTER_MISMATCH", "SINCE_BEFORE_RETENTION", "CURSOR_EXPIRED"
messagestring
401
Missing, invalid, revoked or expired API token.
403
The token does not hold read:audit_logs, or it is an OAuth token. Log export accepts API tokens only.
410application/json
CURSOR_EXPIRED — the cursor points before the start of retention. Restart from since.
errorstring- Allowed values
"VALIDATION_ERROR", "INVALID_CURSOR", "CURSOR_FILTER_MISMATCH", "SINCE_BEFORE_RETENTION", "CURSOR_EXPIRED"
messagestring
429
Rate limited. 60 requests per minute per token; honor Retry-After.
Response examples
{ "data": [ { "id": "<string>", "stream": "api_request", "occurred_at": "2026-01-15T09:30:00Z", "ingested_at": "2026-01-15T09:30:00Z", "action": "GET /v1/events", "outcome": "success", "reason": "<string>", "actor": { "type": "<string>", "id": "<string>", "name": "<string>", "token_hint": "<string>", "user_email": "<string>" }, "src_ip": "<string>", "user_agent": "<string>", "status": 123, "duration_ms": 123, "target": { "type": "event", "id": "<string>" }, "details": {} } ], "next_cursor": "<string>", "has_more": true}{ "error": "VALIDATION_ERROR", "message": "<string>"}{ "error": "VALIDATION_ERROR", "message": "<string>"}