sablenetwork
Documentation — all sections

Verifiable receipts

Every chat completion and embedding comes with a signed receipt: a small, metadata-only attestation that Sable served the request, on which node, in which region, under which tier — signed with secp256k1 so anyone can verify it without trusting us. The receipt proves that inference happened and how; it never carries the prompt or completion.

What you get back

Non-streaming POST /v1/chat/completions and POST /v1/embeddings responses add four headers:

curl -i https://api.buildsable.com/v1/chat/completions \
-H "Authorization: Bearer $SABLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
  "model": "sable-llama-3.3-70b",
  "messages": [{"role":"user","content":"hi"}]
}'

# ... response headers ...
# x-sable-region: eu-central
# x-sable-receipt: eyJ2IjoxLCJyZXF1ZXN0X2lkIjoi...
# x-sable-receipt-sig: 0x4f8c...1b
# x-sable-receipt-signer: 0xA1b2...9F

The receipt payload

Base64url-decode x-sable-receipt and you get canonical JSON. It is metadata only — note content_fingerprint, a SHA-256 over the sealed payload, not the content itself.

{
  "v": 1,
  "request_id": "req_8f3c...",
  "content_fingerprint": "9b1c4e...",
  "model": "sable-llama-3.3-70b",
  "privacy_tier": "confidential",
  "node": "sable-node-fra-1",
  "region": "eu-central",
  "prompt_tokens": 12,
  "completion_tokens": 48,
  "total_tokens": 60,
  "cost_micro_usd": 540,
  "logging": "metadata-only",
  "issued_at": "2026-05-30T12:00:00Z"
}

The fingerprint lets you bind a receipt to a specific request you made (hash your own sealed envelope and compare) without ever exposing the plaintext to the receipt itself. cost_micro_usd is the metered cost in millionths of a dollar — see Cost & metering.

Confidential-tier attestation

A request on the confidential tier (today, sable-confidential-24b) adds an attestation block — also metadata only — proving it ran inside an attested Intel TDX enclave. Standard-tier receipts omit it entirely.

{
  "attestation": {
    "platform": "nvidia-cc",
    "measurement": "3b6dd335…",
    "mrtd": "f06dfda6…",
    "tcb_status": "UpToDate",
    "verification": "tee-attested",
    "response_bound": true,
    "signer": "0x79a5061e…"
  }
}

The gateway verifies the enclave's TDX quote against a pinned measurement before routing, and verifies a per-response signature from the key bound into that quote after — so verification: "tee-attested" with response_bound: true means this specific response came from a correctly-measured enclave the host couldn't see into. The public GET /v1/attestation returns the live verified status, and the SDK's verifyAttestation() checks it as a pre-flight before you send anything.

Streaming

A streamed chat completion can't set trailing headers, so the receipt arrives as the final SSE event after the stream ends:

event: sable.receipt
data: {"receipt":"eyJ2Ijox...","signature":"0x4f8c...","signer":"0xA1b2...9F"}

Read it the same way you'd read the headers: base64url-decode receipt for the payload, verify signature against signer.

Verifying a receipt

Because receipts use standard secp256k1 + EIP-191, any Ethereum signature library verifies them. Recover the signer over the decoded payload string (atob(receipt)) and check it equals x-sable-receipt-signer.

import { verifyMessage } from "viem";

// receipt = x-sable-receipt, signature = x-sable-receipt-sig,
// signer  = x-sable-receipt-signer
async function verifyReceipt(
receipt: string,
signature: `0x${string}`,
signer: `0x${string}`,
): Promise<boolean> {
const payload = atob(receipt); // base64url -> canonical JSON string
return verifyMessage({ address: signer, message: payload, signature });
}

// ethers works too:
//   ethers.verifyMessage(payload, signature) === signer

Verify endpoints

Two public endpoints (no auth) help you verify without wiring up crypto yourself:

The signing key is derived from the deployment's master key, so the signer address is stable per deployment — fetch it once from /v1/receipts/pubkey, pin it, and reject any receipt that recovers to a different address.