Developers · API v1.0.0

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.

Overview

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:

  1. 01

    Decision

    The AI proposes an action.

  2. 02

    Trust

    AIM scores the agent from its evidence.

  3. 03

    Authority

    Your policy turns trust into one of five states.

  4. 04

    Action

    Runs only through AIM, within the authority.

  5. 05

    Outcome

    What happened feeds back into trust.

Every step is written to a tamper-evident governance log you can read back per decision.

Quickstart

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}'
Authority

The five authority states

EXECUTEAllowed. The action can run through AIM within the policy's envelope.
CONSTRAINAllowed with limits. The action runs only inside the returned constraints.
CHALLENGENot enough evidence yet. Send more signals or evidence, then evaluate again.
ESCALATEA human decides. One of your operators approves or rejects it; silence never approves.
BLOCKDenied. The action cannot run.

Each authority can be used for exactly one action. Using it twice returns 409 AUTHORITY_ALREADY_CONSUMED, even under concurrent requests.

Concepts

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

Errors and rate limits

Errors return a JSON body with an error field (and reason on denied actions).

StatusMeaningWhat to do
400Invalid payloadThe body failed validation. Fix the request; retrying will not help.
401Invalid tenant API keyMissing or wrong Authorization: Bearer key.
403Action deniedThe authority does not allow this action. reason says why (e.g. AUTHORITY_EXPIRED, ENVELOPE_VIOLATION:amount).
404Not foundThe id does not exist in your organization.
409ConflictState conflict, e.g. AUTHORITY_ALREADY_CONSUMED or an escalation already resolved.
429Too many requestsRate limit reached. Back off and retry after the RateLimit-Reset seconds.
500Internal errorSafe to retry with the same idempotency key.

Rate limits: 120 requests per minute per client IP. Responses include standard RateLimit-* headers.

Performance

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.

Governed flow · p50

47 ms

All four steps, one client, median.

Governed flow · p95

121 ms

95% of flows finished within this.

Reliability

0 errors

1,650 governed flows at 1–100 concurrent clients.

Stepp50p95
Create decision5.5 ms6.7 ms
Evaluate trust16.4 ms20.5 ms
Evaluate authority11.1 ms13.5 ms
Execute action13.6 ms15.6 ms
Record outcome16.8 ms18.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.
Reference

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

entity_typerequired
member | ai_agent | organization | device | system
external_ref
string — Your own identifier for this actor.
name
string
metadata
object

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

context_typerequired
string
risk_class
string
metadata
object

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

policy_keyrequired
string
decision_typerequired
string
versionrequired
string
rulesrequired
PolicyRule[]

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

dimensionrequired
reliability | consistency | peer_validation | contradiction | decay
directionrequired
positive | negative | neutral
strengthrequired
number
confidencerequired
number
source_entity_id
string
source_evidence_id
string
target_entity_id
string
target_claim_id
string
target_decision_id
string
observed_at
string
effective_from
string
expires_at
string
decay_model
exponential
half_life_days
number — Required when decay_model is set.
metadata
object

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

evidence_typerequired
document | observation | api_response | attestation | verified_claim | machine_event | human_verification | policy_result | historical_behavior
contentrequired
object
provenance
object
claim_id
string
decision_id
string
observed_at
string

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

proposed_by_entity_idrequired
string
target_entity_id
string — Subject of the trust evaluation (defaults to the proposer).
decision_typerequired
string
proposed_actionrequired
string
model_confidence
number
context_id
string
risk_class
string
payloadrequired
object — What the AI wants to do. Policy conditions read these fields.
idempotency_key
string

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

decisionIdrequired
path

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

decision_idrequired
string
context_id
string

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

decision_idrequired
string
trust_state_idrequired
string
policy_idrequired
string

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

authorityIdrequired
path

Request body

grantrequired
EXECUTE | CONSTRAIN | BLOCK
scope
object
reason
string

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

authorityIdrequired
path

Request body

reason
string

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

decision_idrequired
string
authority_idrequired
string
action_typerequired
string
payload
object
idempotency_keyrequired
string

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

action_idrequired
string
outcome_typerequired
string
successrequired
boolean
observations
object

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

emailrequired
string
passwordrequired
string
name
string

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

emailrequired
string
passwordrequired
string

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

decisionIdrequired
path

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