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).