Docs / SDKs / TypeScript
// TYPESCRIPT / NODE SDK
Agentics SDK — TypeScript / Node
Drop-in OpenAI-compatible client. Change one baseURL, keep your existing SDK, and every call is routed, budgeted, guarded, and lands a cryptographically verifiable receipt on the ledger.
The receipt is written server-side. The SDK never signs, hashes, or sets
billable. It attaches identity headers; the gateway's Proof Ledger writes the one verifiable parent receipt. Per-user attribution and provable savings start at your call site.
Install
shell
npm install @agentics/sdk openaiQuickstart — the baseURL swap
TypeScript
import OpenAI from "openai"; // your existing SDK, unchanged
import { createHeaders } from "@agentics/sdk";
const client = new OpenAI({
baseURL: "https://agentics.you/api/v1", // ← the only change
apiKey: process.env.AGENTICS_API_KEY, // your gateway key
defaultHeaders: createHeaders({
user: "alice@acme.com", // per-user attribution
metadata: { costCenter: "support" }, // tags into the receipt
}),
});
const resp = await client.chat.completions.create({
model: "@anthropic/claude-opus-4-8", // @provider/model routing
messages: [{ role: "user", content: "hi" }],
});
console.log(resp.response?.headers.get("x-agentics-receipt"));Or: the self-contained gateway client
No openai dependency required. AgenticsGateway uses global fetch and adds per-call withOptions(...).
TypeScript
import { AgenticsGateway } from "@agentics/sdk";
const gw = new AgenticsGateway({
baseUrl: "https://agentics.you/api/v1",
apiKey: process.env.AGENTICS_API_KEY,
});
// withOptions returns a copy with merged headers — never mutates `gw`.
const resp = await gw
.withOptions({ user: "alice@acme.com", traceId: crypto.randomUUID() })
.chat.completions.create({
model: "@anthropic/claude-opus-4-8",
messages: [{ role: "user", content: "hi" }],
});
// Streaming returns the raw ReadableStream unchanged (gateway meters server-side):
const stream = await gw.chat.completions.create({
model: "@anthropic/claude-haiku-4", messages: [...], stream: true,
});Trace & metadata headers
createHeaders() produces exactly this frozen header set (byte-identical to the Python SDK):
| Header | Maps to | Notes |
|---|---|---|
| x-agentics-trace-id | metadata.trace_id | auto-generated UUID; propagated to all child receipts |
| x-agentics-span-id | metadata.span_id | optional |
| x-agentics-user | principal_user_id | per-user attribution + budget scoping |
| x-agentics-meta | merged metadata | JSON, ≤4KB, PII-redacted server-side |
| x-agentics-debug: false | DO-NOT-TRACK | content-free metering receipt; body hashes are sentinels |
Auto-instrumentation
TypeScript
import { AgenticsGateway, LangchainCallbackHandler } from "@agentics/sdk";
const gw = new AgenticsGateway({ instrumentation: true });
const handler = new LangchainCallbackHandler({ user: "alice@acme.com" });
await chain.invoke(input, { callbacks: [handler] });Model Catalog + verify
TypeScript + CLI
import { AgenticsGateway } from "@agentics/sdk";
const gw = new AgenticsGateway();
const models = await gw.listModels({ provider: "anthropic" });
// end-to-end verification from the CLI:
// agentics proof verify <receipt_hash>
// agentics log tail --limit 5 // shows your trace_id on the ledger row
Never embed a provider key in client code. Provider keys live in Key Vault, referenced by
secret_ref in your gateway config. The only credential the SDK holds is your Agentics ak_ key (or a short-lived gw_ token). x-target overrides are validated server-side.