The AIM API
One question before your AI acts: is this agent allowed to do this, right now? A REST API that turns evidence into trust, and trust into bounded authority, with every step recorded.
How an integration works
Register your AI agents and a versioned policy, and keep AIM informed with signals about how each agent actually behaves. Then, for every consequential action, your system asks AIM first:
- 01
Decision
The AI proposes an action.
- 02
Trust
AIM scores the agent from its evidence.
- 03
Authority
Your policy turns trust into one of five states.
- 04
Action
Runs only through AIM, within the authority.
- 05
Outcome
What happened feeds back into trust.
Every step is written to a tamper-evident governance log you can read back per decision.
From zero to a governed action
1. Set up once: register the agent, publish a policy, and send signals. Your base URL and API key are issued when your pilot starts.
# Register the AI agent AIM will govern
curl -s -X POST "$AIM_API/api/entities" \
-H "Authorization: Bearer $AIM_KEY" -H "Content-Type: application/json" \
-d '{"entity_type":"ai_agent","name":"Billing Refund Agent"}'
# Publish a versioned policy (rules are evaluated top to bottom)
curl -s -X POST "$AIM_API/api/policies" \
-H "Authorization: Bearer $AIM_KEY" -H "Content-Type: application/json" \
-d '{"policy_key":"refunds","decision_type":"refund","version":"1.0","rules":[
{"condition":{"trust_score":{"lt":40}},"authority":"BLOCK"},
{"condition":{"amount":{"gt":1000}},"authority":"ESCALATE"},
{"condition":{"trust_score":{"gte":60}},"authority":"EXECUTE",
"envelope":{"amount":{"lte":1000}}},
{"condition":{"trust_score":{"gte":0}},"authority":"CONSTRAIN"}]}'
# Tell AIM how the agent actually behaves (trust is computed from signals)
curl -s -X POST "$AIM_API/api/signals" \
-H "Authorization: Bearer $AIM_KEY" -H "Content-Type: application/json" \
-d '{"dimension":"reliability","direction":"positive","strength":0.9,
"confidence":0.9,"target_entity_id":"ENT_…"}'2. Before every consequential action, run the governed flow:
export AIM_API="https://<your-pilot-base-url>"
export AIM_KEY="<your-api-key>"
# 1. The AI wants to act: create a decision
curl -s -X POST "$AIM_API/api/decisions" \
-H "Authorization: Bearer $AIM_KEY" -H "Content-Type: application/json" \
-d '{"proposed_by_entity_id":"ENT_…","decision_type":"refund",
"proposed_action":"issue_refund","payload":{"amount":180},
"idempotency_key":"order-8841-refund"}'
# 2. How much is this agent trusted, from its evidence?
curl -s -X POST "$AIM_API/api/trust/evaluate" \
-H "Authorization: Bearer $AIM_KEY" -H "Content-Type: application/json" \
-d '{"decision_id":"DEC_…"}'
# 3. What is it allowed to do? EXECUTE | CONSTRAIN | CHALLENGE | ESCALATE | BLOCK
curl -s -X POST "$AIM_API/api/authority/evaluate" \
-H "Authorization: Bearer $AIM_KEY" -H "Content-Type: application/json" \
-d '{"decision_id":"DEC_…","trust_state_id":"TRS_…","policy_id":"POL_…"}'
# 4. Act only through AIM, with the authority it issued
curl -s -X POST "$AIM_API/api/actions" \
-H "Authorization: Bearer $AIM_KEY" -H "Content-Type: application/json" \
-d '{"decision_id":"DEC_…","authority_id":"AUT_…","action_type":"issue_refund",
"payload":{"amount":180},"idempotency_key":"order-8841-refund-act"}'
# 5. Report what happened; it feeds the agent's trust
curl -s -X POST "$AIM_API/api/outcomes" \
-H "Authorization: Bearer $AIM_KEY" -H "Content-Type: application/json" \
-d '{"action_id":"ACT_…","outcome_type":"refund_settled","success":true}'Authentication, IDs and idempotency
Authentication
Every request carries your organization's API key: Authorization: Bearer <api_key>. Keys are shown once when issued and only their hash is stored. Resolving an escalation also requires a human operator token: X-Operator-Token, obtained from POST /api/tenant-operators/login. Each organization only ever sees its own data.
More on how we protect your data: Security & data
IDs
IDs are prefixed by type so they are never mixed up: ENT_ entity, CTX_ context, POL_ policy, SIG_ signal, EVD_ evidence, DEC_ decision, TRS_ trust state, AUT_ authority, ACT_ action, OUT_ outcome.
Idempotency
Decisions and actions accept an idempotency_key. Retrying with the same key returns the original result with replayed: true and never executes twice, so network retries are always safe. Use a key derived from your own record, such as the order or ticket id.
Errors and rate limits
Errors return a JSON body with an error field (and reason on denied actions).
| Status | Meaning | What to do |
|---|---|---|
| 400 | Invalid payload | The body failed validation. Fix the request; retrying will not help. |
| 401 | Invalid tenant API key | Missing or wrong Authorization: Bearer key. |
| 403 | Action denied | The authority does not allow this action. reason says why (e.g. AUTHORITY_EXPIRED, ENVELOPE_VIOLATION:amount). |
| 404 | Not found | The id does not exist in your organization. |
| 409 | Conflict | State conflict, e.g. AUTHORITY_ALREADY_CONSUMED or an escalation already resolved. |
| 429 | Too many requests | Rate limit reached. Back off and retry after the RateLimit-Reset seconds. |
| 500 | Internal error | Safe to retry with the same idempotency key. |
Rate limits: 120 requests per minute per client IP. Responses include standard RateLimit-* headers.
Measured latency
Latency of the full governed flow (decision → trust → authority → action, four API calls), measured end to end by a client, with synthetic data. The numbers below exclude internet round-trips between your servers and ours.
47 ms
All four steps, one client, median.
121 ms
95% of flows finished within this.
0 errors
1,650 governed flows at 1–100 concurrent clients.
| Step | p50 | p95 |
|---|---|---|
| Create decision | 5.5 ms | 6.7 ms |
| Evaluate trust | 16.4 ms | 20.5 ms |
| Evaluate authority | 11.1 ms | 13.5 ms |
| Execute action | 13.6 ms | 15.6 ms |
| Record outcome | 16.8 ms | 18.3 ms |
- Run on a single 2-core laptop (Intel i7-7500U, 12 GB RAM) hosting the API, the database and the load generator at once; production infrastructure is dedicated and larger.
- On that machine throughput levels off at about 30 governed flows per second (about 150 API calls per second); beyond that, requests queue rather than fail.
- Every flow wrote its full record to the tamper-evident governance log; no step was skipped or cached to produce these numbers.
- The benchmark script is reproducible and ships with the codebase; results are available on request.
API reference
Generated from the OpenAPI 3.1 spec, which you can also import into Postman, Insomnia or any OpenAPI code generator.
Setup
Register the actors, contexts and rules AIM will govern.
get/api/entitiesList entities
Responses
- 200Up to 100 most recent entities.
- 401Missing or invalid tenant API key.
- 429Rate limit exceeded (120 requests per minute).
post/api/entitiesRegister an entity
An entity is an actor AIM keeps a trust record for: an AI agent, a person, an organization, a device or a system.
Request body
Example request
{
"entity_type": "ai_agent",
"name": "Refund Assistant",
"external_ref": "agent-42"
}Responses
- 201Created.
{ "entity_id": "ENT_7f3a…", "status": "active" } - 400Invalid request body or parameters.
- 401Missing or invalid tenant API key.
- 429Rate limit exceeded (120 requests per minute).
post/api/contextsRegister a decision context
Request body
Example request
{
"context_type": "customer_refunds",
"risk_class": "high"
}Responses
- 201Created.
{ "context_id": "CTX_91b2…" } - 400Invalid request body or parameters.
- 401Missing or invalid tenant API key.
- 429Rate limit exceeded (120 requests per minute).
get/api/policiesList active policies
Responses
- 200Active policies.
- 401Missing or invalid tenant API key.
- 429Rate limit exceeded (120 requests per minute).
post/api/policiesPublish a policy version
Rules are evaluated top to bottom; the first matching rule sets the authority. Conditions can reference trust_score, evidence_confidence or any field of the decision payload. Versions are immutable: publishing the same policy_key + version again returns 409 — publish a new version instead.
Request body
Example request
{
"policy_key": "refunds",
"decision_type": "refund",
"version": "1.0",
"rules": [
{
"condition": {
"trust_score": {
"lt": 40
}
},
"authority": "BLOCK"
},
{
"condition": {
"amount": {
"gt": 1000
}
},
"authority": "ESCALATE"
},
{
"condition": {
"trust_score": {
"gte": 60
}
},
"authority": "EXECUTE",
"envelope": {
"amount": {
"lte": 1000
}
}
},
{
"condition": {
"trust_score": {
"gte": 0
}
},
"authority": "CONSTRAIN"
}
]
}Responses
- 201Created.
{ "policy_id": "POL_c4d1…", "policy_key": "refunds", "version": "1.0" } - 400Invalid request body or parameters.
- 401Missing or invalid tenant API key.
- 409This policy_key + version already exists.
- 429Rate limit exceeded (120 requests per minute).
Evidence & Signals
Tell AIM what actually happens. Trust is computed from these.
get/api/signalsList signals
Responses
- 200Up to 100 most recent signals.
- 401Missing or invalid tenant API key.
- 429Rate limit exceeded (120 requests per minute).
post/api/signalsSend a signal
A signal is a structured observation about an entity, claim or decision. Each one adds to the evidence confidence behind a trust evaluation; AIM will not authorize anything while evidence confidence is below 40 (it answers CHALLENGE).
Request body
Example request
{
"dimension": "reliability",
"direction": "positive",
"strength": 0.9,
"confidence": 0.9,
"target_entity_id": "ENT_7f3a…"
}Responses
- 201Created.
{ "signal_id": "SIG_0b7e…" } - 400Invalid body, no target, or decay model without half-life.
- 401Missing or invalid tenant API key.
- 429Rate limit exceeded (120 requests per minute).
get/api/mvp5/evidenceList evidence
Responses
- 200Up to 100 most recent evidence records.
- 401Missing or invalid tenant API key.
- 429Rate limit exceeded (120 requests per minute).
post/api/mvp5/evidenceSubmit evidence
Structured evidence from outside the platform (documents, API responses, attestations, verified claims, machine events…). AIM stores a SHA-256 hash of the content for integrity.
Request body
Example request
{
"evidence_type": "api_response",
"content": {
"check": "refund history reconciled"
},
"decision_id": "DEC_41c2…"
}Responses
- 201Created.
{ "evidence_id": "EVD_5a90…", "content_hash": "9f2c…a41e" } - 400Invalid request body or parameters.
- 401Missing or invalid tenant API key.
- 429Rate limit exceeded (120 requests per minute).
Decisions
Every consequential action starts as a decision.
get/api/decisionsList decisions
Responses
- 20050 most recent decisions.
- 401Missing or invalid tenant API key.
- 429Rate limit exceeded (120 requests per minute).
post/api/decisionsCreate a decision
Register the action your AI wants to take before it happens. Nothing downstream (trust, authority, action) runs without a decision_id.
Request body
Example request
{
"proposed_by_entity_id": "ENT_7f3a…",
"decision_type": "refund",
"proposed_action": "issue_refund",
"payload": {
"amount": 200
},
"context_id": "CTX_91b2…",
"idempotency_key": "order-8841-refund"
}Responses
- 200Replayed: a decision with this idempotency_key already exists.
{ "decision_id": "DEC_41c2…", "status": "created", "replayed": true } - 201Created.
{ "decision_id": "DEC_41c2…", "status": "created" } - 400Invalid request body or parameters.
- 401Missing or invalid tenant API key.
- 429Rate limit exceeded (120 requests per minute).
get/api/decisions/{decisionId}Get a decision with its full history
Parameters
Responses
- 200Decision with every trust evaluation, authority, action and outcome (oldest first).
- 401Missing or invalid tenant API key.
- 404Not found in your organization.
- 429Rate limit exceeded (120 requests per minute).
Trust
How much the subject of a decision is trusted, from its evidence.
post/api/trust/evaluateEvaluate trust for a decision
Computes a new, immutable trust state for the decision's subject from its current signals (reliability, consistency, evidence strength, peer validation, contradiction and decay).
Request body
Example request
{
"decision_id": "DEC_41c2…"
}Responses
- 200Trust state.
{ "trust_state_id": "TRS_2d8f…", "decision_id": "DEC_41c2…", "trust": { "score": 91.6, "class": "VERY_HIGH" }, "evidence_confidence": 56, "dimensions": { "reliability": 92, "consistency": null, "evidence_strength": null, "peer_validation": null, "contradiction": null, "decay": null }, "flags": { "material_contradiction": false, "insufficient_evidence": false } } - 400Invalid request body or parameters.
- 401Missing or invalid tenant API key.
- 404Decision not found.
- 429Rate limit exceeded (120 requests per minute).
Authority
What the AI may do: EXECUTE, CONSTRAIN, CHALLENGE, ESCALATE or BLOCK.
post/api/authority/evaluateEvaluate authority
Applies your policy to the trust state and returns one of five states. EXECUTE and CONSTRAIN are immediately usable (status: active); ESCALATE requires a human operator; CHALLENGE needs more evidence; BLOCK is final. The response also lists the alternatives AIM rejected and why.
Request body
Example request
{
"decision_id": "DEC_41c2…",
"trust_state_id": "TRS_2d8f…",
"policy_id": "POL_c4d1…"
}Responses
- 200Authority issued.
{ "authority_id": "AUT_2b7c…", "authority": "ESCALATE", "reason_codes": [ "POLICY_RULE_MATCH" ], "constraints": { "amount": 2400 }, "status": "issued", "required_next_step": { "type": "human_review" }, "rejected_alternatives": [ { "authority": "EXECUTE", "reason": "exceeds autonomous authority envelope" } ] } - 400Invalid request body or parameters.
- 401Missing or invalid tenant API key.
- 404Decision, trust state or policy not found.
- 429Rate limit exceeded (120 requests per minute).
post/api/authority/{authorityId}/approveResolve an escalation (human approval)
A signed-in operator of your organization resolves an ESCALATE authority. The original is never modified: AIM issues a new authority that supersedes it.
Requires X-Operator-Token in addition to the API key.
Parameters
Request body
Example request
{
"grant": "EXECUTE",
"reason": "Verified with the customer by phone"
}Responses
- 200New superseding authority.
{ "authority_id": "AUT_9d0e…", "authority": "EXECUTE", "status": "active", "supersedes_authority_id": "AUT_2b7c…" } - 400Invalid request body or parameters.
- 401Missing/invalid API key or operator token.
- 409Not an escalation, or already resolved.
- 429Rate limit exceeded (120 requests per minute).
post/api/authority/{authorityId}/revokeRevoke an unused authority
Requires X-Operator-Token in addition to the API key.
Parameters
Request body
Example request
{
"reason": "On hold pending review"
}Responses
- 200Revoked.
{ "authority_id": "AUT_9d0e…", "status": "revoked" } - 401Missing or invalid tenant API key.
- 409Already consumed or not revocable.
- 429Rate limit exceeded (120 requests per minute).
Actions & Outcomes
Execute only with a valid authority, then report what happened.
post/api/actionsExecute an action
Executes through AIM with a valid authority. Validation and consumption are atomic: an authority can be used once, the payload must fit the authorized envelope, and retries with the same idempotency_key return the original result.
Request body
Example request
{
"decision_id": "DEC_41c2…",
"authority_id": "AUT_9d0e…",
"action_type": "issue_refund",
"payload": {
"amount": 200
},
"idempotency_key": "order-8841-refund-exec"
}Responses
- 200Replayed: this idempotency_key was already executed.
{ "action_id": "ACT_5e18…", "status": "executed", "replayed": true } - 201Executed.
{ "action_id": "ACT_5e18…", "status": "executed", "executed_at": "2026-09-29T14:02:11.000Z" } - 400Invalid body, or the authority belongs to another decision.
- 401Missing or invalid tenant API key.
- 403Denied. Reasons: AUTHORITY_STATE_NOT_EXECUTABLE, AUTHORITY_NOT_ACTIVE, AUTHORITY_EXPIRED, ACTION_TYPE_PROHIBITED, ACTION_TYPE_NOT_PERMITTED, ENVELOPE_VIOLATION:<field>.
- 404Authority not found.
- 409A concurrent request consumed the authority first.
- 429Rate limit exceeded (120 requests per minute).
post/api/outcomesRecord an outcome
Reports what happened after an action. AIM turns it into new evidence and a reliability signal, so the next trust evaluation reflects real performance.
Request body
Example request
{
"action_id": "ACT_5e18…",
"outcome_type": "refund_settled",
"success": true
}Responses
- 201Recorded.
{ "outcome_id": "OUT_a3f0…", "evidence_id": "EVD_77c1…", "signal_id": "SIG_d4e2…" } - 400Invalid request body or parameters.
- 401Missing or invalid tenant API key.
- 404Action not found.
- 409The action was not executed.
- 429Rate limit exceeded (120 requests per minute).
Operators
Your human reviewers, who resolve escalations.
post/api/tenant-operatorsRegister an operator
Registers one of your organization's human reviewers. Operators can only act for your organization.
Request body
Example request
{
"email": "ops@acme.com",
"password": "••••••••",
"name": "Ops Lead"
}Responses
- 201Created.
- 400Invalid request body or parameters.
- 401Missing or invalid tenant API key.
- 409Operator already exists.
- 429Rate limit exceeded (120 requests per minute).
post/api/tenant-operators/loginOperator sign-in
Exchanges an operator's credentials for a 12-hour operator token, sent as X-Operator-Token when approving or revoking.
Request body
Example request
{
"email": "ops@acme.com",
"password": "••••••••"
}Responses
- 200Signed in.
{ "operator_token": "eyJ…", "operator_id": "b21c…", "email": "ops@acme.com", "expires_in": "12h" } - 401Wrong credentials.
- 429Rate limit exceeded (120 requests per minute).
Audit
Tamper-evident governance log and operational alerts.
get/api/decisions/{decisionId}/governanceGovernance log for a decision
Every event recorded for the decision, oldest first. Each event stores the hash of the previous one; chain_valid tells you whether the chain still verifies (i.e. nothing was altered).
Parameters
Responses
- 200Governance log.
{ "decision_id": "DEC_41c2…", "chain_valid": true, "events": [ { "event_type": "trust_state.evaluated", "event_hash": "1a77…", "previous_hash": null }, { "event_type": "authority.escalate", "event_hash": "3830…", "previous_hash": "1a77…" } ] } - 401Missing or invalid tenant API key.
- 404Decision not found.
- 429Rate limit exceeded (120 requests per minute).
get/api/ops/alertsOperational alerts
What needs attention: escalations pending for more than 24 hours, authorities that expired unused, and open contradictions.
Responses
- 200Alerts.
- 401Missing or invalid tenant API key.
- 429Rate limit exceeded (120 requests per minute).