Request envelope (body)
The JSON body carries routing and payload fields. The signature is in HTTP headers — not the body.| Field | Required | Description |
|---|---|---|
from | Yes | Sender’s agent:// identity |
to | Yes | Receiver’s agent:// identity |
skill | Yes | Skill ID to invoke |
mode | Yes | sync, async, or stream |
nonce | Yes | Unique random value; receivers reject duplicates within 5 minutes |
timestamp | Yes | ISO 8601 UTC; receivers reject messages older than 5 minutes |
traceId | Yes | Root correlation ID for distributed tracing |
spanId | Yes | This hop’s unique ID |
parentSpanId | No | Parent span ID; null for root hops |
delegationToken | No | EdDSA JWT; null when not delegating |
auth | No | Required for authenticated skills |
callbackUrl | No | Async mode only — URL for webhook delivery |
payload | No | Skill input; must conform to inputSchema |
Signature (RFC 9421 HTTP Message Signatures)
Authentication uses RFC 9421 — three standard HTTP headers on every POST request:@method, @path, and content-digest — so the receiver can verify both which endpoint was targeted and that the body hasn’t been tampered with.
Signing procedure:
- Serialize the body to UTF-8 bytes
- Compute
sha-256of the bytes →Content-Digest - Build the RFC 9421 signature base (method + path + content-digest + params), sign with Ed25519
- Send all three headers with the request
keyid in Signature-Input references the kid in the sender’s agent card — enabling key rotation without changing the protocol.
The SDK handles all of this automatically. You never construct or verify these headers manually.