Route sensitive prompts through private mode
Some prompts carry data that no third party may see in plaintext. private is the routing constraint for those: the request is served only by a TeeML provider, where the model itself runs inside the enclave and the prompt is decrypted nowhere else. If no such provider is available, the request fails rather than being served by something weaker.
This page shows the header, the model choice it forces, and the failure you must handle correctly.
Prerequisites
Section titled “Prerequisites”- An account with a funded balance. See Get 0G and fund your account.
- An
sk-API key from the 0G Private Computer Console, exported asZG_API_KEY. - A working understanding of what each tier guarantees: Trust modes.
Send the header
Section titled “Send the header”Add X-0G-Provider-Trust-Mode: private to an otherwise ordinary chat completion. Header names are case-insensitive; the value must be exactly standard, verified, or private.
curl https://router-api.0g.ai/v1/chat/completions \ --max-time 120 \ --fail-with-body \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ZG_API_KEY" \ -H "X-0G-Provider-Trust-Mode: private" \ -d '{ "model": "glm-5.2", "messages": [{"role": "user", "content": "Summarize this contract clause: <YOUR_TEXT>"}] }'import OpenAI from "openai";
const apiKey = process.env.ZG_API_KEY;if (!apiKey) throw new Error("ZG_API_KEY is not set");
// Every request from this client routes to a TeeML provider or fails.const privateClient = new OpenAI({ apiKey, baseURL: "https://router-api.0g.ai/v1", timeout: 120_000, maxRetries: 0, // a 503 here must be handled explicitly, not retried blindly defaultHeaders: { "X-0G-Provider-Trust-Mode": "private", },});
async function summarizeSealed(text: string): Promise<string> { try { const res = await privateClient.chat.completions.create({ model: "glm-5.2", messages: [{ role: "user", content: `Summarize this contract clause: ${text}` }], }); return res.choices[0].message.content ?? ""; } catch (err) { if (!(err instanceof OpenAI.APIError)) throw err; const code = (err.error as { code?: string } | undefined)?.code;
if (err.status === 503 && code === "no_provider_for_trust_mode") { // No TeeML provider is serving this model right now. // Retry with backoff, or switch to another TeeML model. // Never re-send this request without the header. throw new Error("no private-tier provider available"); } throw err; }}Use defaultHeaders when the whole client handles sensitive traffic. Pass the header per call — as the second argument to create — only when one client serves mixed workloads.
import os
from openai import APIStatusError, OpenAI
api_key = os.environ["ZG_API_KEY"]
# Every request from this client routes to a TeeML provider or fails.private_client = OpenAI( api_key=api_key, base_url="https://router-api.0g.ai/v1", timeout=120.0, max_retries=0, # a 503 here must be handled explicitly, not retried blindly default_headers={"X-0G-Provider-Trust-Mode": "private"},)
def summarize_sealed(text: str) -> str: try: res = private_client.chat.completions.create( model="glm-5.2", messages=[{"role": "user", "content": f"Summarize this contract clause: {text}"}], ) return res.choices[0].message.content or "" except APIStatusError as err: body = err.response.json() code = body.get("error", {}).get("code") if err.status_code == 503 and code == "no_provider_for_trust_mode": # No TeeML provider is serving this model right now. # Retry with backoff, or switch to another TeeML model. # Never re-send this request without the header. raise RuntimeError("no private-tier provider available") from err raiseThe header is one of eight routing headers; the rest are documented in Headers.
The model must have a TeeML provider
Section titled “The model must have a TeeML provider”private routes to TeeML providers only. A model with no TeeML provider can never satisfy the request, and the Router will not substitute a weaker one — you get a 503 on every attempt, no matter how long you wait.
Two models in the catalog serve private for chat: glm-5.2 and 0gm-1.0-35b-a3b. Models reporting TeeTLS — such as glm-5 or deepseek-v4-pro — can serve verified but not private. Models with no TEE backing at all — the claude-* and gpt-5.6-* families — serve neither.
The catalog is the live source of truth, public and unauthenticated. Check it rather than a list in a document:
curl -s https://router-api.0g.ai/v1/models \ | jq '.data[] | select(.verifiability == "TeeML") | .name'Why the tiers split this way, and what TeeML proves that TeeTLS does not, is covered in Trust modes.
Expected output
Section titled “Expected output”The response shape is unchanged; the x_0g_trace block names the provider that served it.
{ "id": "chatcmpl-0852f405-6c56-40c2-a800-e6fd70785065", "object": "chat.completion", "model": "glm-5.2", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "The clause obliges..." }, "finish_reason": "stop" } ], "x_0g_trace": { "request_id": "9c58b3d7-1f42-4e69-b8a0-5d2c7e94f16b", "provider": "0xd9966e13a6026Fcca4b13E7ff95c94DE268C471C", "billing": { "input_cost": "85600000000000", "output_cost": "285760000000000", "total_cost": "371360000000000" } }}When no TeeML provider is free, the request fails instead:
{ "error": { "message": "failed to select provider: no provider available for the requested trust mode: tier=private", "type": "server_error", "code": "no_provider_for_trust_mode" }, "request_id": "4a17e6c5-3b98-4f02-9d7e-8c1a5b6f2049"}Live response, 2026-07-20.
Handle 503 no_provider_for_trust_mode
Section titled “Handle 503 no_provider_for_trust_mode”This is a supply condition, not a permissions problem or a malformed request. Two correct responses:
- Retry with backoff, if the workload tolerates delay and you expect supply to return.
- Switch to another TeeML model for that request, if the work can be done by a different model.
An invalid value returns 400 invalid_trust_mode instead. That is a bug in your code, and retrying it unchanged will never succeed.
Enforce it on the key instead
Section titled “Enforce it on the key instead”A trust mode can also be attached to the API key. In the Console, open Dashboard → API Keys and set the key’s trust mode. Programmatically, create the key with trust_mode, which requires an mk- management key with the appropriate scope:
curl https://router-api.0g.ai/v1/api-keys \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ZG_MANAGEMENT_KEY" \ -d '{"name":"sealed-prod","trust_mode":"private"}'A per-key trust mode is enforced on every request made with that key, whatever the calling code sends. The header cannot weaken it. That is the point: hand a service a key that is structurally incapable of routing outside the enclave and the guarantee survives a bug in that service.
Use the header when one service handles mixed workloads under your control. Use the key when the guarantee is a property of the deployment.
What private mode guarantees, and how to check it
Section titled “What private mode guarantees, and how to check it”Under private, the prompt enters the enclave as ciphertext, is decrypted only inside it, and the response is signed inside it. Neither 0G nor the operator of the hardware sees the plaintext. Inference content is not retained after the request completes.
That is a claim you do not have to take on faith. Each response carries a TEE signature you can check yourself, against the chain and the provider rather than against the Router. See Verify a response.
Common errors
Section titled “Common errors”| Status | code |
Cause | Fix |
|---|---|---|---|
| 400 | invalid_trust_mode |
Value is not standard, verified, or private |
Fix the value; do not retry unchanged |
| 400 | invalid_provider_header |
Another X-0G-Provider-* header has an illegal value |
See Headers |
| 401 | invalid_api_key |
Bad, revoked, or mk- key on an inference call |
Use a live sk- key |
| 402 | insufficient_balance |
Deposit exhausted | Top up, then retry |
| 429 | rate_limit_exceeded |
Too many requests | Wait for Retry-After seconds |
| 503 | no_provider_for_trust_mode |
No TeeML provider serving this model right now | Back off, or switch to another TeeML model |
Full list with retry guidance: Error codes.
Next steps
Section titled “Next steps”- Verify a response — prove the response really came from the enclave
- Trust modes — what
standard,verified, andprivateeach buy you - Headers — the full
X-0G-Provider-*reference