Skip to content

Local API Reference

The local FastAPI service is a programmatic view of the same workspace the CLI and Cockpit use. /openapi.json is the authoritative machine-readable contract; the committed TypeScript client is generated from it. Everything below is enumerated from the running app, and scripts/audit_documentation.py fails if a path named on this page is not one the server serves.

Start and authenticate

ait --workspace-root ./engagement server start --listen 127.0.0.1:8400 --print-token

The server defaults to loopback. A random token lives at .ait/server.token. Send it as Authorization: Bearer TOKEN, or exchange it through POST /api/v1/session for the Cockpit's HttpOnly, SameSite=Strict session cookie. Do not publish the token or bind remotely without an authenticated TLS boundary in front of the service.

Interception

The tool's actual job. A session wraps one connection; messages pause, you decide, the transcript records both sides of the edit.

Route Methods Purpose
/api/v1/intercepts GET POST List sessions; start one against a connection.
/api/v1/intercepts/{session_id} GET Session status, live summary and counts.
/api/v1/intercepts/{session_id}/messages GET Page decoded messages; ?pending=true for what is paused now.
/api/v1/intercepts/{session_id}/messages/{message_id} GET One message: envelope, decode, correlation.
/api/v1/intercepts/{session_id}/messages/{message_id}/comparison GET Structural diff of what the sender sent against what was delivered.
/api/v1/intercepts/{session_id}/messages/{message_id}/suggestions GET Attack primitives applicable to this message.
/api/v1/intercepts/{session_id}/messages/{message_id}/suggestions/{suggestion_id} GET One primitive, with its injection, observation and close control.
/api/v1/intercepts/{session_id}/decisions POST forward_original, forward_wire, forward_modified, drop or replay.
/api/v1/intercepts/{session_id}/decisions/batch POST Resolve several paused messages in one call.
/api/v1/intercepts/{session_id}/break-conditions PUT Replace what the gate pauses on.
/api/v1/intercepts/{session_id}/mode PUT Turn the gate on or off without stopping the session.
/api/v1/intercepts/{session_id}/exports POST Write a session record. disclosure is redacted by default; raw is complete capture and is labeled raw, never "sanitized".
/api/v1/intercepts/{session_id}/stop POST Stop, with an explicit resolution for anything still paused.

Transform rules

Two rule systems, deliberately distinct. Live rules are JSON-Pointer patches scoped to one session. Transform rules are the YAML vocabulary, saved on the connection and re-armed whenever a session starts against it.

Route Methods Purpose
/api/v1/intercepts/{session_id}/rules GET POST Live rules on this session.
/api/v1/intercepts/{session_id}/rules/{rule_id} PUT PATCH DELETE Replace, toggle or remove one.
/api/v1/intercepts/{session_id}/rules/{rule_id}/preview GET Would this rule fire, and if not, which miss code applies.
/api/v1/intercepts/{session_id}/rules/order PUT Reorder: the engine returns on first match, so order decides the winner.
/api/v1/intercepts/{session_id}/rules/import POST Load a YAML rule set into the session.
/api/v1/connections/{connection_id}/transform-rules GET POST Rules persisted on the connection.
/api/v1/connections/{connection_id}/transform-rules/{rule} DELETE Remove one.

Shadow infrastructure

Operator-controlled receivers that turn "routing changed" into "the delegation reached my endpoint carrying these arguments". Loopback-bound, no remote-bind option, observation files written 0600.

Route Methods Purpose
/api/v1/shadows GET POST List shadows; stand up an a2a-agent, mcp-server or callback.
/api/v1/shadows/observations GET What the shadows received, including credential headers in full.
/api/v1/shadows/{name} DELETE Tear one down.

Connections and targets

Route Methods Purpose
/api/v1/connections GET POST Relay definitions: listener, upstream, transport, TLS references.
/api/v1/connections/{connection_id} GET One connection.
/api/v1/connections/{connection_id}/test POST Reach the upstream without starting a session.
/api/v1/connections/discover POST Read an explicitly supplied Agent Card and propose a connection.
/api/v1/targets GET POST Target records and saved runtime documents.
/api/v1/targets/{target_id} GET PATCH Inspect or amend one.
/api/v1/discoveries POST Run discovery against a supplied endpoint.
/api/v1/surfaces GET POST Normalized protocol surfaces derived from discovery.

