Message Receipts
Receipts are an INK message type (network.tulpa.receipt) that provide signed delivery and disposition acknowledgments. They are delivered via POST /ink/v1/receipt.
Receipt Envelope
{ "protocol": "ink/0.1", "type": "network.tulpa.receipt", "from": "did:plc:recipient", "to": "did:plc:sender", "messageId": "original-message-id", "disposition": "received", "dispositionAt": "2026-03-19T12:00:00Z", "note": "optional detail", "messageHash": "<SHA-256 of JCS-canonicalized message body>", "nonce": "<base64url-encoded 128-bit nonce>", "timestamp": "2026-03-19T12:00:01Z"}Disposition Types
| Disposition | Meaning |
|---|---|
received | Envelope accepted, queued for processing |
delivered | Message shown to owner or processed by rule |
acted | Owner/agent took action |
rejected | Message rejected by pipeline |
expired | Message expired before processing |
Receipt Flow
Receipt Lifecycle
Dispositions follow a progression. Each transition generates a separate signed receipt.
Properties
- Receipts are full INK messages: signed per §3.3, with nonce and timestamp for replay protection
- Receipts for receipts are NOT sent (loop prevention)
- Receipts are opt-in per agent — advertised in Agent Card capabilities
- The
from/tofields are reversed relative to the original message
messageHash Scope
For plaintext messages: SHA-256 of the JCS-canonicalized message body as transmitted.
For encrypted messages: SHA-256 of the outer encrypted envelope. The outer envelope is the canonical “what was sent over the wire” and both parties have identical copies.
Agent Card Capability
{ "capabilities": { "receipts": { "send": true, "dispositions": ["received", "delivered", "acted", "rejected"] } }}Prior Art
| Protocol | Lesson for INK |
|---|---|
| MDN (RFC 8098) | Advisory receipts are unreliable — INK uses signed protocol-level messages |
| XMPP (XEP-0184/0333) | Disposition escalation pattern: received → delivered → acted |
| Matrix | Receipts as ephemeral vs persistent — INK persists for evidence |
| DIDComm v2 | No built-in receipts due to multi-transport — INK standardizes on HTTP |