sandpi/ platform

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.

HarnessNative model APIProtocol selection
CodexOpenAI ResponsesFixed; omit connection.api
Claude CodeAnthropic MessagesFixed; omit connection.api
Kimi CodeNative OpenAI-compatible Chat CompletionsFixed; omit connection.api
ZCodeNative OpenAI-compatible Chat CompletionsFixed; omit connection.api
PiOpenAI ResponsesSet connection.api to openai-responses
PiOpenAI Chat CompletionsSet connection.api to openai-completions
PiAnthropic MessagesSet 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 / APIExample connection.baseUrlResulting inference URL
Codex / Responseshttps://gateway.example/v1https://gateway.example/v1/responses
Claude Code / Messageshttps://gateway.examplehttps://gateway.example/v1/messages
Kimi Code / Chat Completionshttps://gateway.example/v1https://gateway.example/v1/chat/completions
ZCode / Chat Completionshttps://gateway.example/api/paas/v4https://gateway.example/api/paas/v4/chat/completions
Pi / openai-responseshttps://gateway.example/v1https://gateway.example/v1/responses
Pi / openai-completionshttps://gateway.example/v1https://gateway.example/v1/chat/completions
Pi / anthropic-messageshttps://gateway.examplehttps://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.

APIRequest formatResponse and tool format
OpenAI ResponsesConversation items in input; instructions and tool definitions use Responses fieldsResponse output items and response.* stream events; tool calls use function_call and function_call_output items
OpenAI Chat CompletionsConversation in messages; function tools in toolschoices with messages or streamed deltas; calls in tool_calls, with results in tool-role messages
Anthropic MessagesConversation in messages; system is separate; tool schemas use input_schemaContent 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)

GET /v1/models

Retired managed Token catalog. Returns an empty list. Select models through your native Harness and your own gateway.

Authentication: Public

Request example

sh
curl \
    "https://api.sandpi.ai/v1/models"

No request body.

Responses

200 Successful response.
Response body application/json
FieldType and constraintsRequiredDescription
dataarrayYesAlways empty. Retained for compatibility with the retired managed-model catalog.
data[]object · extra fields rejectedYeseach array itemHistorical managed model catalog metadata. The deprecated models endpoint returns an empty list; native Run admission does not use this catalog.
data[].providerstring · values: "openai" | "anthropic" | "kimi" | "zai" | "deepseek"Yeseach array itemNative model family associated with this Harness; not a Sandpi Token supplier.
data[].modelstring · min length 1; max length 200Yeseach array itemExact native model ID served by your provider or gateway.
data[].namestring · min length 1Yeseach array itemHuman-readable name for this resource.
data[].harnessIdsarray · min 1 itemsYeseach array itemHistorical native catalog membership; unused for BYOK Run admission.
data[].harnessIds[]string · values: "codex" | "claude-code" | "pi" | "kimi-code" | "zcode"Yeseach array item—
data[].runtimeVerifiedHarnessIdsarrayYeseach array itemHarnesses with historical managed-model execution proof.
data[].runtimeVerifiedHarnessIds[]string · values: "codex" | "claude-code" | "pi" | "kimi-code" | "zcode"Yeseach array item—
data[].harnessVersionsobjectYeseach array itemMap from harness ID to the exact CLI version used for discovery or verification.
data[].harnessVersions.{key}stringNoadditional keys—
data[].contextWindowinteger · > 0; ≤ 9007199254740991Yeseach array itemContext capacity reported by the native model definition, in tokens.
data[].maxOutputTokensinteger · > 0; ≤ 9007199254740991Yeseach array itemOutput capacity reported by the native model definition, in tokens.
data[].reasoningbooleanYeseach array itemWhether the native model definition advertises reasoning support.
data[].priceVersionstringYeseach array itemImmutable historical managed-model price version.
data[].priceSourceUrlstring · format: uriYeseach array itemOfficial pricing reference saved for historical managed-model settlement.
data[].priceSourceModelIdstringNoeach array itemModel identity used by the price-source snapshot when it differs from the published selector.
data[].supplementarySourceUrlstring · format: uriNoeach array itemAdditional pricing or catalog provenance URL when provided.
data[].ratesUsdPerMillionobjectYeseach array itemHistorical managed-model base token prices, before its saved service fee.
data[].ratesUsdPerMillion.{key}string
Validation pattern^\d+(?:\.\d{1,9})?$
Noadditional keys—
data[].pricesCheckedAtstring · format: date-time
Validation 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 itemTime at which the published price source was last checked.
data[].verifiedAtstring · format: date-time; nullable
Validation 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 itemTime of runtime compatibility verification; null for native-only entries.
data[].serviceFeePercentnumber · values: 0 | 5 | 10 | 15Yeseach array itemHistorical managed-model service-fee tier saved with its price version. New BYOK Runs have no Sandpi model service fee.
data[].ratesUsdPerCallobject · extra fields rejectedNoeach array itemHistorical managed-model provider-tool base prices, before its saved service fee.
data[].ratesUsdPerCall.web_searchstring
Validation pattern^\d+(?:\.\d{1,9})?$
Noeach array itemPublished base price in USD per provider-hosted web search call, before the service fee.
data[].providerAvailablebooleanNoeach array itemHistorical managed-provider configuration status; unused for BYOK Run admission.
Example
Example
{
  "data": []
}
Error responses
default Sandpi error.
Error body application/json

Standard error envelope containing a stable code, diagnostic message and request identity.

FieldType and constraintsRequiredDescription
errorobject · extra fields rejectedYesStructured failure information. Inspect the stable code and retain the request ID for investigation.
error.codestringYeswithin errorStable error code used to distinguish failures programmatically.
error.messagestringYeswithin errorHuman-readable diagnostic text.
error.requestIdstringYeswithin errorRequest identifier for correlating diagnostics and support investigations.
error.detailsanyNowithin errorOptional structured error context. Its shape is specific to the service failure.
error.loginUrlstringNowithin errorAuthentication URL supplied when a browser login is required.
error.registrationOpenbooleanNowithin errorWhether new account registration is enabled for this deployment.
Example
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.