QUICKSTART
DOCS
Five minutes to your first signed receipt.
// 01
Install & seed
npm install npm run setup # prisma generate + db push + seed default Atlas-01 npm run dev
The seed prints a demo API key to your terminal. Save it — it is hashed and discarded.
// 02
Create an agent
curl -X POST http://localhost:3000/api/agents \
-H "content-type: application/json" \
-d '{ "name": "Atlas-02", "role": "Research agent" }'The response contains apiKey — shown once, never again.
// 03
Create / update a mandate
curl -X POST http://localhost:3000/api/mandates \
-H "content-type: application/json" \
-d '{
"agentId": "agent_xxx",
"name": "research-budget-v1",
"dailyBudgetUsd": 25,
"maxCostPerActionUsd": 2,
"approvalThresholdUsd": 5,
"allowedTools": ["paid_api_call","web_search"],
"blockedTools": ["wallet_transfer","shell_exec"],
"blockedActions": ["transfer_usdc","delete_files"],
"approvalRequiredActions": ["send_email"],
"allowedDomains": ["api.openai.com"],
"blockedDomains": ["unknown-wallet.site"]
}'// 04
Preflight check (the wire contract)
curl -X POST http://localhost:3000/api/check \
-H "Authorization: Bearer msk_xxx" \
-H "content-type: application/json" \
-d '{
"agentId": "agent_xxx",
"actionType": "paid_api_call",
"tool": "paid_api_call",
"target": "https://api.openai.com/v1/responses",
"costUsd": 0.02
}'Returns decision (APPROVED · BLOCKED · NEEDS_APPROVAL), reason, matchedRule, riskLevel, and the full signed receipt.
// 05
Verify a receipt
curl -X POST http://localhost:3000/api/verify \
-H "content-type: application/json" \
-d '{ "id": "rct_xxxxxx" }'Or POST the full receipt JSON. Returns { "valid": true | false, "reasons": [...] }.
// 06
TypeScript SDK
import { MandateSeal } from "@/sdk/mandateseal";
const seal = new MandateSeal({
apiKey: process.env.MANDATESEAL_API_KEY!,
baseUrl: "http://localhost:3000",
});
const result = await seal.check({
agentId: "agent_atlas_01",
actionType: "paid_api_call",
tool: "paid_api_call",
target: "https://api.openai.com/v1/responses",
costUsd: 0.02,
});
if (result.decision !== "APPROVED") {
throw new Error(result.reason);
}
// run your action…
const proof = await seal.verifyReceipt(result.receipt);
if (!proof.valid) throw new Error("receipt tampered with");// 07
Policy engine — rules in order
- If mandate is disabled → APPROVED.
- Tool in
blockedTools→ BLOCKED. - actionType in
blockedActions→ BLOCKED. - Target domain in
blockedDomains→ BLOCKED. - cost >
maxCostPerActionUsd→ BLOCKED. - cost >
approvalThresholdUsd→ NEEDS_APPROVAL. - actionType in
approvalRequiredActions→ NEEDS_APPROVAL. - If
allowedToolsis non-empty and tool not in it → BLOCKED. - If
allowedDomainsis non-empty and target not in it → BLOCKED. - Otherwise → APPROVED.