attestify-os-sdk
v0.2.0
Published
Official TypeScript SDK for Attestify OS — add governed lane execution in a few lines, or prove what a wallet-free agent did with Attestify Trust.
Downloads
349
Maintainers
Readme
attestify-os-sdk — TypeScript / JavaScript
Add governed lane execution to any codebase in a few lines.
Install
npm install attestify-os-sdk
# or
yarn add attestify-os-sdkWhile the package is in early access, install directly from the repo:
npm install "https://gitpkg.now.sh/attestifyagent/attestify-os/sdk/typescript?main"Build from source
cd sdk/typescript
npm install
npm run build # compiles index.ts → dist/Quick start
import { createClient } from 'attestify-os-sdk';
const attestify = createClient({
apiKey: process.env.ATTESTIFY_API_KEY!,
});
const result = await attestify.runLane({
laneId: 'researcher-v2',
input: 'Summarise the latest advances in quantum error correction.',
sessionId: 'my-session-001',
options: { verify: true, write_memory: true },
});
console.log(result.output); // lane response text
console.log(result.receipt.run_id); // unique run identifier
console.log(result.receipt.evidence); // full evidence bundle
console.log(result.receipt.pricing.price_usdc); // cost in USDCFeatures
createClient({ apiKey })— configure once, use anywhererunLane({ laneId, input, context })— single call handles sessions, retries, and idempotency- Receipts as first-class objects — every run returns a typed
RunReceiptwith evidence, verification, pricing, and settlement - Auto-routing — omit
laneIdand Attestify picks the best lane for the task - Idempotency — pass
idempotencyKeyto guarantee exactly-once execution - Budget constraints — pass
constraints.max_cost_usdcto cap spend per run - Webhook support — pass
options.webhook_urlfor async result delivery
API Reference
createClient(options)
| Option | Type | Default | Description |
|---|---|---|---|
| apiKey | string | required | Your Attestify API key |
| baseUrl | string | https://attestifyos.com | Override the endpoint |
| maxRetries | number | 2 | Retries on 5xx errors |
| timeoutMs | number | 60000 | Per-attempt timeout in ms |
client.runLane(options)
| Option | Type | Description |
|---|---|---|
| input | string | Required. The task or intent |
| laneId | LaneId | Optional — omit to auto-route |
| sessionId | string | Memory / conversation continuity |
| idempotencyKey | string | Prevents duplicate charges |
| context | object | Extra context forwarded to the lane |
| constraints | object | Budget / SLA constraints |
| options | object | verify, write_memory, include_memory, webhook_url |
Returns Promise<{ output: string, receipt: RunReceipt, raw: object }>.
constraints fields:
constraints: {
max_cost_usdc: 0.05, // abort if estimated cost exceeds this
max_latency_ms: 10000, // abort if estimated latency exceeds this
budget_id: 'proj-abc', // link to a named budget envelope
}options fields:
options: {
verify: true, // run output verification (default false)
write_memory: true, // persist session memory (default false)
include_memory: true, // inject prior memory into context
webhook_url: 'https://...' // async result delivery
}client.authorize(intent) — authority envelopes
Request a signed, server-enforced authority envelope before running one or more
governed actions. runLane({ envelope }) attaches it; /api/run verifies the
signature, tenant/agent binding, expiry, live-policy epoch, and remaining
action count / spend cap before every run, and atomically consumes one action.
const envelope = await attestify.authorize({
agentId: 'analyst-v1',
intent: 'batch-report-generation',
riskClass: 'low',
maxSpendUsd: 0.50,
actionCount: 20, // this envelope authorises up to 20 actions
expiryWindowS: 300, // capped at 3600s server-side
});
const result = await attestify.runLane({
laneId: 'analyst-v1',
input: 'Summarise Q2 revenue trends.',
envelope,
});The client caches non-Enterprise envelopes locally and reuses them until the
action count or expiry window is exhausted. If the agent's policy has
per_action_mode enabled, the server forces actionCount=1 and
expiryWindowS=0 and the SDK never caches the result — every action gets a
fresh envelope. A stale envelope (policy changed since issue) is rejected with
HTTP 409; call authorize() again to obtain a fresh one.
client.getReceipt(loopId)
Fetch a stored receipt by its loop_id.
const receipt = await attestify.getReceipt('loop_abc123');
console.log(receipt.verification); // grade, score, output_hash
console.log(receipt.settlement); // on-chain tx hash if x402 usedAttestify Trust — no wallet, ever
Prove what a wallet-free agent did. attestify.trust is a completely
separate surface from everything above — no lanes, no x402, no gas, at any
point. The private signing key never leaves your process; only a public
key and signatures are ever sent to Attestify.
// 1. Generate a keypair once, store the private key yourself (env var,
// secrets manager — the same way you'd hold any other API secret).
const { publicKey, privateKey } = attestify.trust.generateKeyPair();
// 2. Register the agent and its key.
const agent = await attestify.trust.createAgent({ displayName: 'Invoice Bot' });
await attestify.trust.registerKey(agent.id, publicKey);
// 3. Sign and submit evidence for real work the agent did.
const receipt = await attestify.trust.submitEvidence(
{
agentId: agent.id,
schema: 'work-completion/v1',
payload: { summary: 'Extracted 3 line items from a sample invoice' },
actionBasis: 'discretionary', // did this on its own initiative, not because it was told to
},
privateKey,
);
// 4. Anyone can verify it — no API key required.
const result = await attestify.trust.verify(receipt.id);
console.log(result.integrity_verified); // trueclient.trust.generateKeyPair()
Generates a local Ed25519 keypair. Synchronous, no network call. Returns
{ publicKey, privateKey }, both base64url-encoded.
client.trust.createAgent(input?)
| Option | Type | Description |
|---|---|---|
| displayName | string | Optional, private — never shown to a verifier |
| framework | string | e.g. "langchain", "crewai" |
| industry | string | Self-reported |
| country | string | Self-reported |
Returns Promise<TrustAgent>.
client.trust.registerKey(agentId, publicKey)
Registers (or rotates) the Ed25519 signing key for an agent. Returns
Promise<TrustKeyVersion>.
client.trust.submitEvidence(input, privateKey)
| Option | Type | Description |
|---|---|---|
| agentId | string | Required |
| schema | string | Required — e.g. "work-completion/v1" |
| payload | object | Required — bounded to 16KB |
| actionBasis | 'explicit' \| 'discretionary' | Default 'explicit' |
| nonce | string | Default: a random value — override only for a specific replay-defence need |
Canonicalizes and signs the event locally with privateKey, then submits
it. Returns Promise<TrustReceipt> — an immutable, signed record with a
content hash, not the raw evidence.
client.trust.verify(receiptId)
Public, no API key sent. Independently recomputes the receipt's hash and
re-verifies the signature server-side on every call — not just an echo of
what's stored. Returns Promise<TrustVerifyResult> with
integrity_verified: boolean.
client.trust.getReceipt(receiptId)
Your own tenant's full receipt detail (requires the API key that created
it). Use verify() instead for the public, redacted view anyone can check.
Available lanes
| laneId | Description |
|---|---|
| researcher-v2 | Deep research and synthesis |
| analyst-v1 | Data analysis and structured output |
| coder-v1 | Code generation and review |
| writer-v1 | Long-form and structured writing |
| strategist-v1 | Strategic planning and frameworks |
| support-v1 | Customer support and triage |
| comedian-v1 | Creative and entertainment tasks |
Omit laneId entirely to let Attestify auto-route.
Environment variables
ATTESTIFY_API_KEY=atst_live_...