Skip to main content
Company enrichment fills in a tenant’s profile — firmographics, logo, website-derived attributes, certifications — from external sources. The streaming contract lets a client resolve those fields live rather than waiting for a single batch to finish: a fast first layer returns within about a second, and a deeper layer streams in behind it. The flow has two calls: a short POST to trigger (or reuse) a job, followed by a long-lived GET that streams suggestions over Server-Sent Events. Both require the OWNER or ADMIN role.

Start a stream

Triggers a fresh enrichment job if the last one is stale (older than seven days), or returns the in-flight job if one is already running. The response is minimal — you only need the jobId to correlate, and alreadyRunning to know whether you joined an existing job.
Response:
This endpoint has no side effects beyond triggering the job. Open the stream next to receive results.

Open the stream

The response is a text/event-stream. Suggestions arrive in two layers:
  1. Attio layer (~1s) — firmographics and logo from the CRM. If Attio is unavailable, this layer is skipped with an enrichment_status event carrying attioSkipped: true; it is never a fatal error.
  2. Pipeline layer (~45s) — website and document extraction suggestions.

Event types

All event names are prefixed enrichment_ so they never collide with other streams (such as the in-product assistant) on the same client. Example stream:

Resuming

The stream is resumable. On reconnect, send the cursor from the last enrichment_suggestion you received in the Last-Event-ID header. The database is the source of truth, so a client that reconnects resumes without re-emitting already-seen suggestions and without losing any.

Rate limits

The stream allows 10 connection opens per company per minute and a maximum of 3 concurrent streams per company. Exceeding either returns 429.

Confirm a suggestion

Each suggestion is acted on individually — accept it, edit the value, or dismiss it. The write-through is idempotent: repeating the same action returns alreadyConfirmed: true without writing twice. A conflicting transition on a field that was already ACCEPTED or EDITED returns 409, so a prior write-through is never silently undone.
For an edit, include the corrected value:
Response:
action is one of ACCEPT, EDIT, DISMISS. writtenTo indicates where an accepted value landed (COMPANY_COLUMN, COMPANY_ATTRIBUTE, CERTIFICATION, or null for a dismissal). coverageScore is the tenant’s updated profile completeness.

Next steps

Adoption state

Read the tenant’s adoption journey and next-best-action

API Reference

Browse the complete API documentation