Stream estimate update progress (SSE)
Opens a Server-Sent Events stream of live progress for an asynchronous estimate update, from file extraction through the AI edit to material matching.
Streaming is a read-only side-channel — consuming it is optional. The authoritative result is still delivered by the completion webhook and GET /v1/estimate/{estimateJobId}. The streamUrl returned by POST /v1/estimate/{estimateJobId}/update points here.
Event frames Each SSE frame is id, event, and data. id is the resume cursor, event is the event type, and data is a JSON EstimateStreamEvent. Comment lines (: ping) are heartbeats — ignore them.
Event types
- phase — lifecycle stage: extracting → editing → finalizing → matching (extracting only when the update includes files still being processed; prompt-only updates start at editing).
- status — a tool/step started or finished.
- message — assistant text (incremental deltas and/or a final summary).
- estimate_change — a row was added / updated / removed (change.op).
- matching_progress — matched of total materials matched.
- done / error — terminal; the server then closes the connection. done carries a resultUrl.
Versioning Omit version to stream the latest version (the one the most recent update created), or pass ?version=N.
Reconnecting The stream is resumable: reconnect and send the last id you received in the Last-Event-ID header to resume with no gaps or duplicates. Without it, recent buffered events (~1h) are replayed so a late subscriber catches up. Each connection is capped (~110s) and closed with an event: reconnect; just reconnect with the cursor. This makes long (15+ minute) runs resilient to proxy/CDN idle timeouts.
Note: Browsers' native EventSource cannot send an Authorization header — use fetch with a streaming body reader (or an SSE client that supports custom headers).
Request
- Base URL: https://api.handoff.ai
- URL: https://api.handoff.ai/v1/estimate/{estimateJobId}/stream
- Auth: HTTP bearer
Path parameters
Estimate identifier — either the UUID job ID or your internal externalId.
Query parameters
Specific version to stream. If omitted, streams the current/latest version.
Headers
Resume cursor — the id of the last event received. Omit to replay from the buffer.
Response
An open text/event-stream. Each event's data field is an EstimateStreamEvent. The stream stays open until a terminal done/error event, then closes.
Changes
No recorded changes to this operation across all 1 revision of this API.