Estimates

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).

get/v1/estimate/{estimateJobId}/stream

Request

  • Base URL: https://api.handoff.ai
  • URL: https://api.handoff.ai/v1/estimate/{estimateJobId}/stream
  • Auth: HTTP bearer

Path parameters

estimateJobIdstring required

Estimate identifier — either the UUID job ID or your internal externalId.

Example:e1a2b3c4-d5e6-4f7a-8b9c-0d1e2f3a4b5c

Query parameters

versionstring

Specific version to stream. If omitted, streams the current/latest version.

Example:2

Headers

Last-Event-IDstring

Resume cursor — the id of the last event received. Omit to replay from the buffer.

Example:1720448400000-0

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.