Core concepts
Sessions & Runs
Retain native history, queue tasks and retry submissions.
On this page
Start a conversation
A Session is a logical headless conversation inside an Environment. It fixes the Harness and uses your native model connection and resumes the same native conversation across Runs. It is separate from the interactive TUI’s PTY session.
Create a harness Session
/v1/environments/{environmentId}/sessionsCreate a Session using a model vendor’s native Harness and your own API or gateway. Pi requires connection.api. No Sandpi Token purchase or model-price catalog is needed.
Authentication: Platform API bearer token
Parameters and headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
path: environmentId | string · min length 1 | Yes | Environment identifier. It must belong to the caller’s account or Project. |
Request example
curl -X POST \
"https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/sessions" \
-H "Authorization: Bearer $SANDPI_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"harness": "codex",
"connection": {
"baseUrl": "https://gateway.example.com/v1",
"apiKey": "YOUR_GATEWAY_KEY"
}
}'Request body · required application/json
| Field | Type and constraints | Required | Description |
|---|---|---|---|
harness | string · values: "codex" | "claude-code" | "pi" | "kimi-code" | "zcode" | Yes | Native coding-agent program used by the Session. |
connection | object · extra fields rejected | Yes | — |
connection.baseUrl | string · format: uri; max length 2048 | Yeswithin connection | Native model API base URL, including its required path prefix. Harness connects directly; Sandpi does not translate model traffic. |
connection.apiKey | string · min length 1; max length 8192; write only | Yeswithin connection | Your provider or gateway credential. Encrypted at rest, never returned by the API. |
connection.headers | object · max 32 keys; write only | Nowithin connection | Additional native HTTP headers. Stored with the encrypted credential. |
connection.headers.{key} | string · max length 8192 | Noadditional keys | — |
connection.api | string · values: "openai-responses" | "openai-completions" | "anthropic-messages" | Nowithin connection | Pi native API adapter. Required for Pi; other Harnesses use their native API. |
connection.contextWindow | integer · ≥ 1024; ≤ 10000000 | Nowithin connection | Pi custom model context capacity; defaults to 128000. |
connection.maxOutputTokens | integer · ≥ 1; ≤ 1000000 | Nowithin connection | Pi custom model output capacity; defaults to 16384. |
sandboxBudgetUsd | number · nullable; ≥ 0; ≤ 100000 | No | Optional lifetime Sandbox execution budget in USD. Converted to cumulative Harness execution time; does not add a Sandbox charge. Omitted or null is unlimited. |
Example
{
"harness": "codex",
"connection": {
"baseUrl": "https://gateway.example.com/v1",
"apiKey": "YOUR_GATEWAY_KEY"
}
}Responses
201 Created.Response body application/json
| Field | Type and constraints | Required | Description |
|---|---|---|---|
data | object · extra fields rejected | Yes | Persistent native Harness conversation. Configure your own provider or gateway; Sandpi charges only Sandbox runtime. |
data.id | string | Yeswithin data | Resource identifier used to read or manage this resource. |
data.environmentId | string | Yeswithin data | Environment identifier. It must belong to the caller’s account or Project. |
data.harness | string · values: "codex" | "claude-code" | "pi" | "kimi-code" | "zcode" | Yeswithin data | Native coding-agent program used by the Session. |
data.provider | string · values: "openai" | "anthropic" | "kimi" | "zai" | "deepseek" | Yeswithin data | Native model family associated with this Harness; not a Sandpi Token supplier. |
data.nativeSessionId | string | Nowithin data | Native harness conversation identifier retained for Session resume. |
data.nativeHistoryState | string · values: "new" | "available" | "unavailable" | Yeswithin data | State of the Session’s native conversation history. |
data.createdAt | 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))$ | Yeswithin data | Creation time as a UTC date-time string. |
data.connection | object · extra fields rejected | Nowithin data | — |
data.connection.baseUrl | string · format: uri; max length 2048 | Yeswithin data | Native model API base URL, including its required path prefix. Harness connects directly; Sandpi does not translate model traffic. |
data.connection.api | string · values: "openai-responses" | "openai-completions" | "anthropic-messages" | Nowithin data | Pi native API adapter. Required for Pi; other Harnesses use their native API. |
data.connection.revision | integer · ≥ 1 | Yeswithin data | Immutable connection revision captured by new Runs. Rotation does not change an existing Run. |
Example
{
"data": {
"id": "",
"environmentId": "",
"harness": "codex",
"provider": "openai",
"nativeHistoryState": "new",
"createdAt": "2026-10-12T01:00:00Z"
}
}Error responses
400 Invalid request.application/json
401 Missing or invalid Platform API token.application/json
404 Resource not found or outside token scope.application/json
415 Unsupported request media type.application/json
503 The selected harness or model route is temporarily unavailable.application/json
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"
}
}Reuse a Session for follow-up work that benefits from prior native history. Create a new Session for a separate conversation or harness, while remembering that Sessions in the same Environment still share workspace files.
Submit a task
A Run is one task or turn. Select its model explicitly and provide the instructions. File inputs must already exist in the workspace; the Run can reference them by path and optional digest.
Queue an idempotent headless Run
/v1/environments/{environmentId}/sessions/{sessionId}/runsRequires Idempotency-Key. Runs execute serially within an Environment.
Authentication: Platform API bearer token
Parameters and headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
path: environmentId | string · min length 1 | Yes | Environment identifier. It must belong to the caller’s account or Project. |
path: sessionId | string · min length 1 | Yes | Existing Session identifier within the named Environment. |
header: idempotency-key | string · min length 1; max length 128 | Yes | Stable key for one logical operation. Retry with the same key and exact request body; a new key can admit new work. |
Request example
curl -X POST \
"https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/sessions/$SESSION_ID/runs" \
-H "Authorization: Bearer $SANDPI_API_TOKEN" \
-H "idempotency-key: $REQUEST_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "YOUR_SUPPORTED_MODEL_ID",
"input": "Fix the login error"
}'Request body · required application/json
| Field | Type and constraints | Required | Description |
|---|---|---|---|
model | string · min length 1; max length 200Validation pattern.*\S.* | Yes | Exact native model ID served by your provider or gateway. |
input | string · min length 1 | Yes | Instructions supplied to the agent for this task. |
files | array · max 20 items | No | Files associated with this resource; each item is described below. |
files[] | object | Yeseach array item | — |
files[].path | string · min length 1; max length 2048 | Yeseach array item | Canonical absolute path inside /workspace. Protected state, Git metadata and symlinks are not accepted file targets. |
files[].sha256 | stringValidation pattern^[a-f0-9]{64}$ | Noeach array item | Lowercase hexadecimal SHA-256 digest of the file bytes. |
Example
{
"model": "YOUR_SUPPORTED_MODEL_ID",
"input": "Fix the login error"
}Responses
202 Accepted.Response body application/json
| Field | Type and constraints | Required | Description |
|---|---|---|---|
data | object · extra fields rejected | Yes | Native task execution, output, file diff and checkpoint state. These states settle independently. |
data.id | string | Yeswithin data | Resource identifier used to read or manage this resource. |
data.environmentId | string | Yeswithin data | Environment identifier. It must belong to the caller’s account or Project. |
data.sessionId | string | Yeswithin data | Existing Session identifier within the named Environment. |
data.environmentSequence | integer · ≥ -9007199254740991; ≤ 9007199254740991 | Yeswithin data | Environment-wide Run ordering across all Sessions; rollback uses this ordering. |
data.model | string | Yeswithin data | Exact native model ID served by your provider or gateway. |
data.input | string | Yeswithin data | Instructions supplied to the agent for this task. |
data.files | array | Yeswithin data | Files associated with this resource; each item is described below. |
data.files[] | object · extra fields rejected | Yeseach array item | Reference to an existing regular workspace file checked before execution. |
data.files[].path | string | Yeseach array item | Canonical absolute path inside /workspace. Protected state, Git metadata and symlinks are not accepted file targets. |
data.files[].sha256 | stringValidation pattern^[a-f0-9]{64}$ | Noeach array item | Lowercase hexadecimal SHA-256 digest of the file bytes. |
data.status | string · values: "queued" | "running" | "completed" | "failed" | "stopped" | "reverting" | "reverted" | Yeswithin data | Current resource state; inspect the allowed values and the operation’s lifecycle notes. |
data.stopRequested | boolean | Yeswithin data | Whether a client has requested that the native task stop. |
data.output | string | Nowithin data | Final agent output when available. Content retention may erase this field. |
data.error | object · extra fields rejected | Nowithin data | Execution failure or transient runtime availability diagnostic. While status is running, platform_runtime_unavailable means observation or preparation is blocked; the original task may still be executing. Reuse this Run instead of submitting it again. The diagnostic clears after successful runtime access. Optional timestamped resource samples may be appended asynchronously; these measurements do not establish the timeout cause or OOM. |
data.error.code | string | Nowithin data | Stable code identifying an execution failure or transient runtime availability diagnostic. |
data.error.message | string | Nowithin data | Human-readable failure or availability diagnostic; it does not by itself establish that the original task stopped. |
data.fileDiff | array | Yeswithin data | Manifest of added, modified and deleted regular workspace files. It does not contain file bytes. |
data.fileDiff[] | object · extra fields rejected | Yeseach array item | Regular workspace file change with before and after content digests. |
data.fileDiff[].path | string | Yeseach array item | Canonical absolute path inside /workspace. Protected state, Git metadata and symlinks are not accepted file targets. |
data.fileDiff[].kind | string · values: "added" | "modified" | "deleted" | Yeseach array item | Whether the Run added, modified or deleted the regular file. |
data.fileDiff[].beforeSha256 | stringValidation pattern^[a-f0-9]{64}$ | Noeach array item | Content digest before the Run; absent for a newly added file. |
data.fileDiff[].afterSha256 | stringValidation pattern^[a-f0-9]{64}$ | Noeach array item | Content digest after the Run; absent for a deleted file. |
data.fileDiffStatus | string · values: "pending" | "ready" | "failed" | Yeswithin data | File-diff computation state, separate from execution and checkpoint state. |
data.fileDiffError | string | Nowithin data | Diagnostic text when file-diff computation fails. |
data.checkpoint | object · extra fields rejected | Yeswithin data | RootFS checkpoint state and identifier, tracked separately from native execution. |
data.checkpoint.status | string · values: "pending" | "ready" | "failed" | "skipped" | Yeswithin data | Current resource state; inspect the allowed values and the operation’s lifecycle notes. |
data.checkpoint.snapshotId | string | Nowithin data | Sandbox0 checkpoint identifier. Use a returned initial or Run checkpoint when pinning a fork. |
data.checkpoint.error | string | Nowithin data | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
data.createdAt | 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))$ | Yeswithin data | Creation time as a UTC date-time string. |
data.startedAt | 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))$ | Nowithin data | Execution start time as a UTC date-time string. |
data.finishedAt | 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))$ | Nowithin data | Terminal execution time as a UTC date-time string. |
data.steeringEnabled | boolean | Yeswithin data | Whether this Run supports native steering during execution. |
data.contentDeletedAt | string · format: date-time | Nowithin data | Platform content was erased; native history and checkpoints remain until Environment deletion. |
Example
{
"data": {
"id": "",
"environmentId": "",
"sessionId": "",
"environmentSequence": -9007199254740991,
"model": "",
"input": "",
"files": [
{
"path": ""
}
],
"status": "queued",
"stopRequested": false,
"fileDiff": [
{
"path": "",
"kind": "added"
}
],
"fileDiffStatus": "pending",
"checkpoint": {
"status": "pending"
},
"createdAt": "2026-10-12T01:00:00Z",
"steeringEnabled": false
}
}Error responses
400 Invalid request.application/json
401 Missing or invalid Platform API token.application/json
402 Insufficient Platform credit.application/json
404 Resource not found or outside token scope.application/json
409 Resource state conflict.application/json
415 Unsupported request media type.application/json
503 Platform execution is unavailable.application/json
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"
}
}Only one Run executes in an Environment at a time. Runs from different Sessions share the same execution queue and checkpoint boundary. Different Environments can provide independent execution and files.
Make retries safe
Generate one idempotency key per logical submission and persist it with the request body. If the response is lost, retry with that same key, model, input and ordered file references. Reusing a key with changed content conflicts; a new key can create another Run.
The Run continues until the Harness exits, you stop it, or runtime credit, the Team Sandbox budget, or its Session execution allowance is exhausted. An optional Session Sandbox budget converts USD to cumulative execution time across Runs; see Sandbox budgets. Losing an observer connection is not a reason to resubmit.
Read output and state
Get Run state and Sandbox usage
/v1/environments/{environmentId}/sessions/{sessionId}/runs/{runId}Authentication: Platform API bearer token
Parameters and headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
path: environmentId | string · min length 1 | Yes | Environment identifier. It must belong to the caller’s account or Project. |
path: sessionId | string · min length 1 | Yes | Existing Session identifier within the named Environment. |
path: runId | string · min length 1 | Yes | Run identifier within the named Environment and, where applicable, Session. |
Request example
curl \
"https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/sessions/$SESSION_ID/runs/$RUN_ID" \
-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 | Run details with posted Sandbox runtime and retained historical managed-model settlement; BYOK model costs are billed by your provider. |
data.id | string | Yeswithin data | Resource identifier used to read or manage this resource. |
data.environmentId | string | Yeswithin data | Environment identifier. It must belong to the caller’s account or Project. |
data.sessionId | string | Yeswithin data | Existing Session identifier within the named Environment. |
data.environmentSequence | integer · ≥ -9007199254740991; ≤ 9007199254740991 | Yeswithin data | Environment-wide Run ordering across all Sessions; rollback uses this ordering. |
data.model | string | Yeswithin data | Exact native model ID served by your provider or gateway. |
data.input | string | Yeswithin data | Instructions supplied to the agent for this task. |
data.files | array | Yeswithin data | Files associated with this resource; each item is described below. |
data.files[] | object · extra fields rejected | Yeseach array item | Reference to an existing regular workspace file checked before execution. |
data.files[].path | string | Yeseach array item | Canonical absolute path inside /workspace. Protected state, Git metadata and symlinks are not accepted file targets. |
data.files[].sha256 | stringValidation pattern^[a-f0-9]{64}$ | Noeach array item | Lowercase hexadecimal SHA-256 digest of the file bytes. |
data.status | string · values: "queued" | "running" | "completed" | "failed" | "stopped" | "reverting" | "reverted" | Yeswithin data | Current resource state; inspect the allowed values and the operation’s lifecycle notes. |
data.stopRequested | boolean | Yeswithin data | Whether a client has requested that the native task stop. |
data.output | string | Nowithin data | Final agent output when available. Content retention may erase this field. |
data.fileDiff | array | Yeswithin data | Manifest of added, modified and deleted regular workspace files. It does not contain file bytes. |
data.fileDiff[] | object · extra fields rejected | Yeseach array item | Regular workspace file change with before and after content digests. |
data.fileDiff[].path | string | Yeseach array item | Canonical absolute path inside /workspace. Protected state, Git metadata and symlinks are not accepted file targets. |
data.fileDiff[].kind | string · values: "added" | "modified" | "deleted" | Yeseach array item | Whether the Run added, modified or deleted the regular file. |
data.fileDiff[].beforeSha256 | stringValidation pattern^[a-f0-9]{64}$ | Noeach array item | Content digest before the Run; absent for a newly added file. |
data.fileDiff[].afterSha256 | stringValidation pattern^[a-f0-9]{64}$ | Noeach array item | Content digest after the Run; absent for a deleted file. |
data.fileDiffStatus | string · values: "pending" | "ready" | "failed" | Yeswithin data | File-diff computation state, separate from execution and checkpoint state. |
data.fileDiffError | string | Nowithin data | Diagnostic text when file-diff computation fails. |
data.checkpoint | object · extra fields rejected | Yeswithin data | RootFS checkpoint state and identifier, tracked separately from native execution. |
data.checkpoint.status | string · values: "pending" | "ready" | "failed" | "skipped" | Yeswithin data | Current resource state; inspect the allowed values and the operation’s lifecycle notes. |
data.checkpoint.snapshotId | string | Nowithin data | Sandbox0 checkpoint identifier. Use a returned initial or Run checkpoint when pinning a fork. |
data.checkpoint.error | string | Nowithin data | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
data.createdAt | 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))$ | Yeswithin data | Creation time as a UTC date-time string. |
data.startedAt | 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))$ | Nowithin data | Execution start time as a UTC date-time string. |
data.finishedAt | 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))$ | Nowithin data | Terminal execution time as a UTC date-time string. |
data.usage | object · extra fields rejected | Yeswithin data | Posted Sandbox runtime usage and retained historical managed-model settlement. New BYOK Runs have no rated model-call ledger; provider usage and cost are recorded by the customer’s provider or gateway. |
data.usage.calls | array | Yeswithin data | Historical rated managed-model calls only. Empty for new BYOK Runs; does not measure native model requests. |
data.usage.calls[] | object · extra fields rejected | Yeseach array item | — |
data.usage.calls[].id | string | Yeseach array item | Resource identifier used to read or manage this resource. |
data.usage.calls[].provider | string · values: "openai" | "anthropic" | "kimi" | "zai" | "deepseek" | Yeseach array item | Native model family associated with this Harness; not a Sandpi Token supplier. |
data.usage.calls[].model | string | Yeseach array item | Exact native model ID served by your provider or gateway. |
data.usage.calls[].priceVersion | string | Yeseach array item | Historical managed-model settlement only. Immutable version of the published price captured for rating. |
data.usage.calls[].priceSourceUrl | string · format: uri | Yeseach array item | Historical managed-model settlement only. Official provider pricing reference captured with the immutable price version. |
data.usage.calls[].usageCategories | object | Yeseach array item | Historical managed-model settlement only. Provider-reported usage by category, such as uncached input, cached input and output tokens. |
data.usage.calls[].usageCategories.{key} | number | Noadditional keys | — |
data.usage.calls[].ratedLines | array | Yeseach array item | Historical managed-model settlement only. Rated accounting line items for the provider call. |
data.usage.calls[].ratedLines[] | any | Yeseach array item | — |
data.usage.calls[].upstreamAmountUsd | string | Yeseach array item | Historical managed-model settlement only. Published base-rate usage amount in USD, represented as a decimal string. |
data.usage.calls[].serviceFeeUsd | string | Yeseach array item | Historical managed-model settlement only. Itemized service fee in USD, represented as a decimal string. |
data.usage.calls[].totalAmountUsd | string | Yeseach array item | Historical managed-model settlement only. Total rated charge in USD, represented as a decimal string. |
data.usage.calls[].createdAt | 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 | Creation time as a UTC date-time string. |
data.usage.calls[].serviceFeePercent | number · values: 0 | 5 | 10 | 15 | Yeseach array item | Historical managed-model settlement only. Service fee captured by this call’s immutable price version; zero for legacy calls. |
data.usage.serviceFeePercent | number · values: 0 | 5 | 10 | 15 | null | Yeswithin data | Historical managed-model fee shared by all calls, or null for mixed historical tiers. Zero for new BYOK Runs; Sandpi adds no model service fee. |
data.usage.upstreamAmountUsd | string | Yeswithin data | Historical managed-model base charges in USD. Zero for new BYOK Runs; excludes charges billed directly by your model provider. |
data.usage.serviceFeeUsd | string | Yeswithin data | Historical managed-model service fees in USD. Zero for new BYOK Runs. |
data.usage.totalAmountUsd | string | Yeswithin data | Posted Sandbox runtime plus retained historical managed-model charges in USD. Excludes model charges billed directly by your provider or gateway. |
data.usage.sandboxAmountUsd | string | Yeswithin data | Posted Sandbox runtime charge attributed to this Run. Environment initialization and file access may incur separate Environment charges. |
data.usage.sandboxRuntimeSeconds | number · ≥ 0 | Nowithin data | Authoritative billed Sandbox time attributed to this Run. |
Example
{
"data": {
"id": "",
"environmentId": "",
"sessionId": "",
"environmentSequence": -9007199254740991,
"model": "",
"input": "",
"files": [
{
"path": ""
}
],
"status": "queued",
"stopRequested": false,
"fileDiff": [
{
"path": "",
"kind": "added"
}
],
"fileDiffStatus": "pending",
"checkpoint": {
"status": "pending"
},
"createdAt": "2026-10-12T01:00:00Z",
"usage": {
"calls": [],
"serviceFeePercent": 0,
"upstreamAmountUsd": "",
"serviceFeeUsd": "",
"totalAmountUsd": "",
"sandboxAmountUsd": ""
}
}
}Error responses
400 Invalid request.application/json
401 Missing or invalid Platform API token.application/json
404 Resource not found or outside token scope.application/json
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"
}
}Execution status, file-diff status, checkpoint status and accounting are separate. A completed Run can have output while its checkpoint is pending. Transient checkpoint failures retry without rerunning the harness. Display output immediately and wait for workspace access to become available before file operations.
Continue or undo
Submit a later Run in the same Session for a follow-up task. Use steering to add instructions during active execution. Use stop and rollback to stop or restore state; rollback affects later Runs across all Sessions, not only the selected conversation.
Browse conversations and submitted work
List Sessions in the Environment, read one Session’s native history state, then list its Runs.
List harness Sessions
/v1/environments/{environmentId}/sessionsAuthentication: Platform API bearer token
Parameters and headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
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/sessions" \
-H "Authorization: Bearer $SANDPI_API_TOKEN"No request body.
Responses
200 Successful response.Response body application/json
| Field | Type and constraints | Required | Description |
|---|---|---|---|
data | array | Yes | Successful result wrapped by the API. The child fields describe its content. |
data[] | object · extra fields rejected | Yeseach array item | Persistent native Harness conversation. Configure your own provider or gateway; Sandpi charges only Sandbox runtime. |
data[].id | string | Yeseach array item | Resource identifier used to read or manage this resource. |
data[].environmentId | string | Yeseach array item | Environment identifier. It must belong to the caller’s account or Project. |
data[].harness | string · values: "codex" | "claude-code" | "pi" | "kimi-code" | "zcode" | Yeseach array item | Native coding-agent program used by the Session. |
data[].provider | string · values: "openai" | "anthropic" | "kimi" | "zai" | "deepseek" | Yeseach array item | Native model family associated with this Harness; not a Sandpi Token supplier. |
data[].nativeSessionId | string | Noeach array item | Native harness conversation identifier retained for Session resume. |
data[].nativeHistoryState | string · values: "new" | "available" | "unavailable" | Yeseach array item | State of the Session’s native conversation history. |
data[].createdAt | 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 | Creation time as a UTC date-time string. |
data[].connection | object · extra fields rejected | Noeach array item | — |
data[].connection.baseUrl | string · format: uri; max length 2048 | Yeseach array item | Native model API base URL, including its required path prefix. Harness connects directly; Sandpi does not translate model traffic. |
data[].connection.api | string · values: "openai-responses" | "openai-completions" | "anthropic-messages" | Noeach array item | Pi native API adapter. Required for Pi; other Harnesses use their native API. |
data[].connection.revision | integer · ≥ 1 | Yeseach array item | Immutable connection revision captured by new Runs. Rotation does not change an existing Run. |
Example
{
"data": [
{
"id": "",
"environmentId": "",
"harness": "codex",
"provider": "openai",
"nativeHistoryState": "new",
"createdAt": "2026-10-12T01:00:00Z"
}
]
}Error responses
400 Invalid request.application/json
401 Missing or invalid Platform API token.application/json
404 Resource not found or outside token scope.application/json
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"
}
}Get a harness Session
/v1/environments/{environmentId}/sessions/{sessionId}Authentication: Platform API bearer token
Parameters and headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
path: environmentId | string · min length 1 | Yes | Environment identifier. It must belong to the caller’s account or Project. |
path: sessionId | string · min length 1 | Yes | Existing Session identifier within the named Environment. |
Request example
curl \
"https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/sessions/$SESSION_ID" \
-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 | Persistent native Harness conversation. Configure your own provider or gateway; Sandpi charges only Sandbox runtime. |
data.id | string | Yeswithin data | Resource identifier used to read or manage this resource. |
data.environmentId | string | Yeswithin data | Environment identifier. It must belong to the caller’s account or Project. |
data.harness | string · values: "codex" | "claude-code" | "pi" | "kimi-code" | "zcode" | Yeswithin data | Native coding-agent program used by the Session. |
data.provider | string · values: "openai" | "anthropic" | "kimi" | "zai" | "deepseek" | Yeswithin data | Native model family associated with this Harness; not a Sandpi Token supplier. |
data.nativeSessionId | string | Nowithin data | Native harness conversation identifier retained for Session resume. |
data.nativeHistoryState | string · values: "new" | "available" | "unavailable" | Yeswithin data | State of the Session’s native conversation history. |
data.createdAt | 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))$ | Yeswithin data | Creation time as a UTC date-time string. |
data.connection | object · extra fields rejected | Nowithin data | — |
data.connection.baseUrl | string · format: uri; max length 2048 | Yeswithin data | Native model API base URL, including its required path prefix. Harness connects directly; Sandpi does not translate model traffic. |
data.connection.api | string · values: "openai-responses" | "openai-completions" | "anthropic-messages" | Nowithin data | Pi native API adapter. Required for Pi; other Harnesses use their native API. |
data.connection.revision | integer · ≥ 1 | Yeswithin data | Immutable connection revision captured by new Runs. Rotation does not change an existing Run. |
Example
{
"data": {
"id": "",
"environmentId": "",
"harness": "codex",
"provider": "openai",
"nativeHistoryState": "new",
"createdAt": "2026-10-12T01:00:00Z"
}
}Error responses
400 Invalid request.application/json
401 Missing or invalid Platform API token.application/json
404 Resource not found or outside token scope.application/json
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"
}
}List Session Runs
/v1/environments/{environmentId}/sessions/{sessionId}/runsAuthentication: Platform API bearer token
Parameters and headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
path: environmentId | string · min length 1 | Yes | Environment identifier. It must belong to the caller’s account or Project. |
path: sessionId | string · min length 1 | Yes | Existing Session identifier within the named Environment. |
Request example
curl \
"https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/sessions/$SESSION_ID/runs" \
-H "Authorization: Bearer $SANDPI_API_TOKEN"No request body.
Responses
200 Successful response.Response body application/json
| Field | Type and constraints | Required | Description |
|---|---|---|---|
data | array | Yes | Successful result wrapped by the API. The child fields describe its content. |
data[] | object · extra fields rejected | Yeseach array item | Native task execution, output, file diff and checkpoint state. These states settle independently. |
data[].id | string | Yeseach array item | Resource identifier used to read or manage this resource. |
data[].environmentId | string | Yeseach array item | Environment identifier. It must belong to the caller’s account or Project. |
data[].sessionId | string | Yeseach array item | Existing Session identifier within the named Environment. |
data[].environmentSequence | integer · ≥ -9007199254740991; ≤ 9007199254740991 | Yeseach array item | Environment-wide Run ordering across all Sessions; rollback uses this ordering. |
data[].model | string | Yeseach array item | Exact native model ID served by your provider or gateway. |
data[].input | string | Yeseach array item | Instructions supplied to the agent for this task. |
data[].files | array | Yeseach array item | Files associated with this resource; each item is described below. |
data[].files[] | object · extra fields rejected | Yeseach array item | Reference to an existing regular workspace file checked before execution. |
data[].files[].path | string | Yeseach array item | Canonical absolute path inside /workspace. Protected state, Git metadata and symlinks are not accepted file targets. |
data[].files[].sha256 | stringValidation pattern^[a-f0-9]{64}$ | Noeach array item | Lowercase hexadecimal SHA-256 digest of the file bytes. |
data[].status | string · values: "queued" | "running" | "completed" | "failed" | "stopped" | "reverting" | "reverted" | Yeseach array item | Current resource state; inspect the allowed values and the operation’s lifecycle notes. |
data[].stopRequested | boolean | Yeseach array item | Whether a client has requested that the native task stop. |
data[].output | string | Noeach array item | Final agent output when available. Content retention may erase this field. |
data[].error | object · extra fields rejected | Noeach array item | Execution failure or transient runtime availability diagnostic. While status is running, platform_runtime_unavailable means observation or preparation is blocked; the original task may still be executing. Reuse this Run instead of submitting it again. The diagnostic clears after successful runtime access. Optional timestamped resource samples may be appended asynchronously; these measurements do not establish the timeout cause or OOM. |
data[].error.code | string | Noeach array item | Stable code identifying an execution failure or transient runtime availability diagnostic. |
data[].error.message | string | Noeach array item | Human-readable failure or availability diagnostic; it does not by itself establish that the original task stopped. |
data[].fileDiff | array | Yeseach array item | Manifest of added, modified and deleted regular workspace files. It does not contain file bytes. |
data[].fileDiff[] | object · extra fields rejected | Yeseach array item | Regular workspace file change with before and after content digests. |
data[].fileDiff[].path | string | Yeseach array item | Canonical absolute path inside /workspace. Protected state, Git metadata and symlinks are not accepted file targets. |
data[].fileDiff[].kind | string · values: "added" | "modified" | "deleted" | Yeseach array item | Whether the Run added, modified or deleted the regular file. |
data[].fileDiff[].beforeSha256 | stringValidation pattern^[a-f0-9]{64}$ | Noeach array item | Content digest before the Run; absent for a newly added file. |
data[].fileDiff[].afterSha256 | stringValidation pattern^[a-f0-9]{64}$ | Noeach array item | Content digest after the Run; absent for a deleted file. |
data[].fileDiffStatus | string · values: "pending" | "ready" | "failed" | Yeseach array item | File-diff computation state, separate from execution and checkpoint state. |
data[].fileDiffError | string | Noeach array item | Diagnostic text when file-diff computation fails. |
data[].checkpoint | object · extra fields rejected | Yeseach array item | RootFS checkpoint state and identifier, tracked separately from native execution. |
data[].checkpoint.status | string · values: "pending" | "ready" | "failed" | "skipped" | Yeseach array item | Current resource state; inspect the allowed values and the operation’s lifecycle notes. |
data[].checkpoint.snapshotId | string | Noeach array item | Sandbox0 checkpoint identifier. Use a returned initial or Run checkpoint when pinning a fork. |
data[].checkpoint.error | string | Noeach array item | Structured failure information. Inspect the stable code and retain the request ID for investigation. |
data[].createdAt | 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 | Creation time as a UTC date-time string. |
data[].startedAt | 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))$ | Noeach array item | Execution start time as a UTC date-time string. |
data[].finishedAt | 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))$ | Noeach array item | Terminal execution time as a UTC date-time string. |
data[].steeringEnabled | boolean | Yeseach array item | Whether this Run supports native steering during execution. |
data[].contentDeletedAt | string · format: date-time | Noeach array item | Platform content was erased; native history and checkpoints remain until Environment deletion. |
Example
{
"data": [
{
"id": "",
"environmentId": "",
"sessionId": "",
"environmentSequence": -9007199254740991,
"model": "",
"input": "",
"files": [
{
"path": ""
}
],
"status": "queued",
"stopRequested": false,
"fileDiff": [
{
"path": "",
"kind": "added"
}
],
"fileDiffStatus": "pending",
"checkpoint": {
"status": "pending"
},
"createdAt": "2026-10-12T01:00:00Z",
"steeringEnabled": false
}
]
}Error responses
400 Invalid request.application/json
401 Missing or invalid Platform API token.application/json
404 Resource not found or outside token scope.application/json
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"
}
}Rotate the model connection
Update the endpoint and key for subsequent Runs. Active and queued Runs retain their original revision. Keys are never returned in Session reads.
Replace a Session model connection
/v1/environments/{environmentId}/sessions/{sessionId}/connectionCreate an immutable connection revision for subsequent Runs. API keys and headers are write-only. Existing Runs retain their original revision; native history remains in the Session.
Authentication: Platform API bearer token
Parameters and headers
| Field | Type and constraints | Required | Description |
|---|---|---|---|
path: environmentId | string · min length 1 | Yes | Environment identifier. It must belong to the caller’s account or Project. |
path: sessionId | string · min length 1 | Yes | Existing Session identifier within the named Environment. |
Request example
curl -X PUT \
"https://api.sandpi.ai/v1/environments/$ENVIRONMENT_ID/sessions/$SESSION_ID/connection" \
-H "Authorization: Bearer $SANDPI_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"baseUrl": "https://example.com/repository.git",
"apiKey": "example"
}'Request body · required application/json
| Field | Type and constraints | Required | Description |
|---|---|---|---|
baseUrl | string · format: uri; max length 2048 | Yes | Native model API base URL, including its required path prefix. Harness connects directly; Sandpi does not translate model traffic. |
apiKey | string · min length 1; max length 8192; write only | Yes | Your provider or gateway credential. Encrypted at rest, never returned by the API. |
headers | object · max 32 keys; write only | No | Additional native HTTP headers. Stored with the encrypted credential. |
headers.{key} | string · max length 8192 | Noadditional keys | — |
api | string · values: "openai-responses" | "openai-completions" | "anthropic-messages" | No | Pi native API adapter. Required for Pi; other Harnesses use their native API. |
contextWindow | integer · ≥ 1024; ≤ 10000000 | No | Pi custom model context capacity; defaults to 128000. |
maxOutputTokens | integer · ≥ 1; ≤ 1000000 | No | Pi custom model output capacity; defaults to 16384. |
Example
{
"baseUrl": "https://example.com/repository.git",
"apiKey": "example"
}Responses
200 Successful response.Response body application/json
| Field | Type and constraints | Required | Description |
|---|---|---|---|
data | object · extra fields rejected | Yes | Persistent native Harness conversation. Configure your own provider or gateway; Sandpi charges only Sandbox runtime. |
data.id | string | Yeswithin data | Resource identifier used to read or manage this resource. |
data.environmentId | string | Yeswithin data | Environment identifier. It must belong to the caller’s account or Project. |
data.harness | string · values: "codex" | "claude-code" | "pi" | "kimi-code" | "zcode" | Yeswithin data | Native coding-agent program used by the Session. |
data.provider | string · values: "openai" | "anthropic" | "kimi" | "zai" | "deepseek" | Yeswithin data | Native model family associated with this Harness; not a Sandpi Token supplier. |
data.nativeSessionId | string | Nowithin data | Native harness conversation identifier retained for Session resume. |
data.nativeHistoryState | string · values: "new" | "available" | "unavailable" | Yeswithin data | State of the Session’s native conversation history. |
data.createdAt | 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))$ | Yeswithin data | Creation time as a UTC date-time string. |
data.connection | object · extra fields rejected | Nowithin data | — |
data.connection.baseUrl | string · format: uri; max length 2048 | Yeswithin data | Native model API base URL, including its required path prefix. Harness connects directly; Sandpi does not translate model traffic. |
data.connection.api | string · values: "openai-responses" | "openai-completions" | "anthropic-messages" | Nowithin data | Pi native API adapter. Required for Pi; other Harnesses use their native API. |
data.connection.revision | integer · ≥ 1 | Yeswithin data | Immutable connection revision captured by new Runs. Rotation does not change an existing Run. |
Example
{
"data": {
"id": "",
"environmentId": "",
"harness": "codex",
"provider": "openai",
"nativeHistoryState": "new",
"createdAt": "2026-10-12T01:00:00Z"
}
}Error responses
400 Invalid request.application/json
401 Missing or invalid Platform API token.application/json
404 Resource not found or outside token scope.application/json
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"
}
}