Skip to main content
Everything that happens to a document is an event. The same events serve three purposes:
  • the stream mode of POST /documents;
  • reconnecting to or following a document with GET /documents/{id}/events;
  • webhooks (final events only; coming soon).

Event shape

Types

Lifecycle ⏹ = final event: nothing else arrives after it. Content (rendered live) Process

Typical order

Create from a sentence
  • Create from text: the same, but the blocks arrive almost all at once.
  • Review: no content.*: render, review, fixes, pages and final.
  • Edit: edit.planned, one edit.operation_applied (or _rejected) per change, then the same as review.
How to render it on the client: with style.resolved you set up the styles; with content.* you build the view (approximate, without pages); with preview.page_ready you replace it with the real pages.

SSE (stream and /events)

  • Reconnect: GET /documents/{id}/events with the header Last-Event-ID: 13 (or ?after=13). First the later stored events are resent (the complete blocks), then it continues live. The document keeps being processed even if the client disconnects.
  • Heartbeat (: heartbeat) every 15 s so no proxy cuts the connection.
  • After the final event, the server closes the connection.
  • Events are kept for 7 days. After that, GET /documents/{id}/events responds 410 events_expired, though the document record is still available.

Webhooks (coming soon)

  • Same event format. By default only the final ones (document.ready, document.failed, document.canceled). Never events with content.
  • Signed per Standard Webhooks: headers webhook-id, webhook-timestamp and webhook-signature (HMAC-SHA256 with a whsec_… secret).
  • Retries for ~10 h with increasing delays (5 s, 30 s, 2 min, 10 min, 30 min, 1 h, 3 h, 6 h). The client must deduplicate by webhook-id.
  • Public HTTPS URLs only (SSRF protection).