# GetLeads API reference The whole GetLeads REST API in one file: authentication, every endpoint, every search filter and response field, billing, limits and errors. The latest copy is always at https://www.getleads.io/docs.txt. - Base URL: https://app.getleads.io - API key: create one at https://app.getleads.io/api-keys and send it on every request (see Authentication). - MCP setup: in your AI tool’s connector or MCP settings, add a remote server named GetLeads with URL https://app.getleads.io/api/mcp. Choose OAuth or sign-in authentication, connect, sign in to GetLeads and approve access. No API key is needed for this sign-in flow. - Plans, prices and what you may do with the data: https://www.getleads.io/ask.txt --- REST and MCP access to the GetLeads contact and company databases, enrichment, signals and live-lead products. ## Getting started Base URL: `https://app.getleads.io`. Send your API key as `Authorization: Bearer glb_live__` or `X-API-Key`. `GET /api/health` is public; the other REST endpoints require a key. Generate a key at [app.getleads.io/api-keys](https://app.getleads.io/api-keys). ### Rate limits The default is **100 requests per minute per account**, shared across its API keys. A `429` response includes `Retry-After`; wait before retrying. Higher limits are available by arrangement. A batch of 100 people is one request, so request rate and records processed are different measurements. ### Field naming Use the public field names returned by `GET /api/v1/contacts/columns` or the `get_available_columns` MCP tool. Pass those names in `columns`, and read results using the response-key mapping below. REST search responses use storage names for some fields; CSV/MCP labels use the public names. Omit `columns` for the default selection; filtered fields can also be included. Availability varies by record. Several names refer to the same field: `education` / `education_json`, `certifications` / `certifications_json`, `company_linkedin_url` / `current_employer_linkedin_url`, and `direct_dial` / `direct_phone`. Use one name from each pair. `main_industry` is the normalized industry label; `company_industry` is the source label. `contact_id` is no longer available. Use the person's LinkedIn URL and the identifying data in the record when joining results to your own inputs. Do not infer an input/output match from row position alone. ### Common mistakes - Use enrichment for people you already have: batches of LinkedIn URLs, work emails, or names with a company. Use search to discover people. - Company search accepts company filters. Use contact search for titles, seniority and other person filters. - A stored work email is not necessarily verified: `UNKNOWN` and `CATCH_ALL` are distinct from `VALID`. Verify before sending. - Use exact employee-profile bounds for a hard numeric cutoff. Size-band bounds select overlapping bands. - Reverse lookup from a phone number is **pending**. Mobile, direct-dial and company-phone fields are available on records where populated. ### HTTP errors | Status | Meaning | | --- | --- | | `400` | Invalid request, unsupported field/filter, malformed CSV or invalid batch. | | `401` | Missing, invalid or revoked API key. | | `402` | Plan-credit or fair-use budget reached; wallet-funded actions can instead report insufficient wallet cash. | | `410` | The phone reverse-lookup routes are pending and currently unavailable. | | `429` | Request rate exceeded. Respect `Retry-After`. | | `502` / `503` / `504` | Processing failure, temporary unavailability or timeout. | Read the returned `message`, `error` and `code` fields when present. A timeout does not prove that a billed job was never accepted; check its status before submitting it again. ## Billing & limits **Plan credits:** contact/company search and export, lookups, enrichment and signals. One credit buys one returned record, not one email or one populated field. A matched profile can have no work email. A genuine no-match enrichment should not consume a record credit; inspect the returned success counters and output. Counts, field catalogues and enum values are free. Unlimited accounts use fair-use budgets rather than a finite plan-credit balance. **Prepaid wallet:** company followers, profile monitoring, one-time post scrapes and website visitor identification. Wallet cash is separate from plan credits. Defaults for unlimited accounts are 500,000 rows per UTC day and 6,000,000 per UTC calendar month across search, export and enrichment; account-specific limits can differ. `GET /api/v1/usage/fair-use` or MCP `get_fair_use` is authoritative for your account. Exports contain at most 50,000 rows each. REST contact search serves up to 5,000 rows per page; MCP contact search serves up to 100. JSON enrichment batches accept up to 100 people. Large CSVs should use the asynchronous flow. ## Health `GET /api/health` reports service liveness. `GET /api/v1/contacts/health` reports database availability and `record_count`; the count describes records rather than independently deduplicated people. Production counts checked **29 October 2026**: 542,413,703 contact records, 125,227,278 with a work email, 136,275,365 with a personal email and 88,830,227 with a mobile number. These are populated-field counts, not accuracy or deliverability measurements. ## Database search ### POST /api/v1/contacts/search Use structured filters inside `filters`, with `limit`, `offset`, `columns`, `max_per_company` and optional `where_sql` alongside it. Flat filters are also accepted. Different filters AND together; values inside one list filter OR together. Use a predicate for OR across different fields. ```bash curl -sS 'https://app.getleads.io/api/v1/contacts/search' \ -H "Authorization: Bearer $GETLEADS_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"filters":{"domains":["hubspot.com"],"require_email":true},"columns":["full_name","current_title","work_email","email_status"],"limit":10}' ``` Read `contacts`, `returned`, `has_more` and `next_offset`. Advance with the returned offset, stopping when `has_more` is false. Use the count endpoint for audience size rather than treating a page's `total_available` as the full population. If `total_available_is_minimum` or `total_matching_is_minimum` is true, the associated number is a lower bound. ### POST /api/v1/contacts/search/count The same filters, without retrieving contacts. Free. Read `total_matching` and any minimum/estimate flag. ```bash curl -sS 'https://app.getleads.io/api/v1/contacts/search/count' \ -H "Authorization: Bearer $GETLEADS_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"filters":{"domains":["hubspot.com"],"require_email":true}}' ``` ### POST /api/v1/contacts/search/export Start an asynchronous CSV export with the same filters and `columns`. Optional `max_rows` is at most 50,000; `max_per_company` limits contacts per company. The response contains `export_id`. ### GET /api/v1/contacts/search/export/{export_id} Poll until `job_status` is `completed` or `failed`. On completion download `export_url`; the link is temporary. Read the actual CSV headers, and preserve original identifiers when joining it to a customer file. Split searches larger than 50,000 into disjoint segments before starting exports. ## Company search Find companies first, then find people at those companies. These endpoints return **one row per LinkedIn company page**, rather than one row per contact. Search and export cost **1 plan credit per company returned**; counts and the column catalogue are free. Company lookup costs 1 credit on a match and 0 on a miss. Use the same base URL and authentication as contact search: `https://app.getleads.io` and `Authorization: Bearer $GETLEADS_API_KEY`. ### Company filters and fields Pass at least one supported filter or `where_sql`. REST accepts filters at the top level or inside `filters`; `limit`, `offset`, `columns`, `max_rows` and `where_sql` belong at the top level. Different filters combine with AND; values within an array combine with OR. | Target | Company filters | | --- | --- | | Named companies | `domains`, `company_name`, `company_linkedin_urls`, `domain_list_id` | | Business and industry | `industries`, `company_description` | | Headquarters | `headquarters_countries`, `headquarters_cities` | | Employee size bands | `company_size`, `company_size_min`, `company_size_max`, `employees_min`, `employees_max` | | Exact LinkedIn employee headcount | `employee_profiles_on_linkedin_min`, `employee_profiles_on_linkedin_max` | | Revenue and public/private status | `revenue`, `ipo_status` | | Funding | `funding_types`, `total_funding_min`, `total_funding_max` | | Founding year | `founded_year_min`, `founded_year_max` | | Exclusions | `exclude_domains`, `exclude_industries`, `exclude_headquarters_countries` | Use `GET /api/v1/contacts/filter-values?field=industries` (or `company_size`, `revenue`, `headquarters_countries`, `funding_types`) for enum values. Size bounds select overlapping LinkedIn size bands; use the exact-headcount filters for a hard numeric cutoff. The company catalogue below lists available fields and their filter parameters. **Person filters return `400`**, including `job_titles`, `seniority`, `job_functions`, `countries`, and email-presence filters. For company location, use `headquarters_countries`, not `countries`. To qualify people, use [contact search](#post-apiv1contactssearch). Company search already returns one row per company, so do not pass `max_per_company`. ### GET /api/v1/companies/columns Free company-only field catalogue. Each entry includes `canonical_name`, `clickhouse_column`, `label`, `description`, `type`, `searchable`, `exportable` and `filter_params`. Use exportable fields in `columns` and searchable fields in `where_sql`. This is the catalogue for company requests; `get_available_columns` over MCP returns the broader contact-and-company catalogue. ```bash curl -sS "https://app.getleads.io/api/v1/companies/columns" \ -H "Authorization: Bearer $GETLEADS_API_KEY" ``` ### POST /api/v1/companies/search/count Free distinct-company count with the same company filters as search. Returns `total_matching` and `credits_used: 0`, without company records. Count before searching or exporting. ```bash curl -sS -X POST "https://app.getleads.io/api/v1/companies/search/count" \ -H "Authorization: Bearer $GETLEADS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"company_linkedin_urls":["https://www.linkedin.com/company/hubspot"]}' ``` ```json { "ok": true, "total_matching": 1, "credits_used": 0, "creditsRemaining": null, "message": "Found 1 matching companies." } ``` ### POST /api/v1/companies/search Returns a `companies` array. REST defaults to **1,000 rows**, with a **5,000-row maximum**; larger `limit` values are clamped to 5,000. MCP `search_companies` defaults to 100 and rejects a limit above 100. ```bash curl -sS -X POST "https://app.getleads.io/api/v1/companies/search" \ -H "Authorization: Bearer $GETLEADS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"filters":{"company_linkedin_urls":["https://www.linkedin.com/company/hubspot"]},"columns":["company_name","company_domain","company_linkedin_url"],"limit":1}' ``` The response includes `total_available`, `query_credits_used`, `creditsRemaining`, `offset`, `limit`, `returned` and `has_more`. When `has_more` is `true`, pass the returned `next_offset` as the next request's `offset`, keeping the filters unchanged. Stop when `has_more` is `false`. Use count for the match total and export for a CSV. **REST rows use underlying field names; MCP rows and CSV headers use canonical names.** The requested `columns` can use canonical names or display labels. The company identifier and `contact_count` may also appear in JSON even when not requested. | REST JSON key | MCP key / CSV header | | --- | --- | | `co_name` | `company_name` | | `org_domain` | `company_domain` | | `current_company_linkedin_url` | `company_linkedin_url` | | `co_website` | `company_website` | | `co_description` | `company_description` | | `current_company_industry` | `company_industry` | | `org_revenue_range` | `revenue_range` | | `employee_count_range` | `employee_count_range` | | `company_hq_country` | `company_hq_country` | | `company_hq_city` | `company_hq_city` | For example, the REST request above returns `co_name: "HubSpot"`, `org_domain: "hubspot.com"` and `current_company_linkedin_url: "https://www.linkedin.com/company/hubspot"`; the equivalent MCP request returns `company_name`, `company_domain` and `company_linkedin_url`. ### POST /api/v1/companies/search/export Starts an asynchronous company CSV export. Pass the same company filters, optional `columns`, and optional `max_rows` (1–50,000). Costs 1 credit per company exported, subject to your plan's fair-usage limits. The initial response is `202` with `export_id` and `job_status: "queued"`. ```bash curl -sS -X POST "https://app.getleads.io/api/v1/companies/search/export" \ -H "Authorization: Bearer $GETLEADS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"company_linkedin_urls":["https://www.linkedin.com/company/hubspot"],"columns":["company_name","company_domain","company_linkedin_url"],"max_rows":1}' ``` ### GET /api/v1/companies/search/export/{export_id} Poll the ID returned by the export request every few seconds while `job_status` is `queued` or `running`. When it is `completed`, download `export_url`. Read `expires_in_seconds` for the download lifetime; the current production response reports `604800` (7 days). ```bash curl -sS "https://app.getleads.io/api/v1/companies/search/export/$EXPORT_ID" \ -H "Authorization: Bearer $GETLEADS_API_KEY" ``` The completed response includes `rows_exported`, `rows_available`, `query_credits_used`, `creditsRemaining` and cap information such as `rows_capped_by_credits` and `cap_reason`. CSV headers use canonical names; parse with a CSV reader and access fields by header. The example export produces: ```csv company_name,company_domain,company_linkedin_url HubSpot,hubspot.com,https://www.linkedin.com/company/hubspot ``` ### GET /api/v1/companies/lookup Look up one company's firmographic profile. Supply **exactly one** query parameter: `domain` or `company_name`. Supplying both returns `400`. A match returns `found: true` and a `company` object; a miss returns `200` with `found: false`, `company: null` and `query_credits_used: 0`. ```bash curl -sS --get "https://app.getleads.io/api/v1/companies/lookup" \ -H "Authorization: Bearer $GETLEADS_API_KEY" \ --data-urlencode "domain=hubspot.com" ``` To look up by name, replace `domain=hubspot.com` with `company_name=HubSpot`. REST lookup uses the same underlying field names as company search; MCP `lookup_company` uses canonical names. ### From companies to people Take `org_domain` from REST company rows, or `company_domain` from MCP/CSV rows, and pass those values to contact search as `domains`. Add the person's role filters there: ```json { "domains": ["hubspot.com"], "seniority": ["c-level", "vp"], "limit": 10 } ``` Send this body to `POST /api/v1/contacts/search`, or pass the same flat arguments to MCP `search_contacts`. Use `count_contacts` first to size the people search. ### Company MCP tools Pass **flat arguments**, without a nested `filters` object. The same company-filter restrictions apply as over REST. #### `count_companies` Free `total_matching` count. ```json {"domains": ["hubspot.com"]} ``` #### `search_companies` Returns a `companies` array with canonical field names; default/max 100 rows per call. Page with `offset` / `next_offset`. ```json { "domains": ["hubspot.com"], "columns": ["company_name", "company_domain", "company_linkedin_url"], "limit": 1 } ``` #### `lookup_company` One company profile; supply exactly one of `domain` or `company_name`. Costs 1 credit on a match, 0 on a miss. ```json {"domain": "hubspot.com"} ``` #### `export_companies` Starts a CSV export and returns `export_id`; costs 1 credit per company exported. ```json { "domains": ["hubspot.com"], "max_rows": 1, "confirmed": true } ``` #### `check_company_export` Polls `job_status`; `completed` includes `export_url`. ```json {"export_id": ""} ``` `export_companies` **requires `confirmed: true`**. The REST export example above omits this MCP-only argument. Use `count_companies` with the same filters first, then export and poll until complete. --- ## Filters and values `GET /api/v1/contacts/columns` returns each field's public name, description, type, `searchable`, `exportable`, `filter_params` and enum-lookup information. This catalogue is the current contract. Output fields and searchable fields are different sets; do not assume every returned JSON field is a filter. `GET /api/v1/contacts/filter-values?field=industries` returns valid enum values. Use the requested field's documented values rather than inventing labels. MCP equivalents: `get_available_columns` and `get_available_values`. | Filter family | Parameters | | --- | --- | | Company identity | `domains`, `company_name`, `company_linkedin_urls`, `domain_list_id` | | Person role | `job_titles`, `seniority`, `job_functions`, `job_start_date_min`, `job_start_date_max` | | Person location | `countries`, `states`, `cities` | | Company headquarters | `headquarters_countries`, `headquarters_cities` | | Company size | `company_size`, `employees_min`, `employees_max`, `company_size_min`, `company_size_max` | | Exact LinkedIn employee count | `employee_profiles_on_linkedin_min`, `employee_profiles_on_linkedin_max` | | Company information | `industries`, `revenue`, `technologies`, `company_description`, `funding_types`, `founded_year_min`, `founded_year_max`, `total_funding_min`, `total_funding_max` | | Person identity and background | `first_name`, `last_name`, `email_address`, `linkedin_url`, `person_description`, `linkedin_headline`, `skills`, `education`, `certifications`, `languages` | | Contact channels | `require_email`, `require_phone`, `require_direct_dial`, `require_company_phone`, `require_personal_email`, `email_status` | | Additional person/company attributes | Follow the catalogue's `filter_params` for gender, birth year, estimated pay, IPO status, company followers and employee growth. | | Exclusions | `exclude_domains`, `exclude_countries`, `exclude_headquarters_countries`, `exclude_industries`, `exclude_job_titles` | ### Matching and ranges - `company_size` selects size bands. `employees_min/max` select bands overlapping a bound; use `employee_profiles_on_linkedin_min/max` for exact numeric cutoffs. - Person location and company headquarters answer different questions. Combining them requires both to match. - Titles and keywords can have different matching rules. Read the field description, count the proposed filter and inspect a preview before exporting. - `job_start_date_min/max` take literal `YYYY-MM-DD` dates. - `require_email` requires a work email, not a personal address. `require_phone` requires a mobile; direct dials and company switchboards have separate filters. - `email_status` accepts `VALID`, `CATCH_ALL` and `UNKNOWN`. `VALID` is the verified label; `CATCH_ALL` cannot confirm the individual mailbox, and `UNKNOWN` is not verified. Reverify before sending. - `where_sql` is AND-combined with the other filters and is limited to 4,000 characters. Reference only fields marked searchable, using their catalogue names and stored values. It is for predicates, not complete SQL statements. ### Response fields The field names below are the public names to request. JSON-valued fields can contain structured lists or objects. A field can be empty when no value is known; the field count is not a promise of that many populated values on every profile. Education/certification, direct-dial and company-URL aliases are listed once here. #### Contact | Field | Type | Searchable | Description | | --- | --- | --- | --- | | `full_name` | text | No | the contact's full name. Not searchable — filter on first_name / last_name instead. | | `first_name` | text | Yes | the contact's first name. Substring match — Isabel also catches Isabelle and Isabella, so it narrows a set rather than identifying a person. A single character is the exception: it is matched exactly, so J means the first name J and not every name containing a j. | | `last_name` | text | Yes | the contact's last name. Substring match — Wood also catches Woods and Woodward, so it narrows a set rather than identifying a person. A single character is the exception: it is matched exactly, so S means the surname S, as privacy-masked records like "Camille S." store it, and not every surname containing an s. | | `work_email` | text | Yes | the contact's work email address. Matches exactly. | | `email_status` | text | Yes | whether the contact has a verified, deliverable work email. Use VALID for deliverable email (verified aliases to VALID). CATCH_ALL and UNKNOWN (email present but not verified) are also accepted. INVALID is rejected. | | `personal_emails` | text | Yes | personal (non-work) email addresses listed on the contact's profile. Filter with require_personal_email to keep only contacts that have one; several addresses are comma-separated in CSV exports. | | `created_at` | date | No | when the contact record was first created. | | `contact_updated_at` | date | No | when the contact record was last updated. | | `last_refresh_at` | date | No | when the contact's LinkedIn data was last refreshed. | | `mobile_phone` | text | Yes | the contact's mobile phone number in E.164 format (e.g. +14155550123). Filter with require_phone. | | `direct_dial` | text | Yes | the contact's personal direct phone number. | | `gender` | text | Yes | the contact's gender (male / female). Empty for most contacts. Filter with genders. | | `birth_year` | number | Yes | the contact's birth year. Empty for most contacts. Filter with birth_year_min / birth_year_max. | | `email_verified_at` | date | No | when the contact's work email was last verified (date). Returned alongside the email so you know how fresh the verification is. | #### Contact Profile | Field | Type | Searchable | Description | | --- | --- | --- | --- | | `linkedin_headline` | text | Yes | the headline under their name on LinkedIn, searchable by keyword. The best-populated free text on the person side | | `about_person` | text | Yes | the contact's bio / About section on LinkedIn, searchable by keyword. | | `linkedin_url` | text | Yes | the contact's LinkedIn profile URL. | | `open_to_work` | bool | Yes | whether the contact has the Open to Work badge on LinkedIn (boolean). | | `is_hiring` | bool | Yes | whether the contact has the Hiring badge on LinkedIn (boolean). | | `experience_json` | text | No | raw JSON array of the contact's full job history. Unparsed — use current_title for the active role. | | `skills` | text | Yes | skills listed on LinkedIn. Short substrings over-match — "nist" also hits "administration"; confirm with a count or exclude noise tokens. | | `education` | text | Yes | the contact's education history (schools, degrees, fields of study). Keyword-searchable with the education filter (substring). Exported as raw JSON. Same field as education_json. | | `certifications` | text | Yes | the contact's certifications. Keyword-searchable with the certifications filter (case-insensitive substring). Exported as raw JSON. Same field as certifications_json. | | `languages` | text | Yes | languages spoken, as listed on LinkedIn. | | `social_media_json` | text | No | raw JSON of the contact's social profiles, including LinkedIn followers and connections. Kept as JSON because it varies too much to split into columns. To filter on it, export and check per record. | | `smart_tags` | text | No | auto-generated classification tags for the contact. | | `profile_image_url` | text | No | URL of the contact's LinkedIn profile photo. | | `linkedin_connections_count` | number | No | how many LinkedIn connections the person has. Caps at 500, because LinkedIn only publishes "500+". > 500 returns nothing at all — use >= 500 and say that is what it means | | `linkedin_connections_band` | text | No | LinkedIn connection size as a band (e.g. "500+"), derived from linkedin_connections_count. Useful when you want the published bucket rather than the capped number. | #### Contact Location | Field | Type | Searchable | Description | | --- | --- | --- | --- | | `contact_location` | text | No | the contact's location as one combined string (city, state, country), for output only. Not searchable — filter on contact_country / contact_state / contact_city. | | `contact_country` | text | Yes | where the person lives — the default, and what most briefs mean. Full English country names; call get_available_values field=countries for the list. Aliases like USA, UK and Czechia are accepted. Person location and company HQ are alternatives: combining them keeps only people who live in the country AND work for a company headquartered there, which silently drops a large share. | | `contact_state` | text | Yes | where the person lives (state or province). Full names, case-insensitive exact match, not substring — 'CA' matches almost nothing, use 'California'. No fixed value list. Don't combine with company HQ filters without checking the count. | | `contact_city` | text | Yes | where the person lives (city). Case-insensitive exact match on the full city name, not substring — 'SF' matches nothing, use 'San Francisco'. No fixed value list. Don't combine with company HQ filters without checking the count. | | `contact_region` | text | Yes | macro-region of the contact's country: NORAM, EMEA, APAC, LATAM. Filter with regions. | | `contact_continent` | text | Yes | continent of the contact's country. Filter with continents. | #### Contact Job | Field | Type | Searchable | Description | | --- | --- | --- | --- | | `current_title` | text | Yes | the contact's current job title on LinkedIn. Matches whole words — Engineer does not find Engineering. Acronyms match their full form. | | `seniority_level` | text | Yes | the contact's seniority, derived from job title. One of a fixed set — call get_available_values field=seniority (c-level, vp, director, manager, senior, junior, unknown). | | `department` | text | Yes | the department the contact works in. One of a fixed set — call get_available_values field=job_functions for the list (e.g. Sales & Business Development, Marketing & Product Management). | | `current_employer_id` | text | No | internal identifier for the contact's current employer. | | `current_employer` | text | No | the name of the company where the contact currently works. | | `current_employer_logo_url` | text | No | URL of the company's logo image. | | `current_employer_website` | text | No | the primary website of the contact's current employer. | | `current_employer_websites` | text | No | all known websites for the contact's current employer. | | `current_employer_size_json` | text | No | raw JSON with the employer's headcount breakdown. For filtering use linkedin_employee_count_exact or employee_count_range. | | `current_employer_industries` | text | No | the full list of industry labels on the contact's current employer. Normally identical to company_industries. Not searchable — filter with industries, and use main_industry for the canonical value. | | `current_employer_location` | text | No | the contact's current employer's location string. | | `is_current_role` | bool | Yes | whether the contact is still in the listed role. True for ~93% of contacts. False means the experience data shows they have left. Filter with is_current_role=true to exclude stale records. | | `current_role_updated_at` | date | No | when the contact's current job information was last updated. | | `latest_role_change_at` | date | No | date of the contact's most recent role change — normally the same as role_start_date. Not searchable; filter on role_start_date. | | `role_start_date` | date | Yes | the date the contact started their current role — a new leader often re-evaluates vendors. Filter with job_start_date_min / job_start_date_max as YYYY-MM-DD; relative values like 'last 90 days' return 400, so work out the calendar date first. Widen the window before concluding nobody moved. | | `latest_company_change_at` | date | No | date the contact most recently changed companies. 1970-01-01 means unknown. Not searchable. | | `estimated_pay_band` | text | Yes | the contact's estimated annual pay band (modelled, not reported). Filter with pay_bands. | #### Company Industry | Field | Type | Searchable | Description | | --- | --- | --- | --- | | `company_industry` | text | Yes | the primary industry label on the company's LinkedIn profile. Filter with industries using one of the 441 canonical values (call get_available_values field=industries; anything else returns 400 with the valid options). The label shown here can differ from the canonical value it matches — e.g. 'Software & SaaS' is found under 'Software Development'. Use main_industry for the canonical value. | | `main_industry` | text | Yes | the company's main industry as one of the 441 canonical values — the same value the industries filter matches on. Call get_available_values field=industries for the list. | | `company_industries` | text | No | the company's full list of industry labels. Not searchable — filter with industries, and use main_industry for the canonical value. | #### Company | Field | Type | Searchable | Description | | --- | --- | --- | --- | | `company_linkedin_url` | text | Yes | LinkedIn company page URL for the contact's current employer. Same field as current_employer_linkedin_url. Filter with company_linkedin_urls using the full page URL or linkedin.com/company/ — a bare slug returns 400. | | `company_id` | text | No | internal identifier for the company record. | | `company_name` | text | Yes | the name of the company where the contact currently works. | | `company_canonical_name` | text | No | the company's canonical / normalized name. | | `company_alternative_names` | text | No | alternative names or DBA names for the company. | | `company_description` | text | Yes | the company's About text / description on LinkedIn. | | `company_summary` | text | No | a short summary of what the company does. | | `company_contact_info_json` | text | No | raw JSON with the company's phone, email and website. Kept as JSON because it varies too much by company to split into columns. To filter on it, export and check per record. | | `company_founded_year` | text | Yes | the year the company was founded, exported as an ISO date string (e.g. 2020-01-01T00:00:00.000Z), empty when unknown. Filter with founded_year_min / founded_year_max using plain years. | | `company_websites` | text | No | all known websites for the company. | | `company_website` | text | No | the company's primary website. | | `company_business_data_json` | text | No | raw JSON of company classification — customer type (B2B / B2C / B2G), ownership status, flags for acquired, exited, government, non-profit, shut down, startup and stealth, stock exchange and patent count. Kept as JSON because what's present varies too much by company to split into columns. To filter on it, export the list and have an AI check this field per record. | | `company_social_media_json` | text | No | raw JSON of the company's social and data-provider profiles (LinkedIn, Twitter, Crunchbase, PitchBook, Dealroom, GitHub). The LinkedIn page is also in company_linkedin_url. Kept as JSON because it varies too much to split into columns — export and check per record. | | `company_linkedin_slugs` | text | No | LinkedIn URL slug(s) for the company page. | | `company_logo_url` | text | No | URL of the company's logo. | | `company_updated_at` | date | No | when the company record was last refreshed. | | `company_phone` | text | Yes | the company's main phone line (not the person's own). Filter with require_company_phone. | | `company_domain` | text | Yes | the company's primary domain. Filter with domains, which accepts a bare domain or a full URL — the protocol, www., any path and a trailing slash are all stripped before matching, so a pasted company URL and the bare domain return the same companies. An unparseable value returns 400 naming it. | | `revenue_range` | text | Yes | the company's revenue band. One of a fixed set — call get_available_values field=revenue (<$1M, $1M to <$10M, $10M to <$50M, $50M to <$100M, $100M to <$1B, $1B+). | | `company_ipo_status` | text | Yes | whether the company is public, private or delisted. Filter with ipo_status. | | `company_linkedin_followers` | number | Yes | the company's LinkedIn follower count. Filter with followers_min / followers_max. | #### Company Headcount | Field | Type | Searchable | Description | | --- | --- | --- | --- | | `company_workforce_json` | text | No | raw JSON with the company's headcount, headcount history over time and size class. Headcount history (growth) exists only here. For current headcount use linkedin_employee_count_exact or employee_count_range. | | `employee_count_range` | text | Yes | the company's LinkedIn headcount band. Filter with company_size for exact bands (call get_available_values field=company_size: 1 to 10, 11 to 50, 51 to 200, 201 to 500, 501 to 1000, 1001 to 5000, 5001 to 10000, 10001+) or employees_min / employees_max for a number — bands overlap, so a max of 9 returns the whole 1 to 10 band. For a hard cutoff use linkedin_employee_count_exact, which is filled more often; use this band only when the exact count is empty. | | `employee_count_min` | number | Yes | numeric lower bound of employee_count_range. 0 means the band is unknown. Filter with company_size_min; for a hard cutoff use linkedin_employee_count_exact. | | `employee_count_max` | number | Yes | numeric upper bound of employee_count_range. 0 means either an unknown band or the open-ended 10001+ band. Filter with company_size_max; for a hard cutoff use linkedin_employee_count_exact. | | `linkedin_employee_count_exact` | number | Yes | the company's exact employee count from LinkedIn employee profiles. Filter with employee_profiles_on_linkedin_min / employee_profiles_on_linkedin_max for a hard cutoff. Use this by default; fall back to employee_count_range when it's empty. | | `linkedin_employee_growth_rate` | number | Yes | the company's headcount growth over the last 12 months, in percent (5 = +5%, -10 = shrank 10%). Filter with employee_growth_rate_min / employee_growth_rate_max. | #### Company Location | Field | Type | Searchable | Description | | --- | --- | --- | --- | | `company_locations_json` | text | No | raw JSON of the company's office locations. Headquarters is also in company_hq_country / company_hq_city. For any other office, export and check per record — the number and shape of locations varies too much to split into columns. | #### Company Funding | Field | Type | Searchable | Description | | --- | --- | --- | --- | | `company_investor_json` | text | No | raw JSON with the company's investor information. Per-round investors are also in company_funding_json, and the latest round's lead investors are in lead_investors. | | `company_funding_json` | text | No | raw JSON of every funding round (type, amount in USD, date, investors). For the latest round use the structured fields: last_funding_type, last_funding_amount, last_funding_date, total_funding_amount, lead_investors, last_funding_investor_count. | | `last_funding_type` | text | Yes | type of the company's most recent funding round (e.g. Series A, Seed). | | `last_funding_amount` | number | No | dollar amount of the company's most recent funding round. | | `last_funding_date` | date | No | date of the company's most recent funding round. | | `total_funding_amount` | number | Yes | total capital the company has raised across all rounds. | | `lead_investors` | text | No | lead investors in the company's most recent funding round. | | `last_funding_investor_count` | number | No | number of investors in the company's most recent funding round. | #### Company HQ | Field | Type | Searchable | Description | | --- | --- | --- | --- | | `company_hq_country` | text | Yes | the country of the company's headquarters. Canonical country names — call get_available_values field=headquarters_countries for the list; aliases like USA are accepted. | | `company_hq_location` | text | No | the full HQ location string (city, state, country), for output only. Not searchable — filter on company_hq_country / company_hq_city. | | `company_hq_city` | text | Yes | the city of the company's headquarters. Substring match with no fixed value list, so short forms over-match — 'SF' also catches Düsseldorf. | #### Company Technographics | Field | Type | Searchable | Description | | --- | --- | --- | --- | | `company_tech_stack` | text | No | the technology tools the company uses (list). Not filterable on this column — use the top-level technologies parameter on search and count, which matches across all technographic fields. Substring match: 'Sales' catches 'Salesforce'. | #### REST response-key mapping Request public names in `columns`. Read the corresponding REST JSON keys below; do not assume that every public name is also a REST property. CSV/MCP output uses the public labels. | Requested field | REST JSON key | | --- | --- | | `full_name` | `full_name` | | `first_name` | `first_name` | | `last_name` | `last_name` | | `linkedin_headline` | `headline` | | `about_person` | `about` | | `contact_location` | `current_location` | | `contact_country` | `contact_country` | | `contact_state` | `contact_state` | | `contact_city` | `contact_city` | | `linkedin_url` | `linkedin_url` | | `work_email` | `work_email` | | `email_status` | `email_status` | | `personal_emails` | `personal_emails` | | `current_title` | `current_title` | | `seniority_level` | `current_seniority` | | `department` | `current_function` | | `current_employer_id` | `current_company_id` | | `current_employer` | `current_company_name` | | `current_employer_logo_url` | `current_company_logo_url` | | `current_employer_website` | `current_company_website` | | `current_employer_websites` | `current_company_websites` | | `current_employer_size_json` | `current_company_size_json` | | `current_employer_industries` | `current_company_industries` | | `company_industry` | `current_company_industry` | | `main_industry` | `current_company_industry` | | `current_employer_location` | `current_company_location` | | `company_linkedin_url` | `current_company_linkedin_url` | | `open_to_work` | `open_to_work` | | `is_hiring` | `hiring` | | `is_current_role` | `is_current_role` | | `experience_json` | `experience_json` | | `skills` | `skills` | | `education` | `education_json` | | `certifications` | `certifications_json` | | `languages` | `languages` | | `social_media_json` | `social_media_json` | | `smart_tags` | `smart_tags` | | `created_at` | `created_at` | | `contact_updated_at` | `updated_at` | | `last_refresh_at` | `last_refresh_at` | | `current_role_updated_at` | `current_job_updated_at` | | `latest_role_change_at` | `latest_role_change_at` | | `role_start_date` | `role_start_date` | | `latest_company_change_at` | `latest_company_change_at` | | `profile_image_url` | `image_url` | | `company_id` | `co_id` | | `company_name` | `co_name` | | `company_canonical_name` | `co_canonical_name` | | `company_alternative_names` | `co_alternative_names` | | `company_description` | `co_description` | | `company_summary` | `co_summary` | | `company_contact_info_json` | `co_contact_info_json` | | `company_founded_year` | `co_founded` | | `company_industries` | `co_industries` | | `company_websites` | `co_websites` | | `company_website` | `co_website` | | `company_workforce_json` | `co_workforce_json` | | `company_business_data_json` | `co_business_data_json` | | `company_social_media_json` | `co_social_media_json` | | `company_linkedin_slugs` | `co_linkedin_slugs` | | `company_locations_json` | `co_locations_json` | | `company_logo_url` | `co_logo_url` | | `company_investor_json` | `co_investor_json` | | `company_funding_json` | `co_funding_json` | | `company_updated_at` | `co_updated_at` | | `mobile_phone` | `mobile_phone` | | `direct_dial` | `direct_dial` | | `company_phone` | `company_phone` | | `company_domain` | `org_domain` | | `employee_count_range` | `employee_count_range` | | `employee_count_min` | `employee_count_min` | | `employee_count_max` | `employee_count_max` | | `revenue_range` | `org_revenue_range` | | `company_hq_country` | `company_hq_country` | | `company_hq_location` | `company_hq_location` | | `company_hq_city` | `company_hq_city` | | `company_tech_stack` | `company_technologies` | | `last_funding_type` | `last_funding_type` | | `last_funding_amount` | `last_funding_amount` | | `last_funding_date` | `last_funding_date` | | `total_funding_amount` | `total_funding_usd` | | `lead_investors` | `lead_investors` | | `last_funding_investor_count` | `last_funding_investor_count` | | `linkedin_employee_count_exact` | `linkedin_employee_count` | | `gender` | `gender` | | `birth_year` | `birth_year` | | `estimated_pay_band` | `compensation_band` | | `contact_region` | `contact_region` | | `contact_continent` | `contact_continent` | | `company_ipo_status` | `co_ipo_status` | | `company_linkedin_followers` | `co_follower_count` | | `linkedin_employee_growth_rate` | `co_employee_growth_pct` | | `email_verified_at` | `email_verified_at` | | `linkedin_connections_count` | `linkedin_connections` | | `linkedin_connections_band` | `linkedin_connections_band` | ## Person enrichment — 3 ways Match known people to the database. Each JSON endpoint takes `items`, up to 100 people per request. Matched profiles can include work email, phone fields, email verification metadata and current-role status where available. A match does not guarantee an email, a phone or current employment at the company in your original file. | You have | Endpoint | Item shape | | --- | --- | --- | | LinkedIn profile URL | `POST /api/v1/enrich/from-linkedin` | `{"linkedin_url":"https://www.linkedin.com/in/example/"}` | | Work email | `POST /api/v1/enrich/from-email` | `{"email":"person@example.com"}` | | Person name and company | `POST /api/v1/enrich/from-person` | `{"first_name":"Jane","last_name":"Example","company_name":"Example Ltd"}` or replace company name with `email_domain`. | ```bash curl -sS 'https://app.getleads.io/api/v1/enrich/from-linkedin' \ -H "Authorization: Bearer $GETLEADS_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"items":[{"linkedin_url":"https://www.linkedin.com/in/example/"}],"limit_per_item":1}' ``` Read each item's `success` and populated `data`; preserve its echoed input when joining results. `profileUrl`, `linkedinUrl` and `email` convenience keys can also be present. Check `current_role_status` before treating an old company association as current. The deprecated `/enrich/batch`, `/enrich/batch-profile` and `/enrich/batch-person` routes map to the corresponding LinkedIn, work-email and name/company workflows; use the named routes for new integrations. ### POST /api/v1/enrich/csv Synchronous enrichment. Send multipart `file`, `mode` and optional JSON-encoded `mapping`. Supported modes are `linkedin` (`profile`), `work_email` (`email`) and `person`; phone mode is **pending**. Explicit mapping supports a single-column input. Existing input columns are retained, with enrichment columns added. ```bash curl -sS 'https://app.getleads.io/api/v1/enrich/csv' \ -H "Authorization: Bearer $GETLEADS_API_KEY" \ -F 'file=@contacts.csv' \ -F 'mode=linkedin' \ -F 'mapping={"profileUrl":"LinkedIn URL"}' ``` The body is CSV rather than JSON. Read the `X-Enrich-*` headers and actual output rows when checking results. Input headers should have stable row identifiers. A synchronous request can time out on a large file, so use the background flow for large lists. ### POST /api/v1/enrich/csv/async The same multipart upload processed in the background. The initial JSON contains `runId`, `jobStatus`, `rows` and `worstCaseCredits`; the last number is an admission estimate, not the final number of matched profiles. ```bash curl -sS 'https://app.getleads.io/api/v1/enrich/csv/async' \ -H "Authorization: Bearer $GETLEADS_API_KEY" \ -F 'file=@contacts.csv' \ -F 'mode=linkedin' \ -F 'mapping={"profileUrl":"LinkedIn URL"}' ``` Use MCP `check_enrichment_status` with the returned run ID, followed by `get_enrichment_result` to get the CSV. The alternative MCP upload-link workflow uses `create_csv_enrichment_upload_link`, `check_enrichment_upload`, `check_enrichment_status` and `get_enrichment_result`. ## Contacts lookup ### POST /api/v1/contacts/lookup/colleagues Retrieve people using an `email_domain` or `linkedin_company_url`, not both. Optional `job_titles`, `limit_per_item` and `offset` narrow or page the result. Defaults to 100; REST permits up to 5,000 per request. A work-email domain and the person's current employer can differ, so inspect the returned employer data when current employment matters. ### POST /api/v1/contacts/lookup/decision-makers Find senior contacts using the supported company/domain inputs. Inspect the returned titles and company data against your brief; broad seniority labels do not establish who buys your product. REST permits up to 5,000 per request; MCP `lookup_decision_makers` permits up to 100. ### GET /api/v1/contacts/lookup/phone **Pending.** Reverse lookup from a phone number currently returns HTTP `410`. Phone fields on existing records remain available where populated. ### POST /api/v1/contacts/from-phone **Pending.** Batch reverse lookup currently returns HTTP `410`. It is separate from enrichment that returns phone fields for an identified person. ## Funding signals `GET /api/v1/funding/signals` returns funding-news signals. Use the route's query parameters below for time, region and confidence. These news signals are separate from stored company funding fields. ## Acquisition signals `GET /api/v1/acquisitions/signals` returns acquisition-news signals, including acquirer, target, source and deal amount where available. ## Company followers Follower scrapes are wallet-funded at $3.50 per 1,000 followers, with a $8.75 minimum. Quote first; `POST /api/v1/followers/orders` places a paid order. Filters are applied during fulfilment, and the quote describes their effect on count, price and refunds. Order status and delivery are asynchronous. REST supports quotes, orders and status. MCP `lookup_company_linkedin_followers` gets the free page count/quote; `prepare_company_followers_checkout` provides the app checkout link. ## Profile monitoring Monitoring captures engagement on public LinkedIn profiles. It uses prepaid wallet cash at $0.012 per engager. Backfill and ongoing monitoring are different billing choices; request the estimate before starting monitoring. The API also supports one-time post scrapes, profile status changes and reading captured leads. Creating a monitored profile or a post-scrape job can incur wallet charges. ## Website visitor identification Available through the GetLeads app and MCP. Identification covers US visitors, costs $0.125 per delivered lead and uses the prepaid wallet. Use the pixel tools to set up/configure tracking, complete installation and read/export identified leads. The API-key REST reference below does not expose the app's session-only visitor routes. MCP destinations include webhooks, Smartlead visitor delivery and HeyReach live-lead routing where configured. Setting up a destination does not turn unidentified visitors into identified contacts. ## REST endpoint reference The following request parameters come from the published REST contract. Shared search-filter objects use the catalogue and filter families above. Phone lookup and CSV phone mode remain pending even though older schemas still list them. ### POST /api/v1/contacts/search Search contacts Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `domains` | string[] | No | | | `job_titles` | string[] | No | | | `seniority` | string[] | No | | | `job_functions` | string[] | No | | | `industries` | string[] | No | | | `countries` | string[] | No | | | `headquarters_countries` | string[] | No | | | `company_size` | string[] | No | LinkedIn size-band labels (e.g. "51 to 200"). | | `company_linkedin_urls` | string[] | No | | | `revenue` | string[] | No | | | `cities` | string[] | No | | | `states` | string[] | No | | | `exclude_domains` | string[] | No | | | `exclude_countries` | string[] | No | | | `exclude_headquarters_countries` | string[] | No | | | `exclude_industries` | string[] | No | | | `exclude_job_titles` | string[] | No | | | `email_status` | string[] | No | Email verification status. Use ["VALID"] for deliverable emails. | | `technologies` | string[] | No | Technologies/tools a company uses. | | `funding_types` | string[] | No | Last funding round type (e.g. "Seed", "Series A", "IPO"). | | `headquarters_cities` | string[] | No | | | `company_name` | string | No | | | `first_name` | string | No | | | `last_name` | string | No | | | `email_address` | string | No | | | `linkedin_url` | string | No | | | `company_description` | string | No | Keyword search over company LinkedIn About text. | | `person_description` | string | No | Keyword search over person LinkedIn bio. | | `linkedin_headline` | string | No | | | `education` | string | No | | | `certifications` | string | No | | | `languages` | string | No | | | `job_start_date_min` | string | No | Earliest current-role start date (YYYY-MM-DD). | | `job_start_date_max` | string | No | Latest current-role start date (YYYY-MM-DD). | | `skills` | string | No | Keyword search over contact skills. | | `domain_list_id` | string | No | Saved domain list id. | | `company_size_min` | integer | No | | | `company_size_max` | integer | No | | | `employees_min` | integer | No | Minimum company headcount (band-overlap matching). | | `employees_max` | integer | No | Maximum company headcount (band-overlap matching). | | `employee_profiles_on_linkedin_min` | integer | No | Minimum exact LinkedIn employee-profile headcount (hard cutoff). | | `employee_profiles_on_linkedin_max` | integer | No | Maximum exact LinkedIn employee-profile headcount (hard cutoff). | | `founded_year_min` | integer | No | Earliest founding year. | | `founded_year_max` | integer | No | Latest founding year. | | `total_funding_min` | integer | No | Minimum total funding raised (USD). | | `total_funding_max` | integer | No | Maximum total funding raised (USD). | | `require_email` | boolean | No | | | `require_phone` | boolean | No | | | `require_direct_dial` | boolean | No | Only contacts with a direct-dial phone number. | | `require_company_phone` | boolean | No | Only contacts whose company has a phone number. | | `genders` | string[] | No | Contact gender. Offered only when the active dataset has the data. | | `birth_year_min` | integer | No | Earliest birth year. | | `birth_year_max` | integer | No | Latest birth year. | | `pay_bands` | string[] | No | Estimated annual pay band: <$25K, $25K-$50K, $50K-$75K, $75K-$100K, $100K-$150K, $150K-$200K, $200K+. | | `ipo_status` | string[] | No | Company stock-market status. | | `require_company_profile` | boolean | No | Skip contacts with no company name. Defaults on for domain-only searches that request company columns. | | `require_domain_or_headline` | boolean | No | Rank contacts with a company domain or LinkedIn headline first; remaining matches still appear later in the same page and CSV. Defaults on for the new database. Set false for the raw sort key. | | `open_to_work` | boolean | No | Only contacts with LinkedIn Open to Work signal. | | `is_hiring` | boolean | No | Only contacts with LinkedIn Hiring badge. | | `limit` | integer | No | Page size. | | `offset` | integer | No | Pagination offset. | | `max_per_company` | integer | No | Cap contacts per company. | | `columns` | string[] | No | Columns to include by display label or internal name. Discover names with GET /api/v1/contacts/columns. Unknown Classic-only names return invalid_columns and column_replacements. | | `where_sql` | string | No | Advanced WHERE predicate on catalog fields. AND-combined with curated filters. | ### POST /api/v1/contacts/search/count Count matching contacts Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `domains` | string[] | No | | | `job_titles` | string[] | No | | | `seniority` | string[] | No | | | `job_functions` | string[] | No | | | `industries` | string[] | No | | | `countries` | string[] | No | | | `headquarters_countries` | string[] | No | | | `company_size` | string[] | No | LinkedIn size-band labels (e.g. "51 to 200"). | | `company_linkedin_urls` | string[] | No | | | `revenue` | string[] | No | | | `cities` | string[] | No | | | `states` | string[] | No | | | `exclude_domains` | string[] | No | | | `exclude_countries` | string[] | No | | | `exclude_headquarters_countries` | string[] | No | | | `exclude_industries` | string[] | No | | | `exclude_job_titles` | string[] | No | | | `email_status` | string[] | No | Email verification status. Use ["VALID"] for deliverable emails. | | `technologies` | string[] | No | Technologies/tools a company uses. | | `funding_types` | string[] | No | Last funding round type (e.g. "Seed", "Series A", "IPO"). | | `headquarters_cities` | string[] | No | | | `company_name` | string | No | | | `first_name` | string | No | | | `last_name` | string | No | | | `email_address` | string | No | | | `linkedin_url` | string | No | | | `company_description` | string | No | Keyword search over company LinkedIn About text. | | `person_description` | string | No | Keyword search over person LinkedIn bio. | | `linkedin_headline` | string | No | | | `education` | string | No | | | `certifications` | string | No | | | `languages` | string | No | | | `job_start_date_min` | string | No | Earliest current-role start date (YYYY-MM-DD). | | `job_start_date_max` | string | No | Latest current-role start date (YYYY-MM-DD). | | `skills` | string | No | Keyword search over contact skills. | | `domain_list_id` | string | No | Saved domain list id. | | `company_size_min` | integer | No | | | `company_size_max` | integer | No | | | `employees_min` | integer | No | Minimum company headcount (band-overlap matching). | | `employees_max` | integer | No | Maximum company headcount (band-overlap matching). | | `employee_profiles_on_linkedin_min` | integer | No | Minimum exact LinkedIn employee-profile headcount (hard cutoff). | | `employee_profiles_on_linkedin_max` | integer | No | Maximum exact LinkedIn employee-profile headcount (hard cutoff). | | `founded_year_min` | integer | No | Earliest founding year. | | `founded_year_max` | integer | No | Latest founding year. | | `total_funding_min` | integer | No | Minimum total funding raised (USD). | | `total_funding_max` | integer | No | Maximum total funding raised (USD). | | `require_email` | boolean | No | | | `require_phone` | boolean | No | | | `require_direct_dial` | boolean | No | Only contacts with a direct-dial phone number. | | `require_company_phone` | boolean | No | Only contacts whose company has a phone number. | | `genders` | string[] | No | Contact gender. Offered only when the active dataset has the data. | | `birth_year_min` | integer | No | Earliest birth year. | | `birth_year_max` | integer | No | Latest birth year. | | `pay_bands` | string[] | No | Estimated annual pay band: <$25K, $25K-$50K, $50K-$75K, $75K-$100K, $100K-$150K, $150K-$200K, $200K+. | | `ipo_status` | string[] | No | Company stock-market status. | | `require_company_profile` | boolean | No | Skip contacts with no company name. Defaults on for domain-only searches that request company columns. | | `require_domain_or_headline` | boolean | No | Rank contacts with a company domain or LinkedIn headline first; remaining matches still appear later. Defaults on for the new database. | | `open_to_work` | boolean | No | Only contacts with LinkedIn Open to Work signal. | | `is_hiring` | boolean | No | Only contacts with LinkedIn Hiring badge. | ### POST /api/v1/contacts/search/export Export contacts (async) Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `domains` | string[] | No | | | `job_titles` | string[] | No | | | `seniority` | string[] | No | | | `job_functions` | string[] | No | | | `industries` | string[] | No | | | `countries` | string[] | No | | | `headquarters_countries` | string[] | No | | | `company_size` | string[] | No | LinkedIn size-band labels (e.g. "51 to 200"). | | `company_linkedin_urls` | string[] | No | | | `revenue` | string[] | No | | | `cities` | string[] | No | | | `states` | string[] | No | | | `exclude_domains` | string[] | No | | | `exclude_countries` | string[] | No | | | `exclude_headquarters_countries` | string[] | No | | | `exclude_industries` | string[] | No | | | `exclude_job_titles` | string[] | No | | | `email_status` | string[] | No | Email verification status. Use ["VALID"] for deliverable emails. | | `technologies` | string[] | No | Technologies/tools a company uses. | | `funding_types` | string[] | No | Last funding round type (e.g. "Seed", "Series A", "IPO"). | | `headquarters_cities` | string[] | No | | | `company_name` | string | No | | | `first_name` | string | No | | | `last_name` | string | No | | | `email_address` | string | No | | | `linkedin_url` | string | No | | | `company_description` | string | No | Keyword search over company LinkedIn About text. | | `person_description` | string | No | Keyword search over person LinkedIn bio. | | `linkedin_headline` | string | No | | | `education` | string | No | | | `certifications` | string | No | | | `languages` | string | No | | | `job_start_date_min` | string | No | Earliest current-role start date (YYYY-MM-DD). | | `job_start_date_max` | string | No | Latest current-role start date (YYYY-MM-DD). | | `skills` | string | No | Keyword search over contact skills. | | `domain_list_id` | string | No | Saved domain list id. | | `company_size_min` | integer | No | | | `company_size_max` | integer | No | | | `employees_min` | integer | No | Minimum company headcount (band-overlap matching). | | `employees_max` | integer | No | Maximum company headcount (band-overlap matching). | | `employee_profiles_on_linkedin_min` | integer | No | Minimum exact LinkedIn employee-profile headcount (hard cutoff). | | `employee_profiles_on_linkedin_max` | integer | No | Maximum exact LinkedIn employee-profile headcount (hard cutoff). | | `founded_year_min` | integer | No | Earliest founding year. | | `founded_year_max` | integer | No | Latest founding year. | | `total_funding_min` | integer | No | Minimum total funding raised (USD). | | `total_funding_max` | integer | No | Maximum total funding raised (USD). | | `require_email` | boolean | No | | | `require_phone` | boolean | No | | | `require_direct_dial` | boolean | No | Only contacts with a direct-dial phone number. | | `require_company_phone` | boolean | No | Only contacts whose company has a phone number. | | `genders` | string[] | No | Contact gender. Offered only when the active dataset has the data. | | `birth_year_min` | integer | No | Earliest birth year. | | `birth_year_max` | integer | No | Latest birth year. | | `pay_bands` | string[] | No | Estimated annual pay band: <$25K, $25K-$50K, $50K-$75K, $75K-$100K, $100K-$150K, $150K-$200K, $200K+. | | `ipo_status` | string[] | No | Company stock-market status. | | `require_company_profile` | boolean | No | Skip contacts with no company name. Defaults on for domain-only searches that request company columns. | | `require_domain_or_headline` | boolean | No | Rank contacts with a company domain or LinkedIn headline first; remaining matches still appear later. Defaults on for the new database. | | `open_to_work` | boolean | No | Only contacts with LinkedIn Open to Work signal. | | `is_hiring` | boolean | No | Only contacts with LinkedIn Hiring badge. | | `columns` | string[] | No | | | `max_per_company` | integer | No | | | `max_rows` | integer | No | Maximum rows to export. | ### GET /api/v1/contacts/search/export/{exportId} Poll export status | Field | Type | Required | Description | | --- | --- | --- | --- | | `exportId` | string | Yes | | ### POST /api/v1/companies/search Search companies Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `domains` | string[] | No | | | `industries` | string[] | No | | | `headquarters_countries` | string[] | No | | | `company_size` | string[] | No | LinkedIn size-band labels (e.g. "51 to 200"). | | `company_linkedin_urls` | string[] | No | | | `revenue` | string[] | No | | | `exclude_domains` | string[] | No | | | `exclude_headquarters_countries` | string[] | No | | | `exclude_industries` | string[] | No | | | `technologies` | string[] | No | Technologies/tools a company uses. | | `funding_types` | string[] | No | Last funding round type (e.g. "Seed", "Series A", "IPO"). | | `headquarters_cities` | string[] | No | | | `company_name` | string | No | | | `company_description` | string | No | Keyword search over company LinkedIn About text. | | `domain_list_id` | string | No | Saved domain list id. | | `company_size_min` | integer | No | | | `company_size_max` | integer | No | | | `employees_min` | integer | No | Minimum company headcount (band-overlap matching). | | `employees_max` | integer | No | Maximum company headcount (band-overlap matching). | | `employee_profiles_on_linkedin_min` | integer | No | Minimum exact LinkedIn employee-profile headcount (hard cutoff). | | `employee_profiles_on_linkedin_max` | integer | No | Maximum exact LinkedIn employee-profile headcount (hard cutoff). | | `founded_year_min` | integer | No | Earliest founding year. | | `founded_year_max` | integer | No | Latest founding year. | | `total_funding_min` | integer | No | Minimum total funding raised (USD). | | `total_funding_max` | integer | No | Maximum total funding raised (USD). | | `ipo_status` | string[] | No | Company stock-market status. | | `require_company_profile` | boolean | No | Skip contacts with no company name. Defaults on for domain-only searches that request company columns. | | `require_domain_or_headline` | boolean | No | Rank contacts with a company domain or LinkedIn headline first; remaining matches still appear later. Defaults on for the new database. | | `limit` | integer | No | | | `offset` | integer | No | | | `columns` | string[] | No | Company columns only. Discover with GET /api/v1/companies/columns. | | `where_sql` | string | No | | ### POST /api/v1/companies/search/count Count matching companies Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `domains` | string[] | No | | | `industries` | string[] | No | | | `headquarters_countries` | string[] | No | | | `company_size` | string[] | No | LinkedIn size-band labels (e.g. "51 to 200"). | | `company_linkedin_urls` | string[] | No | | | `revenue` | string[] | No | | | `exclude_domains` | string[] | No | | | `exclude_headquarters_countries` | string[] | No | | | `exclude_industries` | string[] | No | | | `technologies` | string[] | No | Technologies/tools a company uses. | | `funding_types` | string[] | No | Last funding round type (e.g. "Seed", "Series A", "IPO"). | | `headquarters_cities` | string[] | No | | | `company_name` | string | No | | | `company_description` | string | No | Keyword search over company LinkedIn About text. | | `domain_list_id` | string | No | Saved domain list id. | | `company_size_min` | integer | No | | | `company_size_max` | integer | No | | | `employees_min` | integer | No | Minimum company headcount (band-overlap matching). | | `employees_max` | integer | No | Maximum company headcount (band-overlap matching). | | `employee_profiles_on_linkedin_min` | integer | No | Minimum exact LinkedIn employee-profile headcount (hard cutoff). | | `employee_profiles_on_linkedin_max` | integer | No | Maximum exact LinkedIn employee-profile headcount (hard cutoff). | | `founded_year_min` | integer | No | Earliest founding year. | | `founded_year_max` | integer | No | Latest founding year. | | `total_funding_min` | integer | No | Minimum total funding raised (USD). | | `total_funding_max` | integer | No | Maximum total funding raised (USD). | | `ipo_status` | string[] | No | Company stock-market status. | | `require_company_profile` | boolean | No | Skip contacts with no company name. Defaults on for domain-only searches that request company columns. | | `require_domain_or_headline` | boolean | No | Rank contacts with a company domain or LinkedIn headline first; remaining matches still appear later. Defaults on for the new database. | ### GET /api/v1/companies/lookup Look up one company | Field | Type | Required | Description | | --- | --- | --- | --- | | `domain` | string | No | | | `company_name` | string | No | | ### POST /api/v1/companies/search/export Export companies to CSV Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `domains` | string[] | No | | | `industries` | string[] | No | | | `headquarters_countries` | string[] | No | | | `company_size` | string[] | No | LinkedIn size-band labels (e.g. "51 to 200"). | | `company_linkedin_urls` | string[] | No | | | `revenue` | string[] | No | | | `exclude_domains` | string[] | No | | | `exclude_headquarters_countries` | string[] | No | | | `exclude_industries` | string[] | No | | | `technologies` | string[] | No | Technologies/tools a company uses. | | `funding_types` | string[] | No | Last funding round type (e.g. "Seed", "Series A", "IPO"). | | `headquarters_cities` | string[] | No | | | `company_name` | string | No | | | `company_description` | string | No | Keyword search over company LinkedIn About text. | | `domain_list_id` | string | No | Saved domain list id. | | `company_size_min` | integer | No | | | `company_size_max` | integer | No | | | `employees_min` | integer | No | Minimum company headcount (band-overlap matching). | | `employees_max` | integer | No | Maximum company headcount (band-overlap matching). | | `employee_profiles_on_linkedin_min` | integer | No | Minimum exact LinkedIn employee-profile headcount (hard cutoff). | | `employee_profiles_on_linkedin_max` | integer | No | Maximum exact LinkedIn employee-profile headcount (hard cutoff). | | `founded_year_min` | integer | No | Earliest founding year. | | `founded_year_max` | integer | No | Latest founding year. | | `total_funding_min` | integer | No | Minimum total funding raised (USD). | | `total_funding_max` | integer | No | Maximum total funding raised (USD). | | `ipo_status` | string[] | No | Company stock-market status. | | `require_company_profile` | boolean | No | Skip contacts with no company name. Defaults on for domain-only searches that request company columns. | | `require_domain_or_headline` | boolean | No | Rank contacts with a company domain or LinkedIn headline first; remaining matches still appear later. Defaults on for the new database. | | `columns` | string[] | No | | | `max_rows` | integer | No | | | `where_sql` | string | No | | ### GET /api/v1/companies/search/export/{export_id} Poll company export | Field | Type | Required | Description | | --- | --- | --- | --- | | `export_id` | string | Yes | | ### GET /api/v1/companies/columns List company columns ### GET /api/v1/contacts/filter-values Get valid values for a filter field | Field | Type | Required | Description | | --- | --- | --- | --- | | `field` | string | Yes | Filter field name (e.g. seniority, industries, company_size). | ### GET /api/v1/contacts/columns List selectable search columns | Field | Type | Required | Description | | --- | --- | --- | --- | | `group` | string | No | Optional group filter (e.g. Company, Contact Job). | | `searchable_only` | boolean | No | When true, only fields usable in where_sql. | | `exportable_only` | boolean | No | When true, only fields usable in columns / CSV export. | ### GET /api/v1/contacts/health Dataset health check ### GET /api/v1/contacts/lookup/phone **Pending — currently HTTP 410.** ### POST /api/v1/contacts/from-phone **Pending — currently HTTP 410.** ### POST /api/v1/contacts/lookup/colleagues Find colleagues at a company Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `email_domain` | string | No | Work email domain (e.g. acme.com). Mutually exclusive with linkedin_company_url. | | `linkedin_company_url` | string | No | LinkedIn company URL. Mutually exclusive with email_domain. | | `job_titles` | string[] | No | Optional title filter. | | `limit_per_item` | integer | No | | | `offset` | integer | No | | ### POST /api/v1/contacts/lookup/decision-makers Find decision-makers at a company Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `domain` | string | No | Company domain. Exactly one of domain, company_name, or linkedin_company_url required. | | `company_name` | string | No | | | `linkedin_company_url` | string | No | | | `limit` | integer | No | | | `offset` | integer | No | | | `require_email` | boolean | No | Always true (contacts without valid email are excluded). | | `email_status` | string[] | No | | ### POST /api/v1/enrich/from-linkedin Enrich from LinkedIn URLs Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `items` | object[] | Yes | | | `limit_per_item` | integer | No | | ### POST /api/v1/enrich/from-email Reverse email lookup Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `items` | object[] | Yes | | ### POST /api/v1/enrich/from-person Enrich from name and company Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `items` | object[] | Yes | | ### POST /api/v1/enrich/csv Enrich CSV (sync) Request body: `multipart/form-data`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `file` | string | No | | | `mode` | string | No | Values: `linkedin`, `work_email`, `person`. Phone enrichment is pending. | | `mapping` | string | No | JSON column-mapping object. | | `maxRows` | integer | No | | | `fileName` | string | No | | Use the shared search filters and search/export options above. ### POST /api/v1/enrich/csv/async Enrich CSV (async) Request body: `multipart/form-data`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `file` | string | No | | | `mode` | string | No | Values: `linkedin`, `work_email`, `person`. Phone enrichment is pending. | | `mapping` | string | No | | | `maxRows` | integer | No | | | `fileName` | string | No | | ### POST /api/v1/enrich/batch Enrich from LinkedIn (deprecated) Deprecated alias; use the named enrichment endpoint for new integrations. Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `items` | object[] | Yes | | | `limit_per_item` | integer | No | | ### POST /api/v1/enrich/batch-profile Reverse email lookup (deprecated) Deprecated alias; use the named enrichment endpoint for new integrations. Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `items` | object[] | Yes | | ### POST /api/v1/enrich/batch-person Enrich from name + company (deprecated) Deprecated alias; use the named enrichment endpoint for new integrations. Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `items` | object[] | Yes | | ### GET /api/v1/funding/signals List funding signals | Field | Type | Required | Description | | --- | --- | --- | --- | | `limit` | integer | No | | | `since` | string | No | Earliest date (YYYY-MM-DD). | | `min_confidence` | number | No | | | `region` | string | No | Values: `US`, `EU`, `GLOBAL`. | ### GET /api/v1/acquisitions/signals List acquisition signals | Field | Type | Required | Description | | --- | --- | --- | --- | | `limit` | integer | No | | | `since` | string | No | Earliest date (YYYY-MM-DD). | | `min_confidence` | number | No | | | `acquirer` | string | No | Filter by acquirer name. | | `target` | string | No | Filter by target name. | | `has_amount` | boolean | No | Only signals with a disclosed amount. | | `min_amount` | number | No | | ### POST /api/v1/followers/quote Quote follower export cost Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `linkedin_company_url` | string | Yes | | | `requested_count` | integer | No | | | `delivery_email` | string | No | | | `filters` | object | No | | `delivery_email` is required for delivery. The quote/order minimum is 2,500 leads ($8.75); use the returned quote before ordering. ### GET /api/v1/followers/orders List follower orders | Field | Type | Required | Description | | --- | --- | --- | --- | | `page` | integer | No | | | `page_size` | integer | No | | ### POST /api/v1/followers/orders Place follower export order Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `linkedin_company_url` | string | Yes | | | `requested_count` | integer | No | | | `delivery_email` | string | No | | | `email` | string | No | Alias for delivery_email. | | `filters` | object | No | | `delivery_email` is required for delivery. The quote/order minimum is 2,500 leads ($8.75); use the returned quote before ordering. ### GET /api/v1/followers/orders/{orderId} Get follower order status | Field | Type | Required | Description | | --- | --- | --- | --- | | `orderId` | string | Yes | | ### GET /api/v1/profile-monitoring/profiles List monitored profiles ### POST /api/v1/profile-monitoring/profiles Add a monitored profile Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `linkedin_profile_url` | string | Yes | | | `billing_choice` | string | No | Values: `backfill_and_new`, `new_only`. | ### PATCH /api/v1/profile-monitoring/profiles/{profileId} Pause or resume a monitored profile | Field | Type | Required | Description | | --- | --- | --- | --- | | `profileId` | string | Yes | | Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `active` | boolean | Yes | | ### DELETE /api/v1/profile-monitoring/profiles/{profileId} Remove a monitored profile | Field | Type | Required | Description | | --- | --- | --- | --- | | `profileId` | string | Yes | | ### POST /api/v1/profile-monitoring/profiles/estimate Estimate monitoring cost Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `linkedin_profile_url` | string | No | | | `billing_choice` | string | No | Values: `backfill_and_new`, `new_only`. | | `engagers_last_month` | integer | No | | ### GET /api/v1/profile-monitoring/leads List profile monitoring leads | Field | Type | Required | Description | | --- | --- | --- | --- | | `limit` | integer | No | | | `cursor` | string | No | | ### GET /api/v1/profile-monitoring/jobs/{jobId} Get job status | Field | Type | Required | Description | | --- | --- | --- | --- | | `jobId` | string | Yes | | ### POST /api/v1/profile-monitoring/jobs/post-scrape One-time LinkedIn post scrape Request body: `application/json`. | Field | Type | Required | Description | | --- | --- | --- | --- | | `post_url` | string | Yes | | ### GET /api/v1/profile-monitoring/summary Profile monitoring account summary ### GET /api/v1/usage/fair-use Fair-use limits and credit balance ## MCP tools In your AI tool’s connector or MCP settings, add a remote server named **GetLeads** with URL `https://app.getleads.io/api/mcp`. Choose OAuth or sign-in authentication, connect, sign in to GetLeads and approve access. No API key is needed for this sign-in flow. API-key clients can instead send Bearer authentication to the same endpoint using Streamable HTTP and JSON-RPC. There are **58 tools** in the production inventory checked 29 October 2026. The current `tools/list` response is authoritative. MCP search filters are flat tool arguments rather than the REST `filters` wrapper. `export_contacts` and `export_companies` require `confirmed: true`. Do not copy that confirmation flag into REST requests. ### Tool inventory **Contact search and exports** `search_contacts`, `count_contacts`, `export_contacts`, `check_contact_export`, `get_available_columns`, `get_available_values`. **Company search** `search_companies`, `count_companies`, `lookup_company`, `export_companies`, `check_company_export`. **People and enrichment** `getleads_get_emails_from_linkedin_batch`, `getleads_get_linkedin_urls_from_emails_batch`, `getleads_enrich_person_batch`, `getleads_lookup_colleagues`, `lookup_decision_makers`, `create_csv_enrichment_upload_link`, `check_enrichment_upload`, `check_enrichment_status`, `get_enrichment_result`, `create_decision_makers_batch_link`, `check_decision_makers_batch`, `get_decision_makers_batch_result`. **Signals** `list_funding_signals`, `list_acquisition_signals`. **Company followers** `lookup_company_linkedin_followers`, `prepare_company_followers_checkout`. **Profile monitoring** `list_monitored_profiles`, `add_monitored_profile`, `scrape_linkedin_post_once`, `set_monitored_profile_active`, `remove_monitored_profile`, `list_profile_monitoring_leads`, `get_profile_monitoring_handoff_prompt`. **Website visitors** `list_website_pixels`, `start_website_visitor_tracking`, `configure_website_pixel`, `configure_website_visitors_smartlead`, `complete_website_pixel_setup`, `set_website_pixel_status`, `delete_website_pixel`, `list_website_visitor_leads`, `export_website_visitor_leads`. **HeyReach** `configure_heyreach`, `list_heyreach_destinations`, `send_contacts_to_heyreach`, `check_heyreach_send`, `create_heyreach_campaign`, `configure_live_leads_heyreach`, `enrich_heyreach_leads`, `get_heyreach_campaign`. **Account and wallet** `getleads_health`, `getleads_contacts_health`, `get_fair_use`, `get_wallet_balance`, `estimate_scrape_cost`, `create_topup_link`, `configure_auto_topup`. ### Calling a tool from an API client ```bash curl -sS 'https://app.getleads.io/api/mcp' \ -H "Authorization: Bearer $GETLEADS_API_KEY" \ -H 'Content-Type: application/json' \ -H 'Accept: application/json, text/event-stream' \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_available_columns","arguments":{}}}' ``` The response can be JSON or an event stream. For event streams, read the JSON-RPC result with your request ID rather than assuming the first event contains it. ### Paging search results over MCP `search_contacts` and `search_companies` return up to 100 rows per call. Follow `has_more` and `next_offset`; use the relevant free count tool for audience size and export tools for CSVs. `export_companies` has its own poll tool, `check_company_export`. For agent workflows, see [thinking-mode](https://www.getleads.io/thinking-mode), [company-list](https://www.getleads.io/company-list) and [get-everyone](https://www.getleads.io/get-everyone).