Skip to main content
Version: v0.12.4

Wire Format

The PEAC wire format defines the on-the-wire representation of receipts. It is a compact JWS (JSON Web Signature, RFC 7515) with an Ed25519 signature (RFC 8032).

Two wire formats

Two wire formats coexist: Wire 0.1 (peac-receipt/0.1, frozen legacy) and Wire 0.2 (interaction-record+jwt, stable). Both use Ed25519 JWS signatures and the PEAC-Receipt header. verifyLocal() auto-detects wire version.

Wire 0.1 (Stable)

Wire 0.1 uses flat payload claims with a simple structure.

Wire 0.1 JWS Header
{
"alg": "EdDSA",
"typ": "peac-receipt/0.1",
"kid": "<key-id>"
}
FieldRequirementValue
algMUSTEdDSA (Ed25519, RFC 8032)
typMUSTpeac-receipt/0.1
kidMUSTMatch a key in the issuer's published JWKS

Payload

Wire 0.1 Receipt Payload
{
"iss": "https://api.example.com",
"aud": "https://client.example.com",
"iat": 1709500000,
"amt": 100,
"cur": "USD",
"rail": "x402",
"reference": "tx_abc123",
"subject": "https://api.example.com/inference"
}

Wire 0.2 (Stable)

Wire 0.2 (interaction-record+jwt) adds structured kinds, typed extensions, and policy binding.

Header

Wire 0.2 JWS Header
{
"alg": "EdDSA",
"typ": "interaction-record+jwt",
"kid": "<key-id>"
}
FieldRequirementValue
algMUSTEdDSA (Ed25519, RFC 8032)
typMUSTinteraction-record+jwt
kidMUSTMatch a key in the issuer's published JWKS (max 256 chars)

Wire 0.2 rejects embedded keys (jwk, x5c, x5u, jku), crit, b64: false, and zip headers.

Payload

Wire 0.2 Evidence Receipt Payload
{
"iss": "https://api.example.com",
"iat": 1709500000,
"peac_version": "0.2",
"kind": "evidence",
"type": "org.peacprotocol/payment",
"pillars": ["commerce"],
"extensions": {
"org.peacprotocol/commerce": {
"payment_rail": "x402",
"amount_minor": "10000",
"currency": "USD"
}
},
"policy": {
"uri": "https://api.example.com/.well-known/peac.txt",
"version": "peac-policy/0.1",
"digest": "sha256:a1b2c3..."
}
}

Wire 0.2 Payload Claims

FieldRequiredDescription
issYesIssuer (canonical: https:// or did: only)
iatYesIssued-at timestamp (Unix seconds)
peac_versionYesMust be "0.2"
kindYesStructural kind: evidence or challenge
typeYesSemantic type (reverse-DNS or absolute URI)
pillarsNoVerification domains (sorted, unique, from 10-pillar taxonomy)
extensionsNoTyped extension groups (keyed by reverse-DNS)
policyNoPolicy binding (uri, version, digest)
occurred_atNoISO 8601 event time (evidence kind only)
actorNoActor binding (identity proof)
representationNoContent representation fields

Extension Groups

Wire 0.2 defines 12 typed extension groups:

KeyFieldsDescription
org.peacprotocol/commercepayment_rail, amount_minor, currency, reference?, asset?, env?Payment evidence
org.peacprotocol/accessresource, action, decision (allow/deny/review)Access control
org.peacprotocol/challengechallenge_type, problem (RFC 9457)Challenge requirements
org.peacprotocol/identityproof_ref?Identity attestation
org.peacprotocol/correlationtrace_id?, span_id?, workflow_id?, parent_jti?, depends_on?Workflow correlation

Kind Semantics

  • evidence: records something that happened. May include occurred_at.
  • challenge: declares what is required before proceeding. Uses RFC 9457 problem details. Must NOT include occurred_at.

Policy Binding

Wire 0.2 supports policy binding via JCS (RFC 8785) + SHA-256. The policy.digest field contains sha256:<64-hex-chars>. Verification returns one of three states: verified, failed, or unavailable.

Common: Signature

The signature is an Ed25519 signature computed over the JWS signing input (<header>.<payload>). Both wire formats use identical signature computation.

Delivery

HTTP

Receipts are delivered via the PEAC-Receipt response header.

HTTP Response
HTTP/1.1 200 OK
Content-Type: application/json
PEAC-Receipt: eyJhbGciOiJFZERTQSIsInR5cCI6InBlYWMtcmVjZWlwdC8wLjEiLCJraWQiOiJwZWFjLTIwMjYtMDMifQ...

Non-HTTP transports

For MCP, gRPC, WebSocket, and other non-HTTP transports, receipts are included in the response metadata using the transport's native metadata mechanism. The receipt format is identical: only the delivery channel changes.

Versioning

Dual wire formats
  • peac-receipt/0.1 (Wire 0.1): frozen legacy receipt format
  • interaction-record+jwt (Wire 0.2): stable with structured kinds, typed extensions, and policy binding
  • verifyLocal() auto-detects wire version and returns wireVersion: '0.1' or wireVersion: '0.2'
  • Both formats use Ed25519 JWS signatures and the PEAC-Receipt header