Quickstart
Authorize an agent action, execute it, and mint a cryptographic receipt in under five minutes.
Two ways to integrate
SDK integration — call authorize() before your agent acts, notarize() after. Full control over the policy + receipt lifecycle.
Gateway (zero code) — change one URL in your OpenAI/Anthropic config. Aira sits in the middle as a transparent proxy, authorizing and signing every call automatically. Gateway guide →
The model in one paragraph
Aira is a gate, not a logger. Before the agent does the real-world thing (send a wire, ship a contract, write to a database), it calls authorize(). Aira evaluates every active policy and returns a decision: proceed, hold for human approval, or blocked. Only after the agent actually executes the action does it call notarize() with the outcome. That second call mints a cryptographic receipt that commits to both the original intent and the actual outcome.
1. Create an account
Register your organization and get your first API key:
curl -X POST https://api.airaproof.com/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "dev@acme.com",
"password": "your-secure-password"
}'{
"org_uuid": "org_01J8X...",
"user_uuid": "usr_01J8X...",
"message": "Account created. Check your email to verify.",
"request_id": "req_a1b2c3d4e5f6"
}After verifying your email, create an API key from the dashboard or via the API.
Save your API key immediately. It is shown once and cannot be retrieved again.
2. Authorize an action
Before the agent executes, ask Aira for permission. Aira evaluates every active policy and returns an Authorization object.
from aira import Aira, AiraError
aira = Aira(api_key="aira_live_...")
try:
auth = aira.authorize(
action_type="wire_transfer",
details="Send 75,000 EUR to vendor X",
agent_id="payments-agent",
)
except AiraError as e:
if e.code == "POLICY_DENIED":
# A policy blocked this action. Do not execute.
log.error(f"Blocked: {e.message}")
return
raiseimport { Aira, AiraError } from "aira-sdk";
const aira = new Aira({ apiKey: "aira_live_..." });
try {
const auth = await aira.authorize({
actionType: "wire_transfer",
details: "Send 75,000 EUR to vendor X",
agentId: "payments-agent",
});
} catch (e) {
if (e instanceof AiraError && e.code === "POLICY_DENIED") {
console.error(`Blocked: ${e.message}`);
return;
}
throw e;
}The authorization response carries a status. There are three branches.
3. Handle the three branches
Branch A: authorized
Policies passed. The agent is cleared to execute. After the real-world action completes, call notarize() to mint the receipt.
if auth.status == "authorized":
# Execute the actual action
result = send_wire(75000, to="vendor")
# Step 2: notarize the outcome and mint the receipt
receipt = aira.notarize(
action_uuid=auth.action_uuid,
outcome="completed",
outcome_details=f"Sent successfully. ref={result.id}",
)
print(receipt.signature) # Ed25519 signatureif (auth.status === "authorized") {
const result = await sendWire(75000, "vendor");
const receipt = await aira.notarize({
actionId: auth.action_uuid,
outcome: "completed",
outcomeDetails: `Sent successfully. ref=${result.id}`,
});
console.log(receipt.signature); // Ed25519 signature
}If the execution fails, pass outcome="failed" instead. No receipt is minted, but the failure is recorded for the audit trail.
Branch B: pending_approval
A policy decided a human must approve. The action is held server-side and an email goes to your configured approvers. The agent must not execute until the human approves. Once approved, status moves to approved and the agent (or a webhook handler) can call notarize().
elif auth.status == "pending_approval":
# Held for human review. Agent must wait.
# When the human approves, the action moves to status="approved".
# A webhook handler (or a worker) then calls notarize() to mint the receipt.
queue.enqueue(auth.action_uuid)else if (auth.status === "pending_approval") {
// Held for human review. Agent must wait.
// When the human approves, the action moves to status="approved".
// A webhook handler (or a worker) then calls notarize() to mint the receipt.
await queue.enqueue(auth.action_uuid);
}See Human Approval for the full held-action flow.
Branch C: POLICY_DENIED
A deny policy matched. The SDK raises AiraError with code POLICY_DENIED. The agent must not execute and there is nothing to notarize. Log and move on.
Handled in the try/except block at the top of step 2.
4. Verify a receipt
Anyone can verify a minted receipt. No authentication required.
curl https://api.airaproof.com/api/v1/verify/action/act_01J8X...{
"valid": true,
"receipt_uuid": "rct_01J8X...",
"verified_at": "2026-04-07T14:35:00Z",
"public_key_id": "aira-signing-key-v1",
"message": "Action receipt exists and signing key is valid."
}Share the verify URL with your auditor, regulator, or compliance team.
5. Register an agent (optional)
Give your agent a verifiable identity. Once registered, Aira validates the agent on every authorize() call. Decommissioned agents are automatically blocked.
curl -X POST https://api.airaproof.com/api/v1/agents \
-H "Authorization: Bearer aira_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"agent_slug": "payments-agent",
"display_name": "Payments Agent",
"capabilities": ["wire_transfer", "ach", "refund"],
"public": true
}'6. Run a consensus case (separate API)
Cases are a separate API for multi-model decision evaluation. They are not the same as the policy consensus mode, even though they share the underlying scoring machinery.
curl -X POST https://api.airaproof.com/api/v1/cases \
-H "Authorization: Bearer aira_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"details": "Should we approve a credit application for a customer with credit score 742?",
"models": ["gpt-5.4", "claude-sonnet-4-6", "gemini-3.1-flash-lite"],
"options": { "human_review_threshold": 0.4 }
}'See Cases for the full reference.
What's next
- Python SDK for the full method reference
- TypeScript SDK for the full method reference
- Policies to see how
authorize()decides - Human Approval for the held-action flow
- Receipts for what
notarize()actually signs - Actions API Reference for the raw HTTP endpoints