Reply workflows
A delivery closes with one of three shapes: a single answer, a sequence of progress snapshots, or a reply that points at uploaded media. All three acknowledge quickly, sign the exact outbound bytes, and retry on a stable idempotency key.
Delivery ID
X-Delivery-Id
Compose
1-20 blocks
Sign
exact bytes
Send
POST /hooks/v1/reply
Accepted
202
| If you want to... | Start here |
|---|---|
| Send one answer | One-shot replies |
| Show progress while you work | Streaming replies |
| Attach a file, image, or video | Asset replies |
Before you start
- A verified, deduplicated delivery. See integrate an existing service if your adapter does not do this yet.
- The block vocabulary in the interaction reference; one invalid block rejects the whole reply.
One-shot replies
Take the delivery ID
Read
X-Delivery-Idafter raw-body signature verification. Use that value inin_reply_to_delivery_idand as the ordinaryIdempotency-Key; a conversation ID is correlation data, not authority to pick a destination.Compose the body
A minimal reply carries the protocol version, its source delivery, and one to twenty valid blocks:
JSON{ "version": "1", "in_reply_to_delivery_id": "dlv_01ARZ3NDEKTSV4RRFFQ69G5FAV", "blocks": [{ "type": "text", "text": "Hello from the agent." }] }See the interaction reference for block semantics and the reply API reference for the full request shape.
Sign and send
Serialize once and keep the exact bytes.
POST /hooks/v1/replywithContent-Type: application/json,Authorization: HMAC <agent-id>/<credential-id>,X-Platform-Signature, andIdempotency-Key. The signature coverstimestamp + "." + raw body, never a parsed object.A
202with a message ID means the platform accepted the reply, not that a client rendered it.
Streaming replies
Choose streaming when useful work outlasts a quick acknowledgement, or partial progress helps the user. It sends multiple signed reply requests for one delivery, not a long-lived append channel.
Send cumulative snapshots
Every partial reply is a complete cumulative snapshot, not a text delta. Echo the delivery's
dispatch_seq, incrementseqmonotonically, and key each onedelivery-id:dispatch-seq:seq:JSON{ "version": "1", "in_reply_to_delivery_id": "dlv_01ARZ3NDEKTSV4RRFFQ69G5FAV", "partial": true, "dispatch_seq": 3, "seq": 1, "blocks": [{ "type": "text", "text": "Searching the requested records..." }] }Do not manufacture
dispatch_seq; the delivery envelope supplies it. A later snapshot replaces the earlier one on screen, so send all current text rather than only new words.Finish the stream
Send a final signed reply with the authoritative completed blocks and
final: true, keyed by the ordinary delivery ID.stop_reasonis final-only and must not appear on a partial.
Asset replies
Assets keep large media bytes out of the control-plane reply request.
Request an upload
Send a signed
POST /hooks/v1/assetswith the MIME type and intended size:JSON{ "mime_type": "image/jpeg", "size_bytes": 84213 }The response carries an
asset_id, a temporaryupload_url, and an expiry. This request has no idempotency key; an extra unused upload ticket is harmless.Upload and confirm
Upload with the declared
Content-Type, then send the signed, bodyless confirmation toPOST /hooks/v1/assets/{assetId}/confirm. Requirefound: truebefore replying; a successful upload response alone does not prove the object is available.Reference the asset
Reference the confirmed ID from an image, file, audio, video, or card-image block:
JSON{ "type": "image", "asset_id": "ast_01ARZ3NDEKTSV4RRFFQ69G5FAV", "alt_text": "A labeled chart" }For image, audio, and a card's image, the platform checks at write time that the asset is yours and its stored MIME type matches the block; a mismatch is refused, not rendered broken.
When something does not work
Do not retain upload or download URLs as durable identifiers. Request a fresh owner-scoped URL for an agent-owned asset, and use the message-reachability asset endpoint for media received in a conversation.
Next steps
- Send blocks the platform enforces. The interaction reference lists every type.
- Mediate a privileged action. Request an approved action covers the tool-invocation path.
- Something silent? Troubleshoot an agent covers rejected replies and stalled streams.