Developers
Quickstart
From an empty account to a traced, policy-evaluated action: create an organization and an API key, connect an AI system, send an event, write a policy.
Six steps
- 01Create an organization
- 02Issue a scoped key
- 03Install the SDK
- 04Register your AI system
- 05Evaluate an action
- 06Watch it refuse
Nothing here deploys anything. Nothing changes in your systems until step 5 returns an authorization and your code chooses to honour it.
Before the steps
This is the setup path. The concepts are next door.
Six steps from an empty account to a decision you can see, ending on a refusal rather than a success. If you already have an account and want the conceptual loop — connect, register, write a policy, evaluate, trace — the documentation quickstart is the one to read.
You are on the right page if
- You want an API key and a working call today.
- You have an AI system already running that takes an action.
- You want to see a refusal before you trust an authorization.
Read the other one if
- You want to understand what a policy is before writing one.
- You want the six trace stages explained.
- You are evaluating the model rather than the API.
The setup
Six steps, and the last one is the interesting one.
Everything before step 5 is credentials and registration. Step 5 is the loop, and step 6 is the half of it most quickstarts leave out.
01
Create an organization
An organization is the tenant boundary. Every record OpsAI writes carries it as part of the primary key rather than as a filter applied in application code, which is the distinction worth checking in any product that claims isolation.
Use a sandbox organization for this walkthrough. Every step is reversible, but step 5 files a real evidence record and evidence cannot be edited afterwards — that is the point of it.
02
Issue a scoped key
Keys are scoped by capability and prefixed accordingly, so the blast radius of a leaked key is legible from the key itself. For this walkthrough you want an evaluate key.
sk_read_... # read the estate, traces, evidence
sk_evaluate_... # evaluate actions; cannot change policy
sk_admin_... # publish policy versions, manage connections
export OPSAI_API_KEY="sk_evaluate_..."A key is shown once and stored as a digest. There is no endpoint that returns a key value, so a lost key is rotated rather than recovered.
03
Install the SDK
npm install @opsai/sdk # or: pip install opsaiThe SDK is a typed wrapper over the HTTP API and nothing more. Everything below works with curl if you would rather see the wire — the API overview covers the conventions.
04
Register your AI system
Register the thing that already exists and already proposes actions. Note what is required and what is not: the accountable human is required, the framework is descriptive and nothing branches on it.
import { OpsAI } from '@opsai/sdk';
const opsai = new OpsAI({ apiKey: process.env.OPSAI_API_KEY });
const agent = await opsai.agents.create({
id: 'refund-resolver',
framework: 'langgraph', // descriptive only
model: 'claude-sonnet',
owner: 'you@example.com', // required: one accountable human
attempts: ['issue.refund'],
});05
Evaluate an action
The loop. Your AI system proposes; OpsAI decides before anything reaches a system of record.
const decision = await opsai.actions.evaluate({
agent: 'refund-resolver',
action: 'issue.refund',
subject: 'ORD-40122',
amount: { currency: 'INR', value: 18400 },
idempotency_key: 'ACT-7512',
});
decision.outcome; // 'authorized'
decision.bound; // 'refund.ceiling'
decision.evidence; // 'EV-7512'
decision.latency_ms;// 11Three possible outcomes. authorized attaches a grant scoped to this one action. held means a person has to decide, and the hold expires rather than queueing. denied names the check that failed.
Confirm it landed: GET /actions/ACT-7512/trace returns the six stages whatever the outcome was.
06
Watch it refuse
Send the same call with an amount above the ceiling. This is the step worth doing before you wire the happy path.
{
"error": {
"code": "bound_violation",
"bound": "refund.ceiling",
"bound_version": "v7",
"check": "amount <= ceiling",
"observed": { "amount": 41200, "ceiling": 25000 },
"evidence": "EV-7601"
}
}Note the evidence reference. A refusal produces a record exactly as complete as an authorization does, which is the property that makes the record usable in a review — a control that only writes down its successes cannot answer what the system tried to do and what stopped it.
After the first call
Three things worth wiring next.
In this order. The webhook is first because a hold that expires is a decision nobody made, and it is the event most likely to be invisible in your own systems.
First
Webhooks
Holds, expiries and escalations as signed events, so a decision nobody made is visible where you work.
Second
Connect a system
Move from asking OpsAI to letting it carry out the action, so governance no longer depends on your code choosing to ask.
Third
Policy and replay
Write a bound properly, version it, and replay past actions against a draft before publishing it.
Where to go
You have a decision and a record. Now make it not depend on your code asking.
Evaluating explicitly is the fastest way in and the weakest form of the control, because it works only where somebody remembered to call it. A connection closes that gap.