PEAC Receipts API
Complete reference for implementing verifiable interaction records. Every HTTP response becomes tamper-evident proof of content, consent, attribution, provenance, and payments.
Spec Snapshot (v0.10.0)
JWS Header Fields
| Field | Type | Status | Description |
|---|---|---|---|
| alg | string | Required | Must be "EdDSA" for Ed25519 signatures |
| typ | string | Required | Must be "peac-receipt/0.1" |
| kid | string | Required | Key identifier for signature verification |
Receipt Payload Fields
| Field | Type | Status | Description |
|---|---|---|---|
| iat | number | Required | Issued at time (Unix timestamp) |
| hash | string | Recommended | Content hash (e.g., "sha256:abc123...") |
| aipref | object | Optional | AI preferences compliance reference |
| payment | object | Optional | Payment scheme details (e.g., x402, stripe) |
| prov | object | Optional | Provenance metadata (e.g., C2PA) |
| aud | string | Optional | Intended audience for the receipt |
| sub | string | Optional | Subject of the content |
| attestations | object[] | Optional | Third-party attestations (e.g., risk assessments) |
| extensions | object | Optional | Namespaced extensions (domain/key pattern) |
HTTP Headers
PEAC-ReceiptRequiredSingle HTTP response header containing the detached JWS compact serialization. This is the only normative header in PEAC Protocol v0.10.0.
Basic Example
HTTP/1.1 200 OK
Content-Type: application/json
PEAC-Receipt: eyJhbGciOiJFZERTQSIsInR5cCI6InBlYWMucmVjZWlwdC8wLjkiLCJraWQiOiJwZWFjLTIwMjUtMDkifQ.eyJpYXQiOjE3Mjc1OTM4MDAsImhhc2giOiJzaGEyNTY6YTFiMmMzLi4uIiwiYWlwcmVmIjp7InVybCI6Ii4uLmFpLXByZWZlcmVuY2VzLnR4dCJ9LCJwYXltZW50Ijp7InNjaGVtZSI6Ing0MDIifSwicHJvdiI6eyJjMnBhIjoic2hhMjU2Oi4uLiJ9fQ.signature_base64url
{
"data": "Your content here",
"attribution": "Content provided under PEAC Protocol terms"
}Decoded JWS
Header
{
"alg": "EdDSA",
"typ": "peac-receipt/0.1",
"kid": "peac-2026-01"
}Payload
{
"iat": 1727593800,
"hash": "sha256:a1b2c3...",
"aipref": {
"url": "...ai-preferences.txt"
},
"payment": {
"scheme": "x402"
},
"prov": {
"c2pa": "sha256:..."
}
}Dispute Bundles (v0.9.30+)
Portable, offline-verifiable evidence packages for disputes, audits, and cross-org handoffs.
A bundle contains receipts, policy snapshots, and a deterministic verification report - everything needed to prove what happened without trusting either party's internal logs.
Bundle Structure
Format
- •ZIP archive with deterministic structure (RFC 8785 canonical JSON)
- •Version:
peac.dispute-bundle/0.1 - •Offline verification fails if keys are missing (no silent network fallback)
- •Cross-language parity: TypeScript and Go produce identical verification reports
Contents
bundle.peacbundle/ ├── manifest.json # Bundle metadata, receipt list, policy ref ├── receipts/ │ ├── receipt_001.jws # Individual receipt JWS tokens │ ├── receipt_002.jws │ └── ... ├── keys/ │ └── jwks.json # Public keys for verification ├── policy/ │ └── peac-policy.yaml # Policy snapshot (optional) └── verification_report.json # Deterministic report with report_hash
CLI Workflow
# Create a dispute bundle peac bundle create \ --receipts ./receipts.ndjson \ --policy ./policy.yaml \ --output ./evidence.peacbundle # Verify bundle offline peac bundle verify ./evidence.peacbundle --offline # Display bundle info peac bundle info ./evidence.peacbundle --json
Deterministic Verification
The verification report includes a report_hash field - a SHA-256 hash of the JCS-canonicalized report. This provides cross-platform and cross-language audit-grade evidence that different verifiers produce identical results.
Error Codes (9 codes)
| Code | Description |
|---|---|
| E_BUNDLE_INVALID_FORMAT | Bundle is not a valid ZIP archive |
| E_BUNDLE_MISSING_MANIFEST | manifest.json not found |
| E_BUNDLE_HASH_MISMATCH | Content hash does not match manifest |
| E_BUNDLE_KEY_NOT_FOUND | Required public key missing from bundle |
| E_BUNDLE_RECEIPT_INVALID | Receipt signature verification failed |
specs/kernel/errors.json for all 9 bundle error codesAPI Endpoints (non-normative examples)
/v1/receipts/:id/confirmExample (non-normative)Confirm and validate a PEAC receipt for resource access.
Request Headers
PEAC-Receipt: rcpt_01HZY3Z3V7C7 Accept: application/json Content-Type: application/json
Request Body
{
"jws": "<detached JWS compact serialization>",
"kid": "peac_pub_2025_08",
"policy_hash": "7K2dmfqM5JdCiQ_9gTXeYZRqh8L_2vKxg3BjPMvqWxA",
"agent_id": "agent_9f3b2"
}Response (202 Accepted)
{
"jti": "rcpt_9D328FC8",
"method": "peac.receipt",
"kid": "peac_pub_2025_08",
"sig_alg": "Ed25519",
"time": "2025-08-30T18:12:03Z",
"agent_id": "agent_9f3b2",
"resource": "https://example.com/api/data",
"status": "VALID",
"id": "rcpt_01HZY3Z3V7C7"
}Error Codes
| Code | Error | Description |
|---|---|---|
| 400 | INVALID_INPUT | Malformed payload or fields |
| 401 | UNAUTHORIZED | Missing or invalid auth on caller |
| 403 | POLICY_MISMATCH | Receipt policy does not match current peac.txt |
| 409 | REPLAY | Receipt previously used or nonce replay |
| 422 | SIG_INVALID | Signature or key reference invalid |
| 429 | RATE_LIMITED | Too many requests |
Security Requirements
Important
- - Receipt verification requires EdDSA signature validation
- - Receipt rid must use UUIDv7 (RFC 9562) for replay protection
- - JWKS must be served from issuer domain for verification
- - Timestamp validation with reasonable clock skew tolerance (<5 minutes)