---
title: "Add people to a campaign from the contact database (spends credits and metered verification)"
method: POST
path: "/lead-finder/imports"
tags: ["Lead Finder"]
---

# Add people to a campaign from the contact database (spends credits and metered verification)

`POST /lead-finder/imports`

## Request

- Base URL: `https://api.emailchaser.com/r`
- URL: `https://api.emailchaser.com/r/lead-finder/imports`
- Auth: HTTP bearer

SPENDS CREDITS, AND BY DEFAULT METERED VERIFICATION. Reveals people from the contact database and adds them to a campaign as leads, in the background. mode=selected adds the people named by refs from search results (1 to 1,000; a ref that is no longer stored is counted in expired and dropped). mode=first_n adds up to count people matching filters who are not in the workspace yet (1 to 5,000). It continues after the last first_n import of the same filters (startsAt in the response says where; fromStart true starts from the top instead) and skips people already in the workspace for free, so repeating a first_n call adds and charges for the next count people: never repeat a call to retry, read GET /lead-finder/imports first. While a first_n import of the same filters is still running another is refused (409 import_running). It stops early when the audience runs out (endReason audience_exhausted, and the next first_n import of those filters starts from the top again) or once it has looked at five people for every one requested, at least 1,000 (endReason fetch_limit, and the next one continues from there). People already in the workspace that it passes count toward that limit although they cost nothing. Every person it looks at, added or skipped, also counts against the account's daily first_n allowance (25,000 people a UTC day by default). Each person added costs creditsPerProspect credits (1 at the time of writing). People already in the workspace, blocklisted, without a usable address, on a personal mailbox when the campaign only takes business addresses, or marked invalid by verification are skipped and cost no credits. verifyEmails (default true) checks every screened address with the paid verification waterfall of POST /email-verification/jobs, including the ones it marks invalid: one check when the first provider rejects the address and two otherwise, billed as metered usage on the next invoice at the GET /email-verification/rates price, within the account's monthly verification allowance. Catch-all and unconfirmed addresses are added and charged, and so is every address once that allowance is used up. Set verifyEmails to false to skip verification. The wallet must hold estimatedCredits for the import to start. Credits are held batch by batch and settled against the leads actually created. Leads added to a running or paused campaign get their emails at once (a paused campaign sends them when resumed); adding to a completed campaign resumes it, so it starts sending again; in a draft campaign the emails are created at launch. At most 3 imports run at once in a workspace. Poll GET /lead-finder/imports/{id} until finishedAt is set. Needs a read_write key.

## Request body

- ModelsLeadFinderImportRequest
  - `campaignId` integer: CampaignID is the campaign the people are added to.
  - `count` integer: Count is how many people to add, for mode first_n: 1 to 5,000.
  - `filters` ModelsLeadFinderFilterSet
    - `cities` string[]
    - `companyKeywords` string: CompanyKeywords is one phrase matched against what the employer does.
    - `companyName` string: CompanyName is one phrase matched against the employer's name.
    - `companySizes` string[]: CompanySizes are headcount bands from GET /lead-finder/filters.
    - `continents` string[]
    - `countries` string[]: Countries, Regions and Continents are values from GET /lead-finder/filters, where the person is. Use one of the three at a time.
    - `domains` string[]: Domains and ExcludeDomains are company domains, up to 1,000 each.
    - `excludeCountries` string[]
    - `excludeDomains` string[]
    - `excludeHeadquartersCountries` string[]
    - `excludeIndustries` string[]
    - `excludeJobTitles` string[]
    - `headquartersCountries` string[]: HeadquartersCountries are where the employer is headquartered.
    - `industries` string[]: Industries are values from GET /lead-finder/filters.
    - `jobFunctions` string[]: JobFunctions are values from GET /lead-finder/filters.
    - `jobTitles` string[]: JobTitles are free text, matched as OR terms.
    - `regions` string[]
    - `revenue` string[]: Revenue is revenue bands from GET /lead-finder/filters.
    - `seniorities` string[]: Seniorities are values from GET /lead-finder/filters.
    - `states` string[]: States and Cities are free text, matched inside the person's location.
    - `technologies` string[]: Technologies are free text: tools the employer uses.
  - `fromStart` boolean: FromStart makes a first_n import start from the top of the results instead of after the last first_n import of the same filters.
  - `mode` 'selected' | 'first_n': Mode is "selected" (add the people named in Refs) or "first_n" (add up to Count people matching Filters who are not in the workspace yet, continuing after the last first_n import of the same filters).
  - `refs` string[]: Refs are result refs from searches, for mode selected: 1 to 1,000.
  - `verifyEmails` boolean: VerifyEmails checks each address with the paid verification waterfall before it is added: one or two metered checks per address, billed on the next invoice (GET /email-verification/rates), including addresses that turn out invalid. Invalid addresses are skipped and cost no credits; catch-all and unconfirmed ones are added and charged, and so is every address once the monthly verification allowance is used up. Defaults to true.

## Response `202`

Import started

- ModelsLeadFinderImportCreated
  - `audienceKey` string: AudienceKey names the import's filters, as on a search.
  - `available` integer: Available is the wallet's spendable balance when the import started. While the workspace's credits are free (unlimited on GET /credits/balance) it is the workspace's own balance, which the import does not use.
  - `creditsPerProspect` integer
  - `estimatedCredits` integer: EstimatedCredits is Requested x CreditsPerProspect, the most this import can cost in credits. Skipped people cost no credits; metered verification is billed separately.
  - `expired` integer: Expired counts refs that were no longer stored and were dropped.
  - `importId` integer
  - `requested` integer: Requested is how many people the import will try to add.
  - `startsAt` integer: StartsAt is the position in the results a first_n import starts from: 1 is the first person. Left out for a selected import.
  - `status` string

## Other responses

- `400`: invalid_request (mode, refs or count) or invalid_filters
- `401`: Unauthorized - invalid or missing API key
- `402`: insufficient_credits: needed and available are in credits; buy more with POST /credits/purchase
- `403`: plan_required, or a read-only key: the auth layer refuses it as text/plain, error 'This API key is read-only; this endpoint requires the read_write scope'
- `404`: campaign_not_found
- `409`: provider_unavailable: the contact database is switched off; or import_running: a first_n import of the same filters is still running (importId), start this one when it has finished
- `410`: results_expired: none of the refs is still stored; search again
- `422`: contact_cap_reached: the import would pass the plan's contact limit
- `429`: rate_limited (reason running_imports) or budget_exhausted (reason daily_import_limit, daily_budget, monthly_budget or fair_use_floor): retry after retryAfterSeconds
- `500`: internal

---

[API](https://skmtc.dev/emailchaser/apis/emailchaser-api.md) · [All operations](https://skmtc.dev/emailchaser/apis/emailchaser-api/llms.txt) · [OpenAPI document](https://skmtc.dev/emailchaser/apis/emailchaser-api/revisions/8b114990abb7?raw)
