Enrich Leads
Enrichment
Enrich Leads
Dispatch an Enrichment over a Lead scope. Runs asynchronously.
POST
Enrich Leads
CLI:
See also: Enrichment status · Get enriched leads · Cancel enrichment.
Overview
Starts an Enrichment for a Lead scope and dispatches a background worker. The endpoint is asynchronous: it validates the request, gates credits, persists the execution ledger, enqueues the Trigger.dev task, and returns theenrichmentRunId immediately. Poll Enrichment status until it is terminal, then read per-Lead results with Get enriched leads.
The handler previews credits before dispatch. If the workspace cannot afford the request, it returns 402 with { required, balance } and no work is created. Successful dispatch charges result.leadCount credits against the Enrichment’s creditAction.
Lead scope
Pick one of three scope shapes in thescope field:
{ type: "explicit_leads", leadIds: [...], listId?: "..." }— enrich a specific set of Leads.listIdis optional and only used for membership-scoped output.{ type: "list", listId: "..." }— enrich every Lead currently in the List.{ type: "filtered_list", listId: "...", filter: {...} }— enrich Leads in the List that match aLeadFilter. Filtered scopes are not yet supported by the planner; use one of the other two shapes.
Modes
mode: "persisted"(default) — runs the worker and writes results to Lead or membership attributes. Charges credits.mode: "preview"— plans the Enrichment without dispatching a worker or writing anything. Free.
Pass
idempotencyKey to safely retry. A repeat call with the same key returns
the existing execution (reusedExistingRun: true) instead of creating a duplicate
or double-charging.AI agent notes
The enrichment journey:
- Call Get enrichments to find the right
enrichmentIdand read its input schema. POST /api/enrichmentwith{ enrichmentId, scope, input, output? }. IncludeidempotencyKeyfor any retryable flow.GET /api/enrichment/{id}— poll every 2 to 5 s untilstatusiscompleted,failed, orcancelled.GET /api/enrichment/{id}/items— read per-Lead results, filter by?status=failedto triage problems.
- Read the Enrichment’s
subject(personorcompany) from Get enrichments, then choose Leads of that type. Do not add asubjectfield insidescope; the scope only acceptstype,leadIds,listId, and optionalfilter. - Use
mode: "preview"for a dry run that returns the resolved Lead count without dispatching or charging. enrichmentRunIdandrunIdin the response are the same value —runIdis kept as a compatibility alias.
400: the code field carries the planner rejection (e.g. EMPTY_LEAD_SCOPE, SUBJECT_MISMATCH, OUTPUT_TARGET_UNSUPPORTED). Surface code in error handling so callers can recover programmatically.On 402: insufficient credits. The response carries required and balance so you can ask the human to top up. No work is created.On 502: code: "DISPATCH_FAILED" means the execution row was created but Trigger.dev rejected the dispatch — the status appears as failed immediately. Correlate triggerRunId with Puffle Seer and the Trigger dashboard.Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
application/json
Minimum string length:
1Available options:
persisted, preview - Option 1
- Option 2
- Option 3
Available options:
overwrite, skip_existing