Aira

Receipts & Verification

Cryptographic receipts — your tamper-proof audit trail.

How Receipts Work

Every case execution automatically generates a cryptographic receipt:

  1. A canonical JSON payload is built from all inputs, outputs, and metadata
  2. The payload is serialized with sorted keys and no whitespace (deterministic)
  3. A SHA-256 hash is computed
  4. The hash is signed with Ed25519 using Aira's signing key
  5. An RFC 3161 trusted timestamp is obtained from an independent authority
  6. The receipt is stored in an append-only table (updates and deletes are blocked at the database level)

The result: a tamper-proof artifact that proves what each model said, when, and whether they agreed — verifiable by anyone, without calling Aira.

Receipt Fields

FieldDescription
receipt_idUnique receipt identifier
payload_hashsha256:... hash of the canonical payload
signatureed25519:... digital signature (base64url)
public_key_idWhich signing key was used (supports rotation)
timestampWhen the receipt was created (ISO 8601 UTC)
timestamp_authorityIndependent TSA that certified the timestamp
receipt_versionSchema version (currently 1.0)
verify_urlPublic URL for verification (no auth required)

Get Receipt

GET /api/v1/receipts/{receipt_id}
Authorization: Bearer aira_live_xxxxx

Returns the full receipt with case consensus and all model results.

Export Receipt

GET /api/v1/receipts/{receipt_id}/export
Authorization: Bearer aira_live_xxxxx

Returns the receipt as a structured JSON document suitable for auditors.

Verify Receipt (Public)

Verification requires no authentication. Share the URL with anyone who needs to verify.

GET /api/v1/verify/{receipt_id}
Response
{
  "valid": true,
  "receipt_id": "rct_01J8X...",
  "verified_at": "2026-03-14T15:00:00Z",
  "public_key_id": "aira-signing-key-v1",
  "message": "Receipt exists and signing key is valid.",
  "request_id": "req_..."
}

Offline Verification

You can verify receipts without calling Aira:

  1. Fetch the public key from /.well-known/keys
  2. Reconstruct the canonical JSON payload (sorted keys, no whitespace)
  3. Compute SHA-256 hash
  4. Verify the Ed25519 signature against the public key
Offline verification
import base64, hashlib, json
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey

# 1. Get public key (cache this)
pub_bytes = base64.b64decode(public_key_b64)
public_key = Ed25519PublicKey.from_public_bytes(pub_bytes)

# 2. Reconstruct canonical payload
canonical = json.dumps(payload, sort_keys=True, separators=(",", ":"))

# 3. Verify signature
sig_bytes = base64.urlsafe_b64decode(signature.removeprefix("ed25519:"))
public_key.verify(sig_bytes, canonical.encode())  # Raises on failure
print("Receipt is valid and untampered")

Signing Keys

GET /api/v1/.well-known/keys

Returns all signing keys (active and retired) with their validity periods:

{
  "keys": [
    {
      "id": "aira-signing-key-v1",
      "public_key": "base64-encoded-ed25519-public-key",
      "algorithm": "Ed25519",
      "status": "active",
      "valid_from": "2026-03-01T00:00:00Z",
      "valid_until": null
    }
  ]
}

Old receipts always verify against their original signing key — key rotation never invalidates existing receipts.

Compliance Mapping

RegulationRequirementHow Receipts Satisfy It
EU AI Act Art. 12Automatic event loggingEvery case run logged with crypto proof
EU AI Act Art. 13TransparencyEach model's reasoning preserved
EU AI Act Art. 14Human oversightDisagreement triggers review flag
EU AI Act Art. 86Right to explanationFull model responses in receipt
SR 11-7Model benchmarkingMulti-model comparison documented
GDPR Art. 22Automated decision transparencyDecision path auditable

On this page