Operate
Audit & exports
Query Platform operations and signed Sandbox0 runtime facts.
On this page
Platform operation facts
GET /v1/audit/events provides 90-day Platform operation facts. They contain only
caller/user/API-key identity, Project/Environment/Run IDs, operation ID, route
action, phase, outcome, HTTP status and time. Prompts, file bodies, raw errors,
tokens and arbitrary request attributes are excluded. Both API and console
operations are recorded. X-Operation-Id correlates an API call's attempt/result;
a missing result means the outcome is unconfirmed. 202 results mean accepted.
Admission is persisted before handler execution; failure to persist a normal
response's result returns an audit-unavailable error and may follow an executed
operation. Retry with the original idempotency key and reconcile by operation ID.
Filters and pagination
Filter by environmentId, runId, action, startTime and endTime. Use after
and response nextCursor for chronological pagination, with limit up to 200.
GET /v1/audit/events/export returns one NDJSON page; use X-Next-Cursor as after
and a fixed endTime to export a stable window. Export access is recorded.
Platform facts are separate from harness transcripts and are not presented as
cryptographically tamper-proof.
Platform and runtime boundaries
GET /v1/environments/{environmentId}/audit/events proxies authorized Sandbox0
canonical signed facts, preserving original field names and integrity information.
It requires the Sandbox0 enterprise audit feature, sandboxaudit:read, and a working
audit backend. Disabled or unavailable auditing is an error, never an empty success.
Queries default to the last 15 minutes. Specify startTime/endTime for historical windows and paginate with cursor. Sandbox0 retention follows the deployment configuration, independently of Platform's
90-day ledger. Platform and Sandbox0 operation IDs are separate: time overlap alone
is not a causal link. Neither ledger guarantees every guest command/syscall is captured.
Console equivalents use /api/v1/platform/ and browser-cookie authentication.
Team admins manage Project retention and deletion; Project API keys have authority
within their Project. The console's Data & audit view lists deletion receipts,
exports Platform facts and queries signed runtime facts. Environment pages set
retention; Run pages request manual content erasure.
Query content-free Platform operation facts
/v1/audit/eventsAuthentication: Platform API bearer token
Parameters and headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
query: environmentId | string | No | Filter receipts or audit facts by this Environment identifier within the token’s scope. |
query: runId | string | No | Filter receipts or audit facts by this Run identifier within the token’s scope. |
query: action | string · max length 200 | No | Filter facts by their recorded operation or route action. |
query: after | string · default: "0"Validation pattern^\d{1,19}$ | No | Last processed event ID or pagination cursor. Return only subsequent records; retain it when reconnecting or fetching another page. |
query: startTime | string · format: date-timeValidation pattern^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ | No | Beginning of the UTC query window, expressed as an ISO date-time string. |
query: endTime | string · format: date-timeValidation pattern^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ | No | End of the UTC query window. Keep it fixed across pages when exporting a stable window. |
query: limit | integer · default: 100; ≥ 1; ≤ 200 | No | Maximum records returned in this page; inspect nextCursor or the export cursor header before ending pagination. |
Request example
curl \
"https://api.sandpi.ai/v1/audit/events" \
-H "Authorization: Bearer $SANDPI_API_TOKEN"No request body.
Responses
200 Successful response.Response body application/json
| Field | Type and constraints | Required | Description |
|---|---|---|---|
data | object · extra fields rejected | Yes | Successful result wrapped by the API. The child fields describe its content. |
data.items | array | Yeswithin data | Records returned by this paginated operation. |
data.items[] | object · extra fields rejected | Yeseach array item | Content-free operation attempt or result, separate from native transcripts and signed Sandbox0 facts. |
data.items[].id | string | Yeseach array item | Resource identifier used to read or manage this resource. |
data.items[].projectId | string | Noeach array item | Team Project identifier associated with this resource. |
data.items[].actorUserId | string | Yeseach array item | User identity associated with the operation actor. |
data.items[].actorKind | string · values: "user" | "api_key" | "service" | Yeseach array item | Whether the operation actor is a user, API key or service. |
data.items[].apiKeyId | string | Noeach array item | API key identity for key-authenticated operations; never the secret token. |
data.items[].environmentId | string | Noeach array item | Environment identifier. It must belong to the caller’s account or Project. |
data.items[].runId | string | Noeach array item | Run identifier within the named Environment and, where applicable, Session. |
data.items[].operationId | string | Yeseach array item | Audit correlation identifier for this operation attempt or result. |
data.items[].action | string | Yeseach array item | Operation or route action recorded by the audit ledger. |
data.items[].phase | string · values: "attempt" | "result" | Yeseach array item | Whether this fact records an attempt or its result. |
data.items[].outcome | string · values: "accepted" | "succeeded" | "denied" | "failed" | "unknown" | Yeseach array item | Recorded operation outcome; accepted denotes asynchronous admission rather than completion. |
data.items[].httpStatus | integer · ≥ -9007199254740991; ≤ 9007199254740991 | Noeach array item | HTTP response status recorded for the operation result. |
data.items[].occurredAt | string · format: date-timeValidation pattern^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ | Yeseach array item | Audit fact time as a UTC date-time string. |
data.nextCursor | string | Nowithin data | Cursor to send as after when retrieving the next page. |
Example
{
"data": {
"items": [
{
"id": "",
"actorUserId": "",
"actorKind": "user",
"operationId": "",
"action": "",
"phase": "attempt",
"outcome": "accepted",
"occurredAt": "2026-10-12T01:00:00Z"
}
]
}
}Error responses
default Sandpi error.Error body application/json
Standard error envelope containing a stable code, diagnostic message and request identity.
| Field | Type and constraints | Required | Description |
|---|---|---|---|
error | object · extra fields rejected | Yes | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
error.code | string | Yeswithin error | Stable error code used to distinguish failures programmatically. |
error.message | string | Yeswithin error | Human-readable diagnostic text. |
error.requestId | string | Yeswithin error | Request identifier for correlating diagnostics and support investigations. |
error.details | any | Nowithin error | Optional structured error context. Its shape is specific to the service failure. |
error.loginUrl | string | Nowithin error | Authentication URL supplied when a browser login is required. |
error.registrationOpen | boolean | Nowithin error | Whether new account registration is enabled for this deployment. |
Example
{
"error": {
"code": "platform_balance_insufficient",
"message": "Top up Platform credits before submitting a Run.",
"requestId": "req_example"
}
}Export a stable window
Choose a fixed endTime before the first request. Download one NDJSON page at a time, then set after to the returned X-Next-Cursor and keep that same time window until pagination ends. Do not treat one page as a complete export.
Export one page of Platform audit facts as NDJSON
/v1/audit/events/exportUp to 200 facts per page. Continue with the X-Next-Cursor response header as the after query value. Export access is audited.
Authentication: Platform API bearer token
Parameters and headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
query: environmentId | string | No | Filter receipts or audit facts by this Environment identifier within the token’s scope. |
query: runId | string | No | Filter receipts or audit facts by this Run identifier within the token’s scope. |
query: action | string · max length 200 | No | Filter facts by their recorded operation or route action. |
query: after | string · default: "0"Validation pattern^\d{1,19}$ | No | Last processed event ID or pagination cursor. Return only subsequent records; retain it when reconnecting or fetching another page. |
query: startTime | string · format: date-timeValidation pattern^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ | No | Beginning of the UTC query window, expressed as an ISO date-time string. |
query: endTime | string · format: date-timeValidation pattern^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ | No | End of the UTC query window. Keep it fixed across pages when exporting a stable window. |
query: limit | integer · default: 100; ≥ 1; ≤ 200 | No | Maximum records returned in this page; inspect nextCursor or the export cursor header before ending pagination. |
Request example
curl \
"https://api.sandpi.ai/v1/audit/events/export" \
-H "Authorization: Bearer $SANDPI_API_TOKEN"No request body.
Responses
200 Successful response.Response headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
X-Next-Cursor | string | No | Continue with this value as after. Absent on the last page. |
Response body application/x-ndjson
| Field | Type and constraints | Required | Description |
|---|---|---|---|
body | string | Yes | — |
Example
""Error responses
default Sandpi error.Error body application/json
Standard error envelope containing a stable code, diagnostic message and request identity.
| Field | Type and constraints | Required | Description |
|---|---|---|---|
error | object · extra fields rejected | Yes | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
error.code | string | Yeswithin error | Stable error code used to distinguish failures programmatically. |
error.message | string | Yeswithin error | Human-readable diagnostic text. |
error.requestId | string | Yeswithin error | Request identifier for correlating diagnostics and support investigations. |
error.details | any | Nowithin error | Optional structured error context. Its shape is specific to the service failure. |
error.loginUrl | string | Nowithin error | Authentication URL supplied when a browser login is required. |
error.registrationOpen | boolean | Nowithin error | Whether new account registration is enabled for this deployment. |
Example
{
"error": {
"code": "platform_balance_insufficient",
"message": "Top up Platform credits before submitting a Run.",
"requestId": "req_example"
}
}Query signed runtime facts
Use the Environment runtime audit operation for Sandbox0’s original signed facts. Specify a historical time window explicitly; its default is the last 15 minutes. Follow its cursor, separately from the Platform audit after cursor.
Query Sandbox0 canonical signed audit facts for an authorized Environment
/v1/environments/{environmentId}/audit/eventsPreserves original Sandbox0 field names and integrity information. Requires the deployment's Sandbox0 audit license, read permission and backend. Backend unavailability is an error, never an empty success. Retention is the Sandbox0 deployment policy. Does not claim every guest syscall is audited. Queries default to the 15 minutes ending at endTime (or now). Supply startTime/endTime for historical windows; paginate with cursor. Unbounded backend scans are not used by default.
Authentication: Platform API bearer token
Parameters and headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
query: startTime | string · format: date-timeValidation pattern^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ | No | Beginning of the query window. Defaults to 15 minutes before endTime. |
query: endTime | string · format: date-timeValidation pattern^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$ | No | End of the query window. Defaults to now. |
query: cursor | string · max length 8192 | No | Opaque cursor returned by the previous signed Sandbox0 audit page. |
query: action | string · max length 200 | No | Filter facts by their recorded operation or route action. |
query: limit | integer · default: 100; ≥ 1; ≤ 200 | No | Maximum records returned in this page; inspect nextCursor or the export cursor header before ending pagination. |
path: environmentId | string · min length 1 | Yes | Environment identifier. It must belong to the caller’s account or Project. |
Request example
curl \
"https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/audit/events" \
-H "Authorization: Bearer $SANDPI_API_TOKEN"No request body.
Responses
200 Successful response.Response body application/json
| Field | Type and constraints | Required | Description |
|---|---|---|---|
data | object | Yes | Successful result wrapped by the API. The child fields describe its content. |
data.{key} | any | Noadditional keys | — |
Example
{
"data": {}
}Error responses
default Sandpi error.Error body application/json
Standard error envelope containing a stable code, diagnostic message and request identity.
| Field | Type and constraints | Required | Description |
|---|---|---|---|
error | object · extra fields rejected | Yes | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
error.code | string | Yeswithin error | Stable error code used to distinguish failures programmatically. |
error.message | string | Yeswithin error | Human-readable diagnostic text. |
error.requestId | string | Yeswithin error | Request identifier for correlating diagnostics and support investigations. |
error.details | any | Nowithin error | Optional structured error context. Its shape is specific to the service failure. |
error.loginUrl | string | Nowithin error | Authentication URL supplied when a browser login is required. |
error.registrationOpen | boolean | Nowithin error | Whether new account registration is enabled for this deployment. |
Example
{
"error": {
"code": "platform_balance_insufficient",
"message": "Top up Platform credits before submitting a Run.",
"requestId": "req_example"
}
}Investigate an unconfirmed outcome
Keep the X-Operation-Id and query the affected resource before retrying a mutation. An attempt without a result is not proof that nothing happened. Reuse an existing idempotency key where supported. See errors and retries.