← All docs

SDK reference

One class. Three primary methods. Fail-open by default.

new Cisora({ apiKey, agentName, ... })

Constructs a client. Call once at agent startup, ideally at module load.

const cisora = new Cisora({
  apiKey: process.env.CISORA_API_KEY!,
  agentName: 'customer-support-bot',
  baseUrl:  'https://cisora.io',  // optional
  failOpen: true,                  // default — never block your agent
  enabled:  true,                  // set false to disable in tests
});

cisora.check({ action_type, tool_name, metadata })

Synchronous policy decision. THIS is the unique thing Cisora gives you — block actions BEFORE they execute, not after the audit.

const { decision, reason } = await cisora.check({
  action_type: 'tool_call',
  tool_name: 'database_write',
  metadata: { table: 'users', field: 'email' }
});

if (decision !== 'allow') {
  throw new Error(`Cisora ${decision}: ${reason}`);
}
// Cisora just prevented a PII leak before it shipped.

cisora.tool(name, fn, opts?)

Wrap any tool call. Cisora captures inputs, outputs, duration, decision — automatically.

const result = await cisora.tool('send_email', async () => {
  return resend.emails.send({ from, to, subject, html });
}, { metadata: { recipient: to } });

cisora.modelCall(model, fn, opts?)

Wrap any LLM invocation. You keep using your own Anthropic/OpenAI/Bedrock key — Cisora just records the call.

const reply = await cisora.modelCall('claude-sonnet-4-5', () =>
  anthropic.messages.create({ model: 'claude-sonnet-4-5', messages })
);

cisora.externalApi(name, fn, opts?)

Wrap any third-party API call (Stripe, Slack, your internal services). Same capture as tool/modelCall.

await cisora.externalApi('stripe.charges.create', () =>
  stripe.charges.create({ amount, currency, source })
);

cisora.flush()

Force-send queued events. Required in short-lived scripts before process exit.

await cisora.flush();

LangChain auto-instrumentation

Using LangChain? Skip the manual wrapping. Drop in one callback handler and every LLM, tool, and chain run inside that run is captured automatically.

import { Cisora } from '@cisora/sdk';
import { CisoraLangChainHandler } from '@cisora/sdk/langchain';

const cisora = new Cisora({ apiKey: process.env.CISORA_API_KEY!, agentName: 'support-bot' });
const handler = new CisoraLangChainHandler(cisora);

// One callback. Captures every LLM call, every tool call, every chain run.
const result = await chain.invoke(input, { callbacks: [handler] });

Works with @langchain/core, langchain, @langchain/anthropic, @langchain/openai, LangGraph, and any framework that accepts LangChain callbacks. @langchain/core is an optional peer dependency — only loaded if you have it installed.

Python SDK

Identical surface, idiomatic Python (context managers instead of callbacks).

from cisora import Cisora

cisora = Cisora(api_key=os.environ["CISORA_API_KEY"],
                agent_name="customer-support-bot")

# check() returns the same shape
decision = cisora.check(action_type="tool_call", tool_name="db_write")

# wrap with context managers
with cisora.tool("send_email", metadata={"to": email}) as call:
    result = send_email(...)
    call.outputs = result

Full source: packages/sdk-ts · packages/sdk-py