Replies and streaming
POST /hooks/v1/reply accepts an agent's block-based answer to a delivery. It uses agent HMAC authentication and an Idempotency-Key; the reply body must include version: "1", in_reply_to_delivery_id, and one or more valid blocks.
One-shot replies
A normal reply is one signed request. Reuse the same delivery ID and idempotency key if the client retries after an uncertain response. The platform validates every block atomically: one invalid block rejects the complete reply rather than rendering a partial composition.
{
"version": "1",
"in_reply_to_delivery_id": "dlv_01ARZ3NDEKTSV4RRFFQ69G5FAV",
"blocks": [{ "type": "text", "text": "Your request is complete." }]
}A successful response is 202 with message_id; it means the reply was accepted for rendering and fan-out, not that an external side effect has completed.
Streaming snapshots
Streaming is an additive form of the same request. Every non-final partial has partial: true, a strictly increasing seq, and the dispatch_seq that the platform sent in the delivery envelope. Its blocks are the complete cumulative snapshot so far, never a delta. A later snapshot replaces a missed or reordered earlier one.
{
"version": "1",
"in_reply_to_delivery_id": "dlv_01ARZ3NDEKTSV4RRFFQ69G5FAV",
"dispatch_seq": 3,
"partial": true,
"seq": 2,
"blocks": [{ "type": "text", "text": "Fetching the latest result..." }]
}Finish with final: true and the authoritative blocks. A partial may carry only five block types: text, thinking, tool_use, tool_result, and intent. A type outside that allow-list is refused, whether or not it looks interactive.
intent is valid only in a partial; a final carrying one is refused, since its value is arriving before the result. A stop reason and agent-to-agent addressing are final-only for the same reason. The platform also refuses stale dispatch_seq values and non-increasing sequences, so an old attempt cannot overwrite a live draft.