A stored runtime document may not contain an inline secret. Credentials are carried as env:NAME references and resolved at the point of use, so a token never lands in a workspace artifact by accident.

Labs

Nine process-backed exercises. No Docker, provider key, or external network is required. Each starts separate local components over loopback or stdio and carries a named proof source.

Route Methods Purpose
/api/v1/labs GET POST The catalog; start an exercise.
/api/v1/labs/{lab_id} GET Lab status, endpoints and effect ledger.
/api/v1/labs/{lab_id}/trigger POST Drive the sender so a message reaches the gate.
/api/v1/labs/{lab_id}/reset POST Return the lab to its pre-attack state between arms.
/api/v1/labs/{lab_id}/stop POST Stop, with a verified cleanup receipt.
/api/v1/labs/{lab_id}/target-handoffs POST Turn a lab component into a connection you can intercept.
/api/v1/labs/{lab_id}/target-handoffs/{connection_id}/start POST Start that handoff.
/api/v1/labs/{lab_id}/target-handoffs/{connection_id}/test POST Check it before arming anything.

Runs, traffic and evidence

Route Methods Purpose
/api/v1/runs GET POST Run history and creation.
/api/v1/runs/{run_id} GET One run with its jobs and manifests.
/api/v1/runs/{run_id}/jobs POST Start supervised work under a run.
/api/v1/runs/{run_id}/cancel POST Cooperative stop of every job the run owns.
/api/v1/runs/{run_id}/traffic GET Cursor-paged lightweight records.
/api/v1/runs/{run_id}/traffic/record GET One record with its structural diff and diagnostics.
/api/v1/observations GET POST What was seen.
/api/v1/hypotheses GET POST What it might mean.
/api/v1/validations GET POST What was tested; PATCH /{validation_id} to amend.
/api/v1/findings GET POST What is claimed; PATCH /{finding_id} to amend.
/api/v1/artifacts POST Register immutable content-addressed evidence.

State snapshots

Route Methods Purpose
/api/v1/targets/{target_id}/state-snapshots GET POST Capture and list scoped state.
/api/v1/state-snapshots/{snapshot_id} GET One snapshot.
/api/v1/state-snapshots/{snapshot_id}/compare/{other_id} GET Diff two: the cheapest way to show a receiver's state moved.
/api/v1/targets/{target_id}/state-restore POST Restore. Requires confirmed: true.

Workspace, console and service

Route Methods Purpose
/api/v1/health GET Liveness.
/api/v1/session POST Exchange the bearer token for a session cookie.
/api/v1/events GET Resumable SSE stream.
/api/v1/workspaces, /api/v1/engagements GET POST Local workspace and engagement records.
/api/v1/media GET POST Deposit and inspect immutable multimodal inputs; GET /{media_id} for one.
/api/v1/plugins GET Registered extensions.
/api/v1/operator/snapshot GET Everything the operator view needs in one read.
/api/v1/cockpit/status, /traffic/detail, /ui-config GET Console-shaped projections, paginated and bounded.

Idempotency and cancellation

Execution requests accept idempotency keys. Repeating an identical normalized request returns the existing run; reusing the key with different inputs returns a conflict. POST /runs/{run_id}/cancel requests cooperative cancellation of every job under the run and returns current state without blocking through the full escalation window.

Pagination and cursors

Traffic and result collections use bounded page sizes and opaque signed cursors. A cursor is bound to its run and filters; clients must not parse or manufacture one. Fetch record detail only after selecting a summary row. This is what keeps a long session responsive.

SSE events

GET /api/v1/events emits ordered events with resumable cursors. Reconnect with the last received cursor rather than polling full status documents.

Errors

HTTP validation errors use the FastAPI problem response.

The stable vocabulary worth keying automation on is the miss codes a rule reports when it does not fire: predicate_mismatch, missing_path, decoder_ineligible, shadowed, disabled, chain_guard, chain_state_unavailable, chain_reference_unresolved, and the evidence tiers and attribution values on a finding. Transport-level failures surface as the transport's own error text rather than a normalized category; the campaign engine's execution error taxonomy went with the engine.

Never treat a 2xx as proof that an attack had impact. A 200 means the API accepted your decision, not that the receiver acted on it. Read the evidence tiers instead. See Evidence. Behavior validation records use kind=behavior, and the API rejects one that asserts impact_validated.

Contract maintenance

python scripts/generate_api_contracts.py --check

Regenerate after an API model or route changes:

python scripts/generate_api_contracts.py