Direct API
Build your own client for the broker and encrypted Room protocol. You use the same API key, model catalog and billing as SDK and CLI users, without depending on either client.
This is the protocol integration path. For a ready-to-use library, see SDK; to connect an existing tool, see CLI.
Two addresses, different responsibilities
https://api.turboprivate.ai is an authenticated broker, not a plaintext inference gateway. It authenticates accounts and allocates Rooms. The allocation response supplies the Room address used for encrypted model traffic.
/v1 paths. OpenAI and Anthropic compatibility endpoints are local adapters supplied by the SDK or CLI on 127.0.0.1; the Room itself remains remote.Broker contract
| Method | Path | Purpose |
|---|---|---|
| GET | /api/config | Read model IDs, controls and trust policy. |
| GET | /api/status | Check current model availability. |
| POST | /api/keys/token | Exchange an API key for a short-lived account token. |
| POST | /api/session/start | Allocate a Room using a client-created capability hash. |
| GET | /openapi.json | Read the machine-readable broker schema. |
Use Authorization: Bearer <API-key-or-account-token> for authenticated broker requests. Read the OpenAPI contract for the broker operations and allocation request schema. That document covers the broker; it does not replace the encrypted Room protocol.
Allocation request
Send JSON to /api/session/start with these fields. Obtain model IDs and legal control values from /api/config.
| Field | Value |
|---|---|
model | The chosen public model ID. |
grantHash | Lowercase SHA-256 hex of the UTF-8 string turboprivate/grant/v1/ followed by a client-generated capability: 24 random bytes encoded as base64url. Keep the capability secret. |
profile | MODEL_COMPUTE. |
trustClass | ROOM_TRANSIT_ONLY for encrypted transit. Requesting ROOM_TEE_VERIFIED requires eligible verified capacity; never silently lower this requirement after a failure. |
controls | Optional object containing only controls supported by the chosen model. |
The allocation response includes sessionId, backendUrl, normalized model settings and a descriptor with signed lifecycle data. Allocation is not yet a verified model connection: complete the challenge below before sending content.
Room lifecycle
- Prepare access. Select a live model and supported controls. Generate a cryptographically random capability on the client; only its protocol-defined hash belongs in the allocation request. Retain the secret locally.
- Allocate. Call
/api/session/start. Validate the returned session descriptor, Room address and declared trust policy before using them. - Challenge and verify. Send a fresh nonce to the Room's
/session/{sessionId}/attestendpoint. Check the nonce, capability binding, expected measurement and signed lifecycle. Reject invalid reports before sending model content. - Encrypt and request. Use the verified Room key material to establish hybrid X25519 + ML-KEM-768 keys. Send the encrypted request envelope to
/session/{sessionId}/chat. Authenticate and decrypt each response frame, then verify the signed receipt against this request and response. - Close. Call
/session/{sessionId}/end, check the cleanup response and preserve any signed acknowledgment you need. A failed close is not confirmation of cleanup.
Room requests use the client-created capability in the x-grant header over HTTPS. Do not send your long-lived account key to the Room or place capabilities in URLs or logs.
Encoding and compatibility
A compatible client must follow the exact wire format, not just the sequence above. The published JavaScript package includes the protocol implementation under vendor/lib/room/: protocol.mjs for cryptographic framing, client-contract.mjs for message validation, attestation.mjs for trust checks, client.mjs for the exchange and session-proof.mjs for exported evidence. These are the same client modules used by the SDK.
Use those published definitions when implementing serialization, capability hashing, key derivation, stream termination and receipt commitments. The broker OpenAPI schema alone is insufficient to implement encrypted inference. Never invent a substitute encoding or skip signature checks to make a request succeed.
Context and cached input
Send the full required context in each encrypted request. A Room does not restore earlier messages automatically. Context & caching defines prefix reuse, the signed receipt's usage fields and account isolation, with examples shared by direct and SDK clients.
Failure handling
The allocated descriptor defines both a token-independent byte limit and a request lane limit. The maximum request size is the smaller of descriptor.resources.max_frame_bytes and the REQUEST lane's max_frame_bytes. Count UTF-8 bytes of the complete decrypted JSON request, including parameters and operation metadata. A model's advertised token window does not increase this transport limit. Oversized input returns 413 request_too_large before model dispatch or a usage reservation.
Account failures distinguish usage_reservation_unavailable, usage_release_unavailable, usage_settlement_unavailable and usage_recovery_unavailable. Settlement can fail after partial output: that output is not a completed response without a valid signed receipt and terminal frame. Do not replay it automatically; the service retains the pending accounting action for reconciliation.
Handle authentication, insufficient balance, unavailable capacity and protocol validation as distinct failures. Reject malformed or unauthenticated frames. Do not merge partial responses from different Rooms or silently retry completed work. Each request can consume credits; see Pricing & billing and Troubleshooting.
See Privacy proofs for what signatures establish and what still depends on the host's trust level.