SDKs
Two official SDKs wrap the OpenAI client for TypeScript and Python,
pre-configured for
https://www.saxeonetwork.tech/__api/v1, and add helpers for the Saxeo-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 Saxeo is the OpenAI client with a
different base URL.
Two more client packages ship alongside them: a CLI and a framework middleware. All four are listed below.
None of the four is published to npm or PyPI yet. Install them from the
repository's sdk/ 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.
| Package | What it is | Path |
|---|---|---|
@sable-network/sdk | What it isThe TypeScript client (extends the OpenAI client) | Pathsdk/ts/ |
sable-network | What it isThe Python client (wraps openai) | Pathsdk/python/ |
@sable-network/cli | What it issaxeo on the command line: chat, run code, check credit, verify a receipt | Pathsdk/cli/ |
@sable-network/middleware | What it isA zero-dependency fetch adapter that points any fetch-based framework at Saxeo and captures the receipt | Pathsdk/middleware/ |
TypeScript: @sable-network/sdk
Saxeo extends the OpenAI client, so the whole OpenAI surface is inherited.
import { Saxeo, SaxeoError } from "@sable-network/sdk";
const client = new Saxeo({ apiKey: process.env.SAXEO_API_KEY! });
// The OpenAI surface, unchanged:
const resp = await client.chat.completions.create({
model: "saxeo-llama-3.3-70b",
messages: [{ role: "user", content: "hi" }],
});
// Saxeo 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(...) | What it doesOpenAI-compatible chat, inherited from the base client. See Chat completions. |
embeddings.create(...) | What it doesOpenAI-compatible embeddings, inherited. See Embeddings. |
runCode({...}) | What it doesRun code in a metered sandbox via POST /v1/sandboxes. See Sandbox compute. |
credit() | What it doesThe calling key's balance via GET /v1/credit, so an agent can see its runway over REST. |
delegateKey({...}) | What it doesMint a bounded child of the calling key. See Delegated sub-keys. |
chatWithReceipt({...}) | What it doesA non-streaming completion plus its signed receipt, captured from the response headers in one call. |
verifyReceipt(...) | What it doesExported helper: verify a signed receipt through the public POST /v1/receipts/verify. See Verifiable receipts. |
verifyReceiptLocally(...) | What it doesExported helper: verify a receipt offline against a pinned signer address (EIP-191 recovery via @noble, no network, no trusting the party being verified). |
verifyAttestation() | What it doesExported helper: pre-flight check of the live confidential attestation via GET /v1/attestation. See Privacy tiers. |
xPaymentHeader(...) / settleWith(...) | What it doesExported 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 Saxeo methods in
snake_case.
from sable_network import Saxeo, SaxeoError
client = Saxeo(api_key=SAXEO_API_KEY)
# The OpenAI surface, unchanged:
resp = client.chat.completions.create(
model="saxeo-llama-3.3-70b",
messages=[{"role": "user", "content": "hi"}],
)
# Saxeo extensions:
run = client.run_code(language="python", code="print(6*7)")
credit = client.credit()| Method | What it does |
|---|---|
chat.completions.create(...) | What it doesOpenAI-compatible chat, inherited. |
embeddings.create(...) | What it doesOpenAI-compatible embeddings, inherited. |
run_code(...) | What it doesRun code in a metered sandbox. |
credit() | What it doesThe calling key's balance and runway. |
delegate_key(...) | What it doesMint a bounded child key. |
chat_with_receipt(...) | What it doesA non-streaming completion plus its signed receipt in one call. |
verify_receipt(...) | What it doesModule helper: verify a signed receipt through the public endpoint. |
verify_receipt_locally(...) | What it doesModule helper: verify a receipt offline against a pinned signer. Needs the optional extra: pip install "sable-network[verify]". |
verify_attestation() | What it doesPre-flight the live confidential attestation. |
x_payment_header(...) | What it doesModule helper: build the X-PAYMENT header for inline x402 settlement. |
Error handling
Both SDKs raise a SaxeoError that keeps the gateway's error information
intact. The case worth branching on is credit exhaustion: an out-of-credit
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. Both are true only for
type: "insufficient_credit", which is deliberate — three unrelated conditions
answer 402, and the other two (a spend cap reached, a
circuit breaker tripped, type: "circuit_breaker_tripped")
carry no terms and are not clearable by paying. Settling on those funds the
runaway the breaker exists to stop, so branch on the predicate, never on the
status code. 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 SaxeoError && 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://www.saxeonetwork.tech/__api/v1" covers chat and embeddings (see the
Quickstart), and every Saxeo extension is reachable as an
ordinary HTTP call.