Skip to main content
Use GET /search/{id}/stream to follow search execution in real time.
Temporary searches stream in the response to POST /search/temporary instead. Their stream uses the events below and cannot be resumed.

Concrete stream example

Run this against an existing SEARCH_ID:
Typical successful session:
Typical BYOK session (providers + completion):
Typical sharding/capacity session:
Typical failed session:

Event types

connected

Sent immediately after the SSE connection is established.

module.result

Sent when one module emits a result card.
Fields:
  • search_id: search UUID
  • module.id: module identifier when available
  • module.name: module display name
  • card: raw card payload
  • timestamp: event time

search.progress

Sent during orchestration and shard execution.
Fields:
  • status: queued or running
  • message: human-readable progress (for example capacity waits or shard progress)
  • result_cards_count: optional running count

byok.result

Sent when a BYOK provider emits one raw card event.
Fields:
  • provider: osint_industries or sherlockeye
  • card: provider-emitted card payload

byok.finished

Sent once per provider when provider execution completes.
Possible status values:
  • success
  • no_results
  • failed

search.finished

Sent when the search reaches a terminal state.
Possible values for status:
  • completed
  • failed
Optional fields:
  • totals.module_results
  • execution_time_ms
  • error

leak.status

Sent for each leak source as it executes.

leak.page.ready (optional)

Sent when an early leak page has been stored and is readable, while the source can still be processing. Currently, Snusbase can publish its first page before the remaining pages are ready. This event contains a notification, not leak records. To receive it, send X-Osintly-Progressive-Leaks: 1 on the stream request. Use the same header on leak overview and leak-page requests. Setting it on POST /search does not opt subsequent requests in automatically.
On receipt, refresh Leaks Overview, then fetch the available page with the same opt-in header. During processing, the source count and pagination describe the published subset. For example, total_pages: 1 and has_next_page: false mean that no additional page is available yet; they do not mean that the source is complete. Refresh the overview again on the source’s terminal leak.status event or leaks.finished. Keep already-loaded pages, update the available page count, and load subsequent pages as needed. Deduplicate retried pages and records by page number and result key. A page-ready event does not guarantee later source success: retain error handling if a subsequent upload or provider step fails.
Without the opt-in header, this event is omitted, processing sources are not fetchable, and existing clients continue to retrieve finalized sources as before. Opting in does not change authentication, ownership checks, or the final response format. Not every source or search emits an early page event.

leaks.finished

Sent when all leak providers have finished or been skipped. This completes the leak phase, not the entire search. Modules and account checks may still be running; keep the stream open until search.finished.

registered_accounts

Sent as each email account-presence check completes. The module object carries the service identity, the found verdict, and, when available, a deletion guide describing how to remove the account.
Rate-limited or errored checks are not emitted on the public stream.

breached_accounts

Sent when breached-account aggregation is ready.

Sharding model

For module execution, the orchestrator can split selected modules into shards and run them across multiple runners.
  • Max shard count is currently 3
  • Shards are assigned from runner capacity snapshots
  • If all runners are saturated, periodic search.progress events report waiting status
  • When capacity returns, execution resumes and progress messages include shard ratios (for example shard 2/3 progress 9/12)
Sharding details are implementation-level and may evolve, but these stream signals are stable integration points.

Resume and reconnection

Streams support resuming from an index:
  • Query params: start_index, cursor, or from
  • Header: Last-Event-ID
When available, each streamed event includes an SSE id: field. Store the last received id and reconnect from it after disconnects. Repeat the progressive opt-in header on every reconnect. Handle replayed notifications idempotently and ignore event types your client does not use. Group overview refreshes during bursts, but retain a trailing refresh if another notification arrives while a request is in progress. Fetch the final overview even if a short disconnect caused an early-page notification to be missed.

Notes

  • Keep the connection open until search.finished
  • The stream is additive: fetch GET /search/{id}/results for the normalized final payload
  • Leak results are retrieved separately through GET /search/{id}/results/leaks