Skip to content

AI2IN AgentDesk API — per-scenario guide ​

The AI Workforce as a web service. You submit a case to a governed agent vertical; the agent works it end-to-end while every action is isolated, PII-masked, egress-controlled, and written to a tamper-evident ledger. Base URL: https://api.ai2in.dev. Auth: Authorization: Bearer ai2in_... (except the two public discovery routes). India-resident (Mumbai ap-south-1).

Two execution modes (this is the key thing to understand) ​

Simulated run (default, today)Live run (Claude-powered)
EndpointPOST /v1/agentdesk/verticals/{id}/runs (async)POST /v1/agentdesk/run (SSE stream)
Braindeterministic governed pipelineclaude-opus-4-8, real tool-use loop
Sandboxsteps recorded as sandbox.* ledger eventsa real gVisor sandbox is opened and code runs in it
Needsjust an ai2in_ keyai2in_ key + ANTHROPIC_API_KEY on the engine

Both write to the same real, hash-chained agent_actions ledger. Use simulated for reliable, free integration + audit trails; use live for genuine reasoning.

When a real sandbox opens, and what runs in it ​

A real sandbox is opened only in a live run, the moment the agent calls the run_python tool — e.g. to compute a fraud/risk score (KYC) or run diagnostics and a fix (IT). The engine does exactly this (server/src/agentdesk.js):

js
// inside the run_python tool handler
if (!sandboxId) {
  // 1) open an isolated gVisor sandbox on the node (no internet, runsc runtime)
  const sbx = await createSandbox({}, 'ai2in/sandbox:python-3.12',
    { teamId, timeoutMs: 120000, metadata: { agentdesk: caseData.id } });
  sandboxId = sbx.id;
}
// 2) run the agent's code inside it
const res = await runCode(sandboxId, input.code);
// 3) record the activity to the tamper-evident ledger (PII-safe)
recordAction({ teamId, alias, action: 'sandbox.run',
  summary: 'ran risk/duplicate check in gVisor sandbox',
  detail: { code: input.code.slice(0,300), stdout: String(res.stdout).slice(0,300) } });
// ...at the end of the run, the sandbox is torn down:
await deleteSandbox(sandboxId);

So the lifecycle is: agent decides code is needed → createSandbox (open) → runCode (activity) → recordAction (audit) → deleteSandbox (teardown). The sandbox is per-run, isolated with gVisor, has no outbound internet, and every command it runs is in the ledger. In a simulated run the same step appears as a sandbox.run ledger entry (governed + audited) without spinning a container — so you can integrate and demo the audit trail before enabling live mode.

The call pattern (same for every vertical) ​

bash
KEY="ai2in_YOUR_KEY"; V="kyc"    # or it | support | voice

# 1) submit the case -> a run (202). Omit --data to use the built-in sample case.
RUN=$(curl -s -X POST "https://api.ai2in.dev/v1/agentdesk/verticals/$V/runs" \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  --data '{"case": { "...": "your fields" }}')
ID=$(echo "$RUN" | jq -r .id)

# 2) poll until status is terminal (succeeded | error)
curl -s "https://api.ai2in.dev/v1/agentdesk/runs/$ID" -H "Authorization: Bearer $KEY"

# 3) pull the tamper-evident audit trail for this run
curl -s "https://api.ai2in.dev/v1/agentdesk/runs/$ID/ledger" -H "Authorization: Bearer $KEY"

Node (any HTTP client works — no SDK required):

js
const H = { Authorization: `Bearer ${process.env.AI2IN_KEY}`, "Content-Type": "application/json" };
const base = "https://api.ai2in.dev/v1/agentdesk";
const run = await (await fetch(`${base}/verticals/it/runs`, { method: "POST", headers: H,
  body: JSON.stringify({ case: { id: "INC-5012", host: "prod-api-01", severity: "P1" } }) })).json();
let s; do { await new Promise(r => setTimeout(r, 500));
  s = await (await fetch(`${base}/runs/${run.id}`, { headers: H })).json();
} while (s.status === "running");
const ledger = await (await fetch(`${base}/runs/${run.id}/ledger`, { headers: H })).json();
console.log(s.decision, ledger.entries.length, "audited steps");

Discovery (public, no key):

bash
curl -s https://api.ai2in.dev/v1/agentdesk/verticals        # list the 4 services
curl -s https://api.ai2in.dev/v1/agentdesk/openapi.json     # full OpenAPI 3.1 contract

1) kyc — Back-office automation (insurance claims / KYC) ​

Job: adjudicate a health-insurance claim from documents to decision.

bash
curl -s -X POST https://api.ai2in.dev/v1/agentdesk/verticals/kyc/runs \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  --data '{"case":{"id":"CLM-2026-04417","applicant":"Ananya Sharma","pan":"ABCPS1234K","aadhaar":"234123456786","policy":"HLT-88213","amount":"₹1,84,500"}}'

