Leads and lists

Leads and companies, CSV imports, enrichment, research, and saved lists and segments.

Leads

A lead is a person you may contact. Fields include first_name, last_name, title, email, phone (E.164), linkedin_url, timezone, language, company_id, owner_id, phone_type, status, source and custom_fields.

  • One live lead per email per workspace. Creating a second one answers 409 with the existing lead's id (existing_id). Deleted leads are soft-deleted and free their email.
  • Status is one of new, contacted, replied, qualified, meeting_booked or disqualified. Each status change adds a status_change event to the lead's timeline.
  • References are checked: a company or owner must belong to the same workspace.
  • Timeline: GET /api/v1/leads/{lead_id}/timeline lists everything that happened to a lead: emails, replies, calls, notes, status changes and imports.

Companies (/api/v1/companies) group leads; signals and research attach to them.

CSV imports

Imports run in three steps: upload → preview → commit.

  1. POST /api/v1/imports/leads uploads the file. It is parsed and stored until you commit.
  2. Check the preview and the column mapping.
  3. POST /api/v1/imports/{import_id}/commit imports the rows in batches.

Each row is deduplicated against live leads on its strongest identifier: email (case-insensitive), else LinkedIn URL, else phone.

  • With skip, existing leads are left alone.
  • With update_empty_fields, only their empty fields are filled.
  • A second row for the same person in the file is skipped as duplicate_in_file.
  • Rows that match a suppression are imported but listed as suppressed, so they stay uncontactable. Use skip_suppressed to leave them out.
  • A row that hits a conflict is reported per row (error or conflict). If the import fails, batches already committed stay.

Opt-in extras at commit time, when the server has them configured:

  • "enrich": true queues enrichment for the imported leads.
  • "research": true queues AI research for them.

Both are capped per import to protect free-tier credits.

Enrichment

POST /api/v1/leads/{lead_id}/enrich fills a lead's empty fields from the configured data providers, trying them in order and stopping at the first hit for each group of fields. It never overwrites a field you set. Results are cached per workspace, every call is counted in the credits ledger, and GET /api/v1/enrichment/usage shows the usage. When the server runs enrichment in the background, the route answers 202 and the result lands on the lead and its timeline.

Research

AI research reads a lead's company website and other public sources and stores a brief with cited facts. Run it for one lead, or queue a research batch for many leads, many companies, or the companies accepted from a discovery run (POST /api/v1/research/batches).

Batches have budgets:

  • a maximum number of items per batch, per workspace per day, and of batches running at once;
  • per-run caps on AI and search calls.

When a daily budget or an AI quota runs out, the batch pauses until its resume_at time; it never retries in a loop. Every claim in a result must cite a fetched source; uncited claims are dropped.

Lists and segments

Saved lead lists (/api/v1/lists) come in two kinds:

KindMembers
staticHand-picked leads: add and remove them with POST /lists/{list_id}/members and .../members/remove.
segmentSaved lead filters. Members are computed from the filters each time you read them.

Deleting a list keeps its leads. A list can be the source of a campaign: POST /api/v1/lists/{list_id}/enroll enrolls its members into a sequence (needs sequences:write with an API key). Lists use the leads:* scopes.