Skip to content

The wire format ​

The X-MotherShy header carries a compact, single-line JSON envelope. This page is the authoritative schema.

The envelope ​

json
{
  "cert": { "path": "agents/alice", "pub": "<b64>", "sig": "<b64>" },
  "req":  { "agent": "<b64>", "site": "example.com", "nonce": 12345,
            "ts": 1728000000, "amt_microusd": 5, "window": 300 },
  "sig":  "<b64>",
  "cap":  { "v": 1, "id": "cap-1", "holder": "<b64>", "aud": "example.com",
            "actions": ["retrieval"], "cap_microusd": 1000,
            "issued_at": 1728000000, "expires_at": 1728003600,
            "policy_receipt": "receipt-1", "verification_mode": "offline",
            "sig": "<b64>" }
}

Field reference ​

cert — the birth certificate ​

FieldTypeMeaning
pathstringDerivation path (e.g. agents/alice)
pubbase64 (32B)Agent public key
sigbase64Mother's signature over "birth:" + path + ":" + pub

req — the request ​

FieldTypeMeaning
agentbase64Agent public key — must equal cert.pub
sitestringTarget site (the audience)
nonceintAnti-replay nonce (JS safe integer)
tsintUnix seconds
amt_microusdintAmount authorized (≤ budget)
windowintHour bucket

sig — the request signature ​

Agent's Ed25519 signature over the canonical request serialization.

cap — the capability (optional, but required to pass) ​

FieldTypeMeaning
vintVersion (must be 1)
idstringCapability id
holderbase64Agent public key — must match cert.pub
audstringAudience — must match req.site
actionsstring[]["retrieval"] only today
cap_microusdintSpend budget
issued_atintMint time
expires_atintExpiry (mandatory for offline)
policy_receiptstringPolicy receipt id
verification_modestringoffline | online
sigbase64Mother's signature over the canonical capability

The canonical byte layouts ​

Signatures are over fixed-order serializations — reproduce them exactly, never re-order:

text
cert signing bytes    = "birth:" + path + ":" + rawPub(32 bytes)

request canonical     = {"agent":<b64>,"site":<str>,"nonce":<int>,"ts":<int>,
                        "amt_microusd":<int>,"window":<int>}

capability canonical  = {"v":1,"id":<str>,"holder":<b64>,"aud":<str>,
                        "actions":["retrieval"],"cap_microusd":<int>,
                        "issued_at":<int>,"expires_at":<int>,
                        "policy_receipt":<str>,"verification_mode":<str>}

All amounts are integer micro-USD. All signatures are pure RFC 8032 Ed25519.

Don't JSON.stringify blindly

JavaScript object key order can differ from the canonical order. Always serialize fields in the fixed order above, or your signature won't verify.

Audience normalization ​

site / aud are normalized to a canonical hostname: lowercased, IDNA/punycode, scheme/path/query/port stripped, trailing dot removed. https://Example.com/path → example.com.

Next ​

MotherShy — the economic operating layer for AI agents and publishers.