Direct answer

AER-1 Receipt JSON Schema

An AER-1 receipt is one JSON record for one agent tool call, built to be checked by a stranger. Its core fields name the call, reference its inputs, commit to its result with an output hash over canonical bytes, stamp when it happened, and optionally carry external anchors. This page explains the schema field by field, separates required fields from optional members, and shows how validation runs. The machine-readable schema itself lives in the open kit, not on this page.

The machine-readable schema and the conformance corpus live in the AER-1 kit repository, folder aer-1. The normative definition is draft-zambo-aer1 on the IETF Datatracker. Check a live receipt free at zambo.dev/verify.

Updated October 20, 2026.

The core fields, one by one

Receipt id

A stable identifier for this exact record. It locates the receipt, and under the draft -21 rule it sits outside the committed payload: it binds to the record only via an externally supplied expected id or Section 9 resolution with digest comparison. A verifier reports an unbound id as unverified.

Tool

The name of the tool that ran for this call. A receipt records one tool call, so this field names the single call the record covers, not a whole session or a multi-step job.

Inputs reference

A reference to what went into the call, so a checker can see what the output claims to answer. The reference lets validation confirm the recorded inputs are the inputs the payload commits to, without turning the receipt into a copy of every system around it.

Output hash

The hash commitment over the saved result. Validation recomputes the hash over the receipt's canonical bytes and compares: a match means the saved result was not changed after the fact, and a mismatch means it was, or the bytes are not the bytes that were committed.

Timestamps

When the call ran and when the record was made. Timestamps order the record and let a checker place the call in time. They are part of the record a verifier reads, and altering them alters the record the hash covers.

Anchors (optional)

External anchors a producer chose to attach, such as a SCITT registration or an RFC 3161 timestamp, both permitted since draft -18. Each anchor is reported with a Section 6 outcome under draft -24: verified, verification failed, rejected: unresolvable record, not checked when it was not evaluated, and the anchor member is simply absent when no anchor exists.

Required fields and optional members

The required core is small on purpose: the fields a checker needs to identify the record, name the call, reference the inputs, recompute the output hash, and place the call in time. Everything beyond that core is an optional member: anchors are the clearest example, present only when a producer anchored the receipt. Producers may also carry extra members for their own tooling. A verifier checks the core the draft defines; optional members extend a receipt without changing what the core check means, and a receipt is not invalid for leaving an optional member out.

Canonical bytes: why field order is not the check

JSON text can vary in spacing and ordering while meaning the same thing, and a hash over raw text would break on harmless variation. AER-1 solves this the way the draft specifies: the record is reduced to canonical bytes, a single exact byte form, and the output hash commits to those bytes. Validation rebuilds the canonical bytes from the record and recomputes. Two records with the same meaning produce the same canonical bytes; any change to the committed content produces different bytes and a different hash.

How validation works

  1. Read the core fields. Confirm the required fields are present and well formed.
  2. Rebuild the canonical bytes from the record exactly as the draft specifies.
  3. Recompute the output hash and compare it with the hash the receipt carries.
  4. Check the id state. Report the receipt id as bound only via an expected id or Section 9 resolution with digest comparison; otherwise report it as unverified.
  5. Report anchors honestly. For each anchor, report its Section 6 outcome, including not checked when the anchor was not evaluated.

The open conformance kit exercises this procedure as 119 vectors and 122 checks at draft -24, so a schema question that prose leaves open gets settled by running the corpus.

Where the machine-readable schema lives

In the kit repository, folder aer-1, alongside the draft text, the test vectors, and the runners in 7 languages. That placement is deliberate: the schema, the vectors, and the checkers version together, so the file you validate against is the same revision the corpus tests. This page is the explanation; the kit is the source of truth, and the draft text governs where the two ever differ.

Cite this draft

Cite AER-1 as the IETF Internet-Draft draft-zambo-aer1, current revision -24, posted October 20, 2026 and expiring April 23, 2027, at datatracker.ietf.org/doc/draft-zambo-aer1.

@misc{zambo-aer1,
  author = {Brennan Zambo},
  title = {AER-1: Agent Execution Receipt, version 1},
  howpublished = {IETF Internet-Draft draft-zambo-aer1-24},
  year = {2026},
  url = {https://datatracker.ietf.org/doc/draft-zambo-aer1/}
}

Honest limits

This page describes the fields the draft defines; it does not reproduce the full machine-readable schema, and it invents no fields beyond the record the draft and kit carry. Read the schema from the kit for building, and the draft text for anything normative. And the standing limit applies to the format itself: validation proves the saved result was not changed after the fact. It never proves the result was correct.

Frequently asked questions

What fields does an AER-1 receipt contain?

The core fields are the receipt id, the tool that ran, an inputs reference, the output hash committed over the canonical bytes, and timestamps for the call and the record. Anchors are an optional member, present only when a producer anchored the receipt externally, for example with a SCITT registration or an RFC 3161 timestamp.

Where does the machine-readable AER-1 schema live?

In the open kit repository, gitlab.com/rambozambodotdev/zambo, in the aer-1 folder, alongside the draft text, the test vectors, and the runners. The schema versions with the kit so the file you validate against is the same revision the conformance corpus tests. The draft text at the IETF Datatracker is the normative definition.

How does AER-1 receipt validation work?

Rebuild the canonical bytes from the record exactly as the draft specifies, recompute the output hash, and compare it with the hash the receipt carries. Then check the id state: an id is bound only via an externally supplied expected id or Section 9 resolution with digest comparison. Finally, report each anchor with its Section 6 outcome, including not checked for an anchor that was not evaluated.

What is the output hash in an AER-1 receipt?

It is the hash commitment over the saved result, computed over the receipt's canonical bytes. Recomputing it is the foundation check: a match means the saved result was not changed after the fact, and a mismatch means the bytes being checked are not the bytes that were committed. It proves nothing about whether the result was correct.

Are anchors required in an AER-1 receipt?

No. Anchors are optional members. A receipt with no anchor is complete, and its anchor state is reported as absent under draft -24. When a producer does attach an anchor, such as a SCITT registration or an RFC 3161 timestamp, each anchor is reported with its own Section 6 outcome.

Related