> ## Documentation Index
> Fetch the complete documentation index at: https://docs.try-airlock.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Decision events

> Reporting a consequential agent decision (with evidence) to Airlock

Most of what Airlock captures is access. An agent read a document, called a
tool, hit a host. Decision events are different: they're for the narrower
case of an agent (yours, running anywhere — it doesn't have to be inside an
Airlock sandbox) making a call that has real consequences attached, and you
want that call visible and, later, automatically flagged if it looks
unreliable.

Consider, for example, a system that uses an AI agent to resolve
prediction-market contracts. A wrong resolution can move real money, so the
agent reporting *how* it decided (what it cited, how confident it was)
matters as much as *what* it decided.

## Sending a decision event

Decision events go through the same ingestion endpoint as every other event
kind, authenticated with a bearer token (an admin mints one for your agent
identity via `POST /api/v1/admin/users/:id/tokens`).

```sh theme={null}
curl -X POST https://your-airlock-server/api/v1/events \
  -H "Authorization: Bearer $AIRLOCK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      {
        "kind": "decision",
        "source": "push-api",
        "occurred_at": "2026-07-30T18:00:00Z",
        "dedupe_key": "market-us-president-2024-resolution-1",
        "decision": {
          "target": "us-president-2024",
          "decision": "Biden",
          "confidence": 0.92,
          "reasoning": "Associated Press and all major networks called the race.",
          "sources": [
            { "title": "AP News", "url": "https://apnews.com/...", "quote": "..." }
          ]
        }
      }
    ]
  }'
```

### Fields

| Field        | Required | Notes                                                                                                                                                                                                               |
| ------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `target`     | yes      | Whatever you're deciding — a market slug, a dispute ID, anything stable enough to group repeated/conflicting decisions about the same thing later.                                                                  |
| `decision`   | yes      | The actual call, as a short string.                                                                                                                                                                                 |
| `confidence` | no       | 0–1. Omit it if your agent doesn't produce one — that's meaningful signal on its own.                                                                                                                               |
| `reasoning`  | no       | Free text.                                                                                                                                                                                                          |
| `sources`    | no       | `{url, title, quote}` — cite what the decision was based on. An empty list is different from omitting it: it says "I decided this and cited nothing," which is exactly the case Airlock most wants visibility into. |

`dedupe_key` (on the envelope, not the decision object) works the same as
every other event kind: retrying the same POST with the same key is a no-op,
so it's safe to retry on a timeout without double-reporting a decision.

<Tip>
  Keep `target` stable across agents, not just across retries. Pointing two
  independent resolvers at the same targets is the cheapest cross-check
  available - no shared prompt or failure mode. A stable
  `target` is what lets their answers be lined up against each other.
</Tip>

## What happens to it right now

Today: it's stored, queryable via `GET /api/v1/events?kind=decision` and
`GET /api/v1/sessions/:id`, and shows up in the dashboard timeline like any
other event. What it does *not* do yet: automatically flag anything.

Access and chat events use the same endpoint with `kind` set accordingly —
the CLI's `airlock publish` is just another client of this contract. See
[audit log](/audit-log) for what it ships.
