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| Method | What 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()| Method | What 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.