Flow (8 governed steps):

#actionwhat happensgovernance
1fs.readOCR the claim form + discharge summary—
2pii.scandetect PAN / Aadhaar / phonemasked in every log & the ledger
3kyc.verifyPAN format + Aadhaar Verhoeff checksumPII-tagged
4db.queryconfirm policy active & in-network—
5risk.score→ opens a sandbox and runs the duplicate/risk modelsandbox.run audited
6egress.blockagent tries a 3rd-party enrichment APIblocked (not allow-listed)
7agent.decisionadjudicate (approve / escalate)recorded
8db.writefile the case, queue payout—

Sandbox moment: step 5. The agent writes a short Python check and calls run_python → the engine opens a gVisor sandbox, runs it (no internet), records sandbox.run, and tears it down at the end.


2) it — IT helpdesk & ops ​

Job: diagnose and fix a production incident. This vertical is the heaviest sandbox user — the agent does real ops work, and every command is isolated.

bash
curl -s -X POST https://api.ai2in.dev/v1/agentdesk/verticals/it/runs \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  --data '{"case":{"id":"INC-4471","host":"prod-web-03","severity":"P1","symptom":"502s, health check failing"}}'

Flow (8 governed steps):

#actionwhat happensgovernance
1ticket.triageclassify P1, form a hypothesis—
2sandbox.openopens a gVisor session scoped to the host — no host accesssandbox.open audited
3sandbox.runruns diagnostics (df -h, journalctl) in the sandboxaudited
4agent.findingroot cause: access.log filled the disk—
5egress.blockagent tries to fetch a remediation scriptblocked
6sandbox.runapplies the fix (rotate/truncate logs, restart nginx) in the sandboxaudited
7sandbox.runverifies recovery (disk 41%, health 200) in the sandboxaudited
8db.writeclose the ticket with the full command trail—

Sandbox moments: steps 2–3 and 6–7. The agent opens one isolated session and runs diagnostics → fix → verify inside it. Because it's gVisor with no egress, a compromised or hallucinated command cannot touch the host or the network — and the entire command history is in the tamper-evident ledger.


3) support — Customer support ​

Job: resolve a support ticket on real customer data it can't leak. Data-centric — no sandbox needed (lookups + writes, not code execution).

bash
curl -s -X POST https://api.ai2in.dev/v1/agentdesk/verticals/support/runs \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  --data '{"case":{"id":"TKT-90218","customer":"Rahul Verma","pan":"AAKPV9021M","account":"SB-2291-8830","issue":"Locked out"}}'

Flow (7 governed steps):

#actionwhat happensgovernance
1ticket.readparse intent (unlock + explain logins)—
2kyc.verifymatch PAN + email on filePII masked
3db.querylook up account (3 failed logins, new device)—
4agent.findingassess: benign lockout, reset approved—
5egress.blockagent tries a device-reputation APIblocked
6db.writereset access, send device alert—
7db.writeclose ticket with masked trail—

Sandbox moment: none by default — the work is database reads/writes. If a policy required running code (e.g. a custom eligibility script), the agent would open a sandbox exactly as in KYC/IT; support simply doesn't need one.


4) voice — Voice call center (preview) ​

Job: handle an inbound call — verify, answer, update records. The speech layer (STT/TTS/telephony) sits on top of the same governed runtime; the agent logic here is DB-centric, no sandbox by default.

bash
curl -s -X POST https://api.ai2in.dev/v1/agentdesk/verticals/voice/runs \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  --data '{"case":{"id":"CALL-7793","caller":"Meera Nair","phone":"+91 90031 22140","policy":"MOT-55110"}}'

Flow (6 governed steps):

#actionwhat happensgovernance
1call.startinbound call routed to the AI voice agent—
2kyc.verifyverify caller via phone + OTPphone masked
3db.queryanswer: policy status—
4db.writeupdate the caller's address (read back + confirm)—
5egress.blockagent tries a maps autocomplete APIblocked
6agent.decisionwrap up, send SMS confirmation—

Sandbox moment: none by default. Voice is I/O + DB; the isolation guarantees still apply to any tool the agent calls, and the whole call is in the ledger.


Verifying the audit trail ​

Every run's steps are appended to your team's agent_actions chain. Prove integrity independently (or from the dashboard's Governance console):

sql
select * from verify_agent_ledger('<your-team-id>');
-- ok=true, checked=<n>  ... or the first row where the chain was broken

GET /v1/agentdesk/runs/{id}/ledger returns that run's entries with row_hash / prev_hash, correlated by the run's ledger_ref.

Sovereign compute for Indian AI — hosted in Mumbai (ap-south-1).