Aiudit

External Integration API v1

Machine-to-machine REST API for connecting Aiudit to government GRC platforms (RSA Archer, ServiceNow GRC, OneTrust), case management systems (Jira, ServiceNow ITSM), and SIEMs. Designed for sovereign and air-gapped deployments.

OpenAPI spec: /api/v1/openapi.json · Issue a credential

Authentication

Each request must include a Bearer token issued from API & Integrations.

Authorization: Bearer pk_live_<prefix>_<secret>

Sandbox tokens use the pk_test_ prefix and may only be issued by Pilot organizations. Secrets are stored as SHA-256 hashes and shown to the operator only once at issuance.

Scopes

ScopeEndpoints
governance.readGET /api/v1/agents, GET /api/v1/agents/:id
evidence.readGET /api/v1/evidence-packages, GET /api/v1/evidence-packages/:id
audit.readGET /api/v1/audit/entries
vendors.readGET /api/v1/vendors
incidents.writePOST /api/v1/incidents

Each credential's scopes are a strict subset of the issuer's RBAC role. A scope cannot grant access beyond what the user holds at the moment of issuance.

Rate limits

Per-credential, per-minute quota (default 60 req/min, configurable up to 10000). Responses always include:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 2026-06-26T11:32:00.000Z
Retry-After: 12     # only on 429

Classification handling

Every credential has a classification_ceiling (public, restricted, secret, top_secret). Resources above the ceiling return as{ id, _redacted: true } stubs. List endpoints report a redacted_count.

Error envelope

{
  "error": {
    "code": "insufficient_scope",
    "message": "Required scope: evidence.read",
    "request_id": "0193f1b4e8c14d52a3a..."
  }
}

The x-request-id response header is always set; quote it when contacting support.

Example — list agents (curl)

curl -s https://<your-aiudit>/api/v1/agents \
  -H "Authorization: Bearer pk_live_abc1234567_xxxxxxxxxxxxxxxxxxxxxxxx" \
  | jq

Example — TypeScript

const res = await fetch("/api/v1/evidence-packages", {
  headers: { authorization: "Bearer " + process.env.AIM_API_KEY },
});
const { data, redacted_count } = await res.json();

Example — Python

import os, requests
r = requests.get(
    "https://aiudit.gov.example/api/v1/audit/entries",
    headers={"Authorization": f"Bearer {os.environ['AIM_API_KEY']}"},
    params={"from_seq": 0, "limit": 1000},
    timeout=30,
)
r.raise_for_status()
for entry in r.json()["data"]:
    sink.write(entry)

GRC adapter recipe (ServiceNow GRC / RSA Archer)

Schedule a nightly job that pulls sealed evidence packages and stores the payload_hash, merkle_root, and download URL against the relevant control. See examples/grc-sync.ts in the repository.

// Nightly: pull new sealed packages and link to GRC controls
const since = lastSyncedAt(); // ISO string
const { data } = await aiudit.get("/api/v1/evidence-packages");
for (const pkg of data.filter(p => p.sealed_at > since)) {
  await grc.linkEvidence({
    controlId: pkg.purpose,                 // your mapping convention
    title: pkg.title,
    externalId: pkg.id,
    integrityHash: pkg.payload_hash,
    merkleRoot: pkg.merkle_root,
    url: `https://aiudit/api/v1/evidence-packages/${pkg.id}`,
  });
}

Case management recipe (Jira / ServiceNow ITSM)

On case creation, your platform's outbound webhook posts to POST /api/v1/incidents with the case key in external_ref. Aiudit creates an incident in the assigned agent's org and emits a tamper-evident audit event linking the two.

curl -X POST https://aiudit/api/v1/incidents \
  -H "Authorization: Bearer $AIM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Agent X breached policy","severity":"high","external_ref":"SNOW-INC012345"}'

Sovereign & air-gapped deployments