Portal
Documentation: all sections

SDKs

Two official SDKs wrap the OpenAI client, pre-configured for https://api.buildsable.com/v1, and add helpers for the Sable-specific surface: sandbox runs, credit, delegated sub-keys, and receipt and attestation verification. Everything the OpenAI client can do (chat, embeddings, streaming) works unchanged, because Sable is the OpenAI client with a different base URL.

Neither SDK is published to npm or PyPI yet. Install them from the repository's sdk/ts and sdk/python directories for now. Publishing is planned, not done, and we'd rather say so than have you hunt for a package that isn't there.

TypeScript: @sable-network/sdk

Sable extends the OpenAI client, so the whole OpenAI surface is inherited.

import { Sable, SableError } from "@sable-network/sdk";

const client = new Sable({ apiKey: process.env.SABLE_API_KEY! });

// The OpenAI surface, unchanged:
const resp = await client.chat.completions.create({
model: "sable-llama-3.3-70b",
messages: [{ role: "user", content: "hi" }],
});

// Sable extensions:
const run = await client.runCode({ language: "python", code: "print(6*7)" });
const credit = await client.credit(); // this key's balance and runway
MethodWhat it does
chat.completions.create(...)OpenAI-compatible chat, inherited from the base client. See Chat completions.
embeddings.create(...)OpenAI-compatible embeddings, inherited. See Embeddings.
runCode({...})Run code in a metered sandbox via POST /v1/sandboxes. See Sandbox compute.
credit()The calling key's balance via GET /v1/credit, so an agent can see its runway over REST.
delegateKey({...})Mint a bounded child of the calling key. See Delegated sub-keys.
chatWithReceipt({...})A non-streaming completion plus its signed receipt, captured from the response headers in one call.
verifyReceipt(...)Exported helper: verify a signed receipt through the public POST /v1/receipts/verify. See Verifiable receipts.
verifyReceiptLocally(...)Exported helper: verify a receipt offline against a pinned signer address (EIP-191 recovery via @noble, no network, no trusting the party being verified).
verifyAttestation()Exported helper: pre-flight check of the live confidential attestation via GET /v1/attestation. See Privacy tiers.
xPaymentHeader(...) / settleWith(...)Exported helpers: build the X-PAYMENT header for inline x402 settlement. See Paying with USDT.

Requests carry sensible default timeouts (per-call timeoutMs override), so a hung gateway call fails instead of blocking an agent forever.

Python: sable-network

The same shape: a wrapper around openai-python, plus the Sable methods in snake_case.

from sable_network import Sable, SableError

client = Sable(api_key=SABLE_API_KEY)

# The OpenAI surface, unchanged:
resp = client.chat.completions.create(
  model="sable-llama-3.3-70b",
  messages=[{"role": "user", "content": "hi"}],
)

# Sable extensions:
run = client.run_code(language="python", code="print(6*7)")
credit = client.credit()
MethodWhat it does
chat.completions.create(...)OpenAI-compatible chat, inherited.
embeddings.create(...)OpenAI-compatible embeddings, inherited.
run_code(...)Run code in a metered sandbox.
credit()The calling key's balance and runway.
delegate_key(...)Mint a bounded child key.
chat_with_receipt(...)A non-streaming completion plus its signed receipt in one call.
verify_receipt(...)Module helper: verify a signed receipt through the public endpoint.
verify_receipt_locally(...)Module helper: verify a receipt offline against a pinned signer. Needs the optional extra: pip install "sable-network[verify]".
verify_attestation()Pre-flight the live confidential attestation.
x_payment_header(...)Module helper: build the X-PAYMENT header for inline x402 settlement.

Error handling

Both SDKs raise a SableError that keeps the gateway's error information intact. The case worth branching on is credit exhaustion: a 402 carries x402 payment terms, and the error exposes them so an agent can settle and retry: isInsufficientCredit in TypeScript, is_insufficient_credit in Python. See Paying with USDT for what the terms contain and how settlement works. On a 429, the error also carries the Retry-After value (retryAfterSecs / retry_after_secs), so a backoff loop doesn't have to guess.

try {
await client.chat.completions.create({ /* ... */ });
} catch (err) {
if (err instanceof SableError && err.isInsufficientCredit) {
  // err carries the 402's x402 "accepts" terms; settle, then retry.
}
throw err;
}

If you'd rather not take a dependency at all, the plain OpenAI SDK with base_url="https://api.buildsable.com/v1" covers chat and embeddings (see the Quickstart), and every Sable extension is reachable as an ordinary HTTP call.