Core concepts
Harnesses & models
Choose compatible models and understand availability.
On this page
Native Harness connections
Platform supports Codex, Claude Code, Kimi Code, ZCode and Pi with your own model API key and endpoint (BYOK). New Runs require a Session model connection; Sandpi does not supply a shared model key or sell model Tokens. Model charges go to your provider or gateway, while Sandpi bills Sandbox runtime.
Sandpi runs the native Harness and keeps its conversation history. Model requests go directly from the Sandbox to your endpoint, without protocol translation in Sandpi. Choose the Harness by the API your endpoint implements, not just the model name or provider branding.
| Harness | Native model API | Protocol selection |
|---|---|---|
| Codex | OpenAI Responses | Fixed; omit connection.api |
| Claude Code | Anthropic Messages | Fixed; omit connection.api |
| Kimi Code | Native OpenAI-compatible Chat Completions | Fixed; omit connection.api |
| ZCode | Native OpenAI-compatible Chat Completions | Fixed; omit connection.api |
| Pi | OpenAI Responses | Set connection.api to openai-responses |
| Pi | OpenAI Chat Completions | Set connection.api to openai-completions |
| Pi | Anthropic Messages | Set connection.api to anthropic-messages |
Codex uses OpenAI Responses. A gateway that only exposes Chat Completions cannot serve Codex. Claude Code requires Anthropic Messages. An “OpenAI-compatible” label alone does not establish which API a gateway supports.
Pi is an independent Harness. Its upstream project supports more adapters, including Google, Azure and Bedrock, and an optional pi-messages protocol. Platform exposes the three key-based native APIs above; it does not translate other protocols into them. Custom Pi models can specify contextWindow (default 128000) and maxOutputTokens (default 16384).
Endpoint addresses
Enter the API base URL, including the gateway's required path prefix. Do not enter the complete inference URL ending in /responses, /messages or /chat/completions; the native client adds that operation path.
The following are illustrative gateway addresses, not a domain allowlist. Official provider endpoints and custom gateways are accepted when they implement the Harness's native API.
| Harness / API | Example connection.baseUrl | Resulting inference URL |
|---|---|---|
| Codex / Responses | https://gateway.example/v1 | https://gateway.example/v1/responses |
| Claude Code / Messages | https://gateway.example | https://gateway.example/v1/messages |
| Kimi Code / Chat Completions | https://gateway.example/v1 | https://gateway.example/v1/chat/completions |
| ZCode / Chat Completions | https://gateway.example/api/paas/v4 | https://gateway.example/api/paas/v4/chat/completions |
Pi / openai-responses | https://gateway.example/v1 | https://gateway.example/v1/responses |
Pi / openai-completions | https://gateway.example/v1 | https://gateway.example/v1/chat/completions |
Pi / anthropic-messages | https://gateway.example | https://gateway.example/v1/messages |
For example, a gateway mounted under /models/v1 needs that prefix in its base URL. The /api/paas/v4 prefix shown for ZCode is an example, not a required path for every gateway. Use the prefix documented by your gateway for the selected API.
API format compatibility
These are the model provider's wire formats, separate from Sandpi's Session and Run API. The native Harness builds the model request and interprets the response.
| API | Request format | Response and tool format |
|---|---|---|
| OpenAI Responses | Conversation items in input; instructions and tool definitions use Responses fields | Response output items and response.* stream events; tool calls use function_call and function_call_output items |
| OpenAI Chat Completions | Conversation in messages; function tools in tools | choices with messages or streamed deltas; calls in tool_calls, with results in tool-role messages |
| Anthropic Messages | Conversation in messages; system is separate; tool schemas use input_schema | Content blocks and message/content-block stream events; tools use tool_use and tool_result blocks |
A working text-only request is not sufficient proof of Harness compatibility. Your gateway must also support the native client's streaming responses, tool calls and tool results, authentication headers, and any additional operations or extensions the installed Harness uses. Sandpi does not convert between these formats or emulate missing gateway features.
Configure and rotate
Set connection.baseUrl and connection.apiKey when creating a Session. Pi also requires connection.api; other Harnesses use a fixed native protocol and reject that setting. Optional headers are passed to the native Harness. API keys and header values are encrypted, never returned in Session reads. The key is accessible to the agent inside its Sandbox, as required for direct model access.
Use the Session connection update to rotate credentials.
Rotation applies to new Runs; queued and active Runs retain the encrypted connection revision captured at admission. Existing Sessions need a connection before new Runs can start. A Session keeps its Harness and history when its connection changes.
Use your gateway's native model ID in each Run. Sandpi does not enforce a managed model catalog. The deprecated GET /v1/models returns an empty list.
List the retired managed-model catalog (empty)
/v1/modelsRetired managed Token catalog. Returns an empty list. Select models through your native Harness and your own gateway.
Authentication: Public
Request example
curl \
"https://api.sandpi.ai/v1/models"No request body.
Responses
200 Successful response.Response body application/json
| Field | Type and constraints | Required | Description |
|---|---|---|---|
data | array | Yes | Always empty. Retained for compatibility with the retired managed-model catalog. |
data[] | object · extra fields rejected | Yeseach array item | Historical managed model catalog metadata. The deprecated models endpoint returns an empty list; native Run admission does not use this catalog. |
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[].model | string · min length 1; max length 200 | Yeseach array item | Exact native model ID served by your provider or gateway. |
data[].name | string · min length 1 | Yeseach array item | Human-readable name for this resource. |
data[].harnessIds | array · min 1 items | Yeseach array item | Historical native catalog membership; unused for BYOK Run admission. |
data[].harnessIds[] | string · values: "codex" | "claude-code" | "pi" | "kimi-code" | "zcode" | Yeseach array item | — |
data[].runtimeVerifiedHarnessIds | array | Yeseach array item | Harnesses with historical managed-model execution proof. |
data[].runtimeVerifiedHarnessIds[] | string · values: "codex" | "claude-code" | "pi" | "kimi-code" | "zcode" | Yeseach array item | — |
data[].harnessVersions | object | Yeseach array item | Map from harness ID to the exact CLI version used for discovery or verification. |
data[].harnessVersions.{key} | string | Noadditional keys | — |
data[].contextWindow | integer · > 0; ≤ 9007199254740991 | Yeseach array item | Context capacity reported by the native model definition, in tokens. |
data[].maxOutputTokens | integer · > 0; ≤ 9007199254740991 | Yeseach array item | Output capacity reported by the native model definition, in tokens. |
data[].reasoning | boolean | Yeseach array item | Whether the native model definition advertises reasoning support. |
data[].priceVersion | string | Yeseach array item | Immutable historical managed-model price version. |
data[].priceSourceUrl | string · format: uri | Yeseach array item | Official pricing reference saved for historical managed-model settlement. |
data[].priceSourceModelId | string | Noeach array item | Model identity used by the price-source snapshot when it differs from the published selector. |
data[].supplementarySourceUrl | string · format: uri | Noeach array item | Additional pricing or catalog provenance URL when provided. |
data[].ratesUsdPerMillion | object | Yeseach array item | Historical managed-model base token prices, before its saved service fee. |
data[].ratesUsdPerMillion.{key} | stringValidation pattern^\d+(?:\.\d{1,9})?$ | Noadditional keys | — |
data[].pricesCheckedAt | 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 | Time at which the published price source was last checked. |
data[].verifiedAt | string · format: date-time; nullableValidation 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 | Time of runtime compatibility verification; null for native-only entries. |
data[].serviceFeePercent | number · values: 0 | 5 | 10 | 15 | Yeseach array item | Historical managed-model service-fee tier saved with its price version. New BYOK Runs have no Sandpi model service fee. |
data[].ratesUsdPerCall | object · extra fields rejected | Noeach array item | Historical managed-model provider-tool base prices, before its saved service fee. |
data[].ratesUsdPerCall.web_search | stringValidation pattern^\d+(?:\.\d{1,9})?$ | Noeach array item | Published base price in USD per provider-hosted web search call, before the service fee. |
data[].providerAvailable | boolean | Noeach array item | Historical managed-provider configuration status; unused for BYOK Run admission. |
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"
}
}Gateway networking
Requests originate inside the Sandbox. Configure your gateway DNS, firewall and Environment network policy accordingly. Private gateways must be reachable from that network; saving their URL does not establish private connectivity. A localhost or 127.0.0.1 address refers to the Sandbox itself, not your laptop or the Sandpi control plane.
New Environments do not carry the retired managed-model provider deny rules. Existing Environments and forks retain their saved network policy, which can still block an official endpoint. If a connection fails, inspect and update the Environment's network policy through the API or console. Saving or rotating a model connection does not change outbound permissions.
The Platform connection API validates the URL shape; it does not probe credentials, check protocol compatibility or establish a private tunnel. Successfully saving a connection does not prove that its key, model ID or gateway works. Validate the connection with a Run that exercises native tool use.