# Get API Key Details Source: https://docs.blitz-api.ai/api-reference/account/get-api-key-details api-reference/v2.openapi.json GET /v2/account/key-info Check API key validity, remaining records, rate limit, allowed endpoints, and active subscription plans.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**0 records** Use this as a **health check** before running batch jobs. A 200 response confirms the key is valid, and the record balance covers the run. How to provision and use the `x-api-key` header across BlitzAPI endpoints. # Get Changelog Source: https://docs.blitz-api.ai/api-reference/changelog/changelog api-reference/v2.openapi.json GET /changelog Public — no API key required. Returns changelog entries newest-first: breaking changes, new features, improvements, fixes, deprecations, and announcements. Use `days` to limit to recent changes and `limit` to cap the number of entries (default 50).
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**0 records** **Public endpoint.** No API key required — call it without the `x-api-key` header. Fetch the Blitz API changelog programmatically. Entries are returned newest-first and cover breaking changes, new features, improvements, fixes, deprecations, and announcements. Use it to surface release notes inside your own tools or to alert your team whenever an endpoint you depend on changes. Pass `days` to fetch only recent entries (e.g. `days=7` for the last week) and `limit` to cap how many you get back (default `50`). Each entry's `affected_endpoints` lists the routes that changed, and `type` categorizes the impact — one of `breaking`, `feature`, `improvement`, `fix`, `deprecation`, or `announcement`. # Company Enrichment Source: https://docs.blitz-api.ai/api-reference/company-enrichment/company-enrichment api-reference/v2.openapi.json POST /v2/enrichment/company Retrieve a full company profile from a LinkedIn company URL.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record** Retrieve a full company profile from a LinkedIn company URL — name, industry, employee count, headquarters location, website, and more. If you only have a domain, run **Domain to Linkedin URL** first, then pipe the LinkedIn URL into this endpoint. Most other v2 endpoints (Waterfall ICP, Employee Finder) also accept LinkedIn URLs, so this resolution step unlocks the full pipeline. Compose enrichment endpoints into a CRM-ready pipeline. # Domain to Linkedin URL Source: https://docs.blitz-api.ai/api-reference/company-enrichment/domain-to-linkedin-url api-reference/v2.openapi.json POST /v2/enrichment/domain-to-linkedin Convert a website domain into a Company LinkedIn URL.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record** Convert a website domain into a Company LinkedIn URL. Use this as the **first step** when your source data only contains domains. The LinkedIn URL is the required input for Waterfall ICP Search, Employee Finder, and Company Enrichment — once you have it, you can call any of those. Response carries `found`. On `found: false`, no LinkedIn page maps to the domain — usually because the company is private, very small, or branded under a different domain than its public site. How domain resolution fits into the full ICP-list-building flow. # Linkedin URL to Domain Source: https://docs.blitz-api.ai/api-reference/company-enrichment/linkedin-url-to-domain api-reference/v2.openapi.json POST /v2/enrichment/linkedin-to-domain Get the email domain associated with a Company LinkedIn URL.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record** Get the email domain associated with a Company LinkedIn URL. Response carries `found`. On `found: true`, `email_domain` is the canonical domain used for company email addresses (often differs from a marketing/website domain). On `found: false`, no email domain has been resolved for the company. Domain resolution as part of a full contact-enrichment pipeline. # Company Search Source: https://docs.blitz-api.ai/api-reference/company-search/company-search api-reference/v2.openapi.json POST /v2/search/companies Find companies matching ICP criteria (industry, size, location, keywords).
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record per result** Find companies matching ICP criteria (industry, size, location, keywords). Returns company profiles with LinkedIn URLs ready for downstream enrichment or Employee Finder calls. **Pagination is cursor-based.** Pass the `cursor` from each response back into the next request. `cursor: null` means you're on the first page; a `null` cursor in the response means you've reached the end. **Filter logic:** all filters combine with **AND**. Multiple values within a single filter combine with **OR** — e.g. two industries in `industry.include` returns companies in *either* industry. Build an ICP-aligned company list — full walk-through with example filters. # TAM By Jobs Source: https://docs.blitz-api.ai/api-reference/company-search/tam-by-jobs api-reference/v2.openapi.json POST /v2/company/tam-by-jobs Returns the distinct companies hiring for the matching jobs (deduplicated), each with its matched-jobs count. Optional job.min_per_company floors that count; when it filters heavily, a page may be partial — keep paging until cursor is null. Cost: 1 record per result (max = max_results)
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record per result** Build a total addressable market (TAM) from hiring signals. Filter live job postings the same way you would with [Search Jobs](/api-reference/job-search/search-jobs) — but instead of individual jobs, this endpoint returns the **distinct companies** hiring for those roles (deduplicated), each with its `matched_jobs` count. Combine job-level filters (title, description, field, seniority, employment type, work arrangement, location, date posted) with company-level firmographics (industry, size, headcount, HQ) to surface accounts that match your ICP *and* are actively hiring. **Pagination is cursor-based.** Pass the `cursor` returned by each response back into the next request. `cursor: null` means you're on the first page; a `null` cursor in the response means you've reached the end. **`job.min_per_company`** floors the matched-jobs count — only companies with at least that many matching postings are returned (max `25`, `0` = unset). When it filters heavily, a page may come back partial: keep paging until `cursor` is `null`. **Filter logic:** all filters combine with **AND**. Multiple values within a single `include` list combine with **OR** — e.g. two values in `job.title.include` returns companies hiring for *either* role. Use `exclude` to filter matches out. Build an ICP-aligned company list — full walk-through with example filters. # TAM By People Source: https://docs.blitz-api.ai/api-reference/company-search/tam-by-people api-reference/v2.openapi.json POST /v2/company/tam-by-people Returns the distinct companies whose current employees match the people and firmographic filters (deduplicated), each with its matched-people count. Takes the same input as [Find People](/api-reference/people-search/find-people). Optional people.min_per_company floors that count; when it filters heavily, a page may be partial, so keep paging until cursor is null. Cost: 1 record per result (max = max_results)
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record per result** Build a total addressable market (TAM) from headcount signals. Filter people the same way you would with [Find People](/api-reference/people-search/find-people), but instead of individual contacts this endpoint returns the **distinct companies** employing them (deduplicated), each with its `matched_people` count. Combine people-level filters (title, function, level, location, education) with company-level firmographics (industry, size, revenue, funding, HQ) to size the set of accounts that actually employ your buyer persona. **Pagination is cursor-based.** Pass the `cursor` returned by each response back into the next request. `cursor: null` means you're on the first page; a `null` cursor in the response means you've reached the end. **`people.min_per_company`** floors the matched-people count, so only companies with at least that many matching employees are returned (max `25`, `0` = unset). When it filters heavily, a page may come back partial: keep paging until `cursor` is `null`. **TAM By People vs [TAM By Jobs](/api-reference/company-search/tam-by-jobs):** By People sizes accounts on who already works there, By Jobs on who they are hiring. Use By People for persona-based ICP sizing, By Jobs for intent. **Filter logic:** all filters combine with **AND**. Multiple values within a single `include` list combine with **OR**. Use `exclude` to filter matches out. Build an ICP-aligned company list, with a full walk-through and example filters. # Search Company Jobs Source: https://docs.blitz-api.ai/api-reference/job-search/company-jobs api-reference/v2.openapi.json POST /v2/jobs/company List job postings at a single company from its LinkedIn company URL, with optional job-level filters.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record per result** List live job postings at a single company. Pass the target's `company_linkedin_url` to scope results to that company, then optionally narrow with job-level filters (title, description, field, seniority, employment type, work arrangement, location, date posted). **Pagination is cursor-based.** Pass the `cursor` returned by each response back into the next request. `cursor: null` means you're on the first page; a `null` cursor in the response means you've reached the end. A single query returns up to **5,000 jobs**, paginating through a maximum of **50 results** per request. **Filter logic:** all filters combine with **AND**. Multiple values within a single `include` list combine with **OR**. Use `exclude` to filter matches out. # Search Jobs Source: https://docs.blitz-api.ai/api-reference/job-search/search-jobs api-reference/v2.openapi.json POST /v2/jobs/search Search job postings across companies by job attributes, location, and company firmographics.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record per result** Search live job postings across companies in a single call. Combine job-level filters (title, description, field, seniority, employment type, work arrangement, location, date posted) with company-level firmographics (industry, size, headcount, HQ) to surface hiring signals that match your ICP. **Pagination is cursor-based.** Pass the `cursor` returned by each response back into the next request. `cursor: null` means you're on the first page; a `null` cursor in the response means you've reached the end. A single query returns up to **5,000 jobs**, paginating through a maximum of **50 results** per request. **Filter logic:** all filters combine with **AND**. Multiple values within a single `include` list combine with **OR** — e.g. two values in `job.title.include` returns jobs matching *either* title keyword. Use `exclude` to filter matches out. # Find Mobile & Direct Phone Source: https://docs.blitz-api.ai/api-reference/people-enrichment/find-mobile-&-direct-phone api-reference/v2.openapi.json POST /v2/enrichment/phone Retrieve a direct mobile phone number from a LinkedIn profile URL.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record** **Phone enrichment is not available on the Trial plan.** It requires a paid plan. Retrieve a direct mobile phone number from a LinkedIn profile URL. **Coverage is limited to United States only.** End-to-end pattern for processing a list of LinkedIn URLs into verified contact data. # Find Work Email Source: https://docs.blitz-api.ai/api-reference/people-enrichment/find-work-email api-reference/v2.openapi.json POST /v2/enrichment/email Retrieve a verified work email address from a LinkedIn profile URL.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record** Retrieve a verified work email address from a LinkedIn profile URL. Response always carries `found`. On `found: true`, the verified `email` and a `all_emails[]` array are populated. On `found: false`, no verified email exists in our database — `email` will be `null`. End-to-end pattern for processing a list of LinkedIn URLs into verified contact data. # Person Enrichment Source: https://docs.blitz-api.ai/api-reference/people-enrichment/person-enrichment api-reference/v2.openapi.json POST /v2/enrichment/person Retrieve a professional's full profile and entire career history from their LinkedIn profile URL.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record on success** Retrieve a professional's full profile and entire career history from their LinkedIn profile URL. Response always carries `found`. On `found: true`, `person` holds the full profile: identity, headline, location, every role in `experiences[]`, plus `education[]`, `skills[]` and `certifications[]`. On `found: false`, `person` is `null` and no record is charged. This is the profile-first counterpart to the reverse lookups. Use it when you already hold a LinkedIn URL and want the whole career, not a single contact point. Pair it with [Find Work Email](/api-reference/people-enrichment/find-work-email) or [Find Mobile & Direct Phone](/api-reference/people-enrichment/find-mobile-&-direct-phone) when you also need a way to reach them. End-to-end pattern for processing a list of LinkedIn URLs into verified contact data. # Reverse Email Lookup Source: https://docs.blitz-api.ai/api-reference/people-enrichment/reverse-email-lookup api-reference/v2.openapi.json POST /v2/enrichment/email-to-person Identify a professional and retrieve their full profile starting from a verified work email address.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record** Identify a professional and retrieve their full profile starting from a verified work email address. Useful for **CRM hygiene** — given an inbound email, you get back the LinkedIn profile, current job, company, and seniority. Pair with Find Work Email when you need to round-trip between identity surfaces. Reverse lookups for cleaning, enriching, and de-duping CRM records. # Reverse Phone Lookup Source: https://docs.blitz-api.ai/api-reference/people-enrichment/reverse-phone-lookup api-reference/v2.openapi.json POST /v2/enrichment/phone-to-person Identify a professional and retrieve their full profile from a verified phone number.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record** **Phone enrichment is not available on the Trial plan.** It requires a paid plan. Identify a professional and retrieve their full profile from a verified phone number. **Coverage is limited to United States only.** Reverse lookups for cleaning, enriching, and de-duping CRM records. # Employee Finder Source: https://docs.blitz-api.ai/api-reference/people-search/employee-finder api-reference/v2.openapi.json POST /v2/search/employee-finder Search all employees at a single company by job level, department, location, and seniority.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record per result** Search all employees at a single company by job level, department, location, and seniority. **Pagination is page-based.** Increment `page` until `page > total_pages` to walk the full result set. Pagination is limited to maximum of 10k results. Browse all employees at a target company with filters — full walk-through with examples. # Find People Source: https://docs.blitz-api.ai/api-reference/people-search/find-people api-reference/v2.openapi.json POST /v2/search/people Search decision-makers across many companies in a single call. Every result carries the person's full position history in experiences[], in profile order, not just the position that matched your filters.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record per result** **Job title - exact match:** wrap a value in square brackets to switch from keyword matching to exact matching. `"[CEO]"` matches only `CEO`/`ceo`/`Céo`; `"CEO"` (no brackets) is FTS (full text search) and also matches `Co-CEO`, `CEO Office`. Mixed arrays are allowed: `["[CEO]", "Founder"]`. [Full rules](/guide/reference/normalization/filters). Search decision-makers across many companies in a single call. Combine company-level filters (industry, size, HQ) with person-level filters (job title, level, location). **Pagination is cursor-based.** Pass the `cursor` returned by each response back into the next request. Stop when `cursor` is `null`. Pagination is limited to maximum to 50k results. **Filter logic:** All filters combine with **AND**. Multiple values within a single filter combine with **OR** — e.g. two industries in `company.industry.include` returns people at companies in *either* industry. Walk-through of combining company and person filters to build an ICP list end-to-end. # Waterfall ICP Search Source: https://docs.blitz-api.ai/api-reference/people-search/waterfall-icp-search api-reference/v2.openapi.json POST /v2/search/waterfall-icp-keyword Find the best decision-maker at a target company using a prioritized cascade hierarchy.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record per result** Find the best decision-maker at a target company using a prioritized cascade hierarchy. The engine tries each tier in order and stops as soon as `max_results` is reached. **Job title - exact match:** wrap a value in square brackets to switch from keyword matching to exact matching. `"[CEO]"` matches only `CEO`/`ceo`/`Céo`; `"CEO"` (no brackets) is FTS (full text search) and also matches `Co-CEO`, `CEO Office`. Mixed arrays are allowed: `["[CEO]", "Founder"]`. [Full rules](/guide/reference/normalization/filters). **`icp`** is the cascade tier that matched (1 = highest priority). **`ranking`** is overall relevance within the company (1 = most relevant). Two different signals that you can combine when ordering results client-side. How the cascade picks the right contact when you don't have a profile URL. # Company Distribution by Department Source: https://docs.blitz-api.ai/api-reference/utilities/company-department-distribution api-reference/v2.openapi.json POST /v2/enrichment/company-distribution-by-department Returns the distribution of a company's employees grouped by department. Employees with no classified department are counted under "Other".
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record** Get the distribution of a company's employees, grouped by department, from a LinkedIn company URL. Counts are returned in descending order, and `total_employees` is the sum of every bucket's `count`. Each bucket also includes a `percentage_ratio` — its share of `total_employees` (0–100, to 2 decimals). Employees whose department could not be classified are grouped under `Other`. A company with no matching employees returns an empty `distribution` array and `total_employees: 0`. If you only have a domain, run **Domain to Linkedin URL** first, then pipe the LinkedIn URL into this endpoint. # Company Distribution by Country Source: https://docs.blitz-api.ai/api-reference/utilities/company-employment-distribution api-reference/v2.openapi.json POST /v2/enrichment/company-distribution-by-country Returns the distribution of a company's employees grouped by ISO 3166-1 alpha-2 country code.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**1 record** Get the geographic distribution of a company's employees, grouped by country, from a LinkedIn company URL. Each bucket returns both a `count` and a `percentage_ratio` — the bucket's share of `total_employees` (0–100, to 2 decimals). Countries are reported as ISO 3166-1 alpha-2 codes (e.g. `US`, `GB`). Employees whose country could not be determined are grouped under `unknown`. If you only have a domain, run **Domain to Linkedin URL** first, then pipe the LinkedIn URL into this endpoint. # Get Current Date and Time Source: https://docs.blitz-api.ai/api-reference/utilities/get-current-date-and-time api-reference/v2.openapi.json POST /v2/utils/current-date Get the current server date and time.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**0 records** Get the current date and time in a given timezone. The timezone is specified in the `region` parameter. The timezone must be a valid timezone string. You can find the list of valid timezone strings [here](https://docs.sentinel.thalesgroup.com/softwareandservices/ems/EMSdocs/WSG/Content/TimeZone.htm). # Company Search Source: https://docs.blitz-api.ai/guide/concepts/company-search # Company Search > Find companies matching precise ICP criteria. Build ABM lists and power dynamic prospecting workflows.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**API Reference**: [`Company Search` endpoint](/api-reference/company-search/company-search) — full request/response schema and try-it console. The **Company Search** endpoint (`POST /v2/search/companies`) lets you find companies matching precise criteria. Use it to: * Build ABM target lists from scratch * Identify ICP-matching accounts by industry, size, and geography * Power dynamic prospecting workflows without static lists **Paid plans**: Unlimited — included in your flat monthly subscription. **Need the people, not just the companies?** [Find People](/guide/concepts/find-people) accepts the **exact same `company` filter object** as Company Search and returns matching decision-makers in one call — no need to chain Company Search → Employee Finder. *** ## How It Works You send a `POST` request with a `company` object containing your filters. All filters are **optional** and combined with **AND** logic. Within each filter, multiple values use **OR** logic. The API returns a paginated list of company profiles matching your criteria. *** ## Request Parameters | Parameter | Type | Required | Description | | :- | :- | :- | :- | | `company` | `object` | Yes | Filter object. All nested fields are optional and combined with AND logic. | | `max_results` | `integer` | No | Number of companies to return. Default: `10`. Max: `25`. | | `cursor` | `string` | No | Pagination cursor from a previous response. Pass to get the next page. (Hard limit on the 1,000th page) | ### Company Filter Fields | Field | Type | Description | Example | | :- | :- | :- | :- | | `keywords.include` | `array` | Keywords that must appear in the company profile | `["SaaS", "B2B"]` | | `keywords.exclude` | `array` | Keywords to exclude | `["agency", "consulting"]` | | `industry.include` | `array` | Industry names (must use [normalized values](/guide/reference/normalization/industries)) | `["Software Development"]` | | `hq.country_code` | `array` | HQ country codes (2-letter ISO, e.g., `"US"`) | `["FR", "DE"]` | | `employee_range` | `array` | Employee count ranges | `["51-200", "201-500"]` | Industry values are **case-sensitive and normalized**. Passing `"Tech"` instead of `"Computer Software"` or `"SaaS"` instead of `"Software Development"` returns a [`422`](/guide/reference/errors#validation-errors-422) naming the invalid value. See the [Field Normalization reference](/guide/reference/normalization) for accepted values. *** ## Example Request Find SaaS companies with 51-500 employees headquartered in France or Germany: ```javascript Node.js theme={null} const companies = await client.search.companies({ company: { keywords: { include: ["SaaS"] }, industry: { include: ["Software Development"] }, hq: { country_code: ["FR", "DE"] }, employee_range: ["51-200", "201-500"], }, max_results: 25, }); for (const company of companies.data) { console.log(`${company.name} — ${company.industry}`); console.log(` LinkedIn: ${company.linkedin_url}`); console.log(` Employees: ${company.employees_on_linkedin}`); } ``` ```python Python theme={null} companies = client.search.companies( company={ "keywords": {"include": ["SaaS"]}, "industry": {"include": ["Software Development"]}, "hq": {"country_code": ["FR", "DE"]}, "employee_range": ["51-200", "201-500"], }, max_results=25, ) for company in companies.results: print(f"{company.name} — {company.industry}") print(f" LinkedIn: {company.linkedin_url}") print(f" Employees: {company.employees_on_linkedin}") ``` ```bash cURL theme={null} curl -X POST "https://api.blitz-api.ai/v2/search/companies" \ -H "Content-Type: application/json" \ -H "x-api-key: YOUR_API_KEY" \ -d '{ "company": { "keywords": { "include": ["SaaS"] }, "industry": { "include": ["Software Development"] }, "hq": { "country_code": ["FR", "DE"] }, "employee_range": ["51-200", "201-500"] }, "max_results": 25 }' ``` *** ## Response Schema The JSON below is the **raw HTTP response**. The SDKs wrap this page and expose its items under a language-specific property — in the examples above, `companies.data` (TypeScript/Node.js) and `companies.results` (Python) refer to the same `results[]` array shown here. See [Page object shape](/sdks/pagination#page-object-shape) for the full mapping. ```json theme={null} { "results_length": 25, "cursor": "eyJwYWdlIjoy...", "results": [ { "name": "Acme Corp", "linkedin_url": "https://www.linkedin.com/company/acme-corp", "website": "acme.com", "industry": "Software Development", "employees_on_linkedin": 120, "hq": { "city": "Paris", "country": "France", "country_code": "FR" } } ] } ``` | Field | Type | Description | | :- | :- | :- | | `results_length` | `integer` | Number of results in this page. | | `cursor` | `string` | Pass this value in the next request to get the following page. `null` if no more results. | | `results[].name` | `string` | Company name. | | `results[].linkedin_url` | `string` | Company LinkedIn URL. Use this as input for Waterfall ICP, Employee Finder, and Company Enrichment endpoints. | | `results[].website` | `string` | Company website domain. | | `results[].industry` | `string` | Normalized industry name. | | `results[].employees_on_linkedin` | `integer` | Approximate employee count on LinkedIn. | | `results[].hq` | `object` | Headquarters location (city, country, country\_code). | *** ## Pagination The API supports cursor-based pagination. Each response includes a `cursor` field. Pass it in the next request to get the following page. ```json theme={null} // First request { "company": { ... }, "max_results": 25 } // Response includes: "cursor": "eyJwYWdl..." // Next page request { "company": { ... }, "cursor": "eyJwYWdl...", "max_results": 25 } ``` When `cursor` is `null` in the response, you've reached the last page. Pagination is limited to 1k pages. *** ## Recommended Workflow Use Company Search as the first step in your ABM pipeline: Use Company Search to build a list of target accounts matching your ICP filters. The `linkedin_url` field in the response is your key for all downstream enrichment. Pass each `linkedin_url` to the [Waterfall ICP Search](/guide/concepts/waterfall-logic) to find the right contacts. Enrich contacts with verified emails and sync to your CRM or outreach tool. # Employee Finder Source: https://docs.blitz-api.ai/guide/concepts/employee-finder # Employee Finder > Search employees at a company by role, seniority, department, and location. With pagination.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**API Reference**: [`Employee Finder` endpoint](/api-reference/people-search/employee-finder) — full request/response schema and try-it console. The **Employee Finder** endpoint (`POST /v2/search/employee-finder`) lets you search for employees within a specific company using structured filters: job level, department, geography, and more. Unlike [Waterfall ICP Search](/guide/concepts/waterfall-logic) which uses a priority cascade to find the *best* contact, Employee Finder returns *all matching employees* with pagination — ideal for broad team mapping and multi-threaded outreach. If you instead need to search people across **many companies at once**, use [Find People](/guide/concepts/find-people). **Paid plans**: Unlimited — included in your flat monthly subscription. *** ## When to Use Employee Finder vs. Other Endpoints | Use Case | Best Endpoint | | :- | :- | | Find the *single best* decision-maker at a company | [Waterfall ICP](/guide/concepts/waterfall-logic) | | Search decision-makers across **many companies** at once | [Find People](/guide/concepts/find-people) | | Map *all* VPs and Directors in the Sales department | **Employee Finder** | | Build a buying committee with strict priority order | [Waterfall ICP](/guide/concepts/waterfall-logic) | | Export the full engineering team for hiring intelligence | **Employee Finder** | | Get paginated results across large companies | **Employee Finder** | *** ## Request Parameters ### Top-Level Parameters | Parameter | Type | Required | Default | Description | | :- | :- | :- | :- | :- | | `company_linkedin_url` | `string` | Yes | — | The full LinkedIn URL of the target company. | | `country_code` | `array` | No | `["WORLD"]` | Filter by country (2-letter ISO codes). Use `["WORLD"]` for global. | | `continent` | `array` | No | — | Filter by continent. See [accepted values](/guide/reference/normalization/geography#continents). | | `sales_region` | `array` | No | — | Filter by sales region. See [accepted values](/guide/reference/normalization/geography#sales-regions). | | `job_level` | `array` | No | — | Filter by seniority level. See [accepted values](/guide/reference/normalization/job-levels#job-levels). | | `job_function` | `array` | No | — | Filter by department/function. See [accepted values](/guide/reference/normalization/job-levels#job-functions). | | `min_connections_count` | `number` | No | `0` | Minimum LinkedIn connections (0–500). Useful to filter out inactive profiles. | | `max_results` | `number` | No | `50` | Results per page. Min: `1`, Max: `50`. | | `page` | `number` | No | `1` | Page number for pagination. Starts at `1`. | All filter values (`job_level`, `job_function`, `sales_region`, `continent`) are **case-sensitive enums**. Passing `"vp"` instead of `"VP"` or `"sales"` instead of `"Sales & Business Development"` returns a [`422`](/guide/reference/errors#validation-errors-422) that names the field and points you to the valid value. Copy-paste from the [Field Normalization reference](/guide/reference/normalization). *** ## Example Request Find all Directors and VPs in Sales & Marketing at OpenAI, in North America: ```json cURL theme={null} theme={null} curl -X POST "https://api.blitz-api.ai/v2/search/employee-finder" \ -H "Content-Type: application/json" \ -H "x-api-key: YOUR_API_KEY" \ -d '{ "company_linkedin_url": "https://www.linkedin.com/company/openai", "job_level": ["VP", "Director"], "job_function": ["Sales & Business Development", "Advertising & Marketing"], "sales_region": ["NORAM"], "max_results": 10, "page": 1 }' ``` ```javascript Node.js theme={null} theme={null} const employees = await client.search.employee_finder({ company_linkedin_url: "https://www.linkedin.com/company/openai", job_level: ["VP", "Director"], job_function: ["Sales & Business Development", "Advertising & Marketing"], sales_region: ["NORAM"], max_results: 10, }); console.log(`Page ${employees.response.page} of ${employees.response.total_pages}`); for (const person of employees.data) { console.log(`${person.full_name} — ${person.headline}`); console.log(` LinkedIn: ${person.linkedin_url}`); } ``` ```python Python theme={null} theme={null} employees = client.search.employee_finder( company_linkedin_url="https://www.linkedin.com/company/openai", job_level=["VP", "Director"], job_function=["Sales & Business Development", "Advertising & Marketing"], sales_region=["NORAM"], max_results=10, ) for person in employees.results: print(f"{person.full_name} — {person.headline}") print(f" LinkedIn: {person.linkedin_url}") ``` *** ## Response Schema The JSON below is the **raw HTTP response**. The SDKs wrap this page and expose its items under a language-specific property — in the examples above, `employees.data` (TypeScript/Node.js) and `employees.results` (Python) refer to the same `results[]` array shown here. See [Page object shape](/sdks/pagination#page-object-shape) for the full mapping. ```json theme={null} theme={null} { "company_linkedin_url": "https://www.linkedin.com/company/openai", "max_results": 10, "results_length": 10, "page": 1, "total_pages": 24, "results": [ { "first_name": "Jane", "last_name": "Doe", "full_name": "Jane Doe", "nickname": null, "civility_title": "Ms", "headline": "VP of Sales | @OpenAI", "about_me": "Experienced sales leader...", "location": { "city": "San Francisco", "state_code": "CA", "country_code": "US", "continent": "North America", "postal_code": null, "street_address": null }, "linkedin_url": "https://www.linkedin.com/in/janedoe", "connections_count": 2500, "profile_picture_url": null, "experiences": [ { "job_title": "VP of Sales", "company_linkedin_url": "https://www.linkedin.com/company/openai", "company_linkedin_id": "88888888", "job_description": "Leading the global sales team...", "job_start_date": "2024-01-15", "job_end_date": null, "job_is_current": true, "job_contract_type": null, "job_work_arrangement": null, "job_location": { "city": "San Francisco", "state_code": "CA", "country_code": "US" } } ], "education": [ { "school_name": "Stanford University", "degree": "MBA", "start_date": "2016-09-01", "end_date": "2018-06-01" } ], "skills": ["Sales Strategy", "B2B", "SaaS"], "certifications": [] } ] } ``` ### Top-Level Response Fields | Field | Type | Description | | :- | :- | :- | | `company_linkedin_url` | `string` | The company queried. | | `max_results` | `number` | The `max_results` value you sent. | | `results_length` | `number` | Number of results on this page. | | `page` | `number` | Current page number. | | `total_pages` | `number` | Total number of pages available. Use to know when to stop paginating. | | `results` | `array` | Array of person profiles. | ### Person Fields (`results[]`) | Field | Type | Description | | :- | :- | :- | | `first_name` | `string \| null` | First name. | | `last_name` | `string \| null` | Last name. | | `full_name` | `string \| null` | Full display name. | | `nickname` | `string \| null` | Nickname / preferred name. | | `civility_title` | `string \| null` | Title (e.g., "Mr", "Ms", "Dr"). | | `headline` | `string \| null` | Built from the first position as ` \| @`, not the free-text profile headline. | | `about_me` | `string \| null` | LinkedIn "About" section text. | | `location` | `object` | Person location: `city`, `state_code`, `country_code`, `continent`, `postal_code`, `street_address`. | | `linkedin_url` | `string` | Person LinkedIn URL. Use this as input for email/phone enrichment. | | `connections_count` | `number \| null` | LinkedIn connections count. | | `profile_picture_url` | `string \| null` | Always `null`. Kept in the response so existing clients do not break. | | `experiences` | `array` | Work history (see below). | | `education` | `array \| null` | Education history (see below). | | `skills` | `array \| null` | List of skills (strings). | | `certifications` | `array \| null` | List of certifications. Each entry has `name`, `authority`, `url`. | ### Experience Fields (`results[].experiences[]`) | Field | Type | Description | | :- | :- | :- | | `company_name` | `string \| null` | Employer name. Prefers the name on the linked LinkedIn company page. | | `job_title` | `string \| null` | Job title. | | `company_linkedin_url` | `string \| null` | Company LinkedIn URL. | | `company_linkedin_id` | `string \| null` | Company LinkedIn numeric ID. | | `company_domain` | `string \| null` | Employer domain. Populated on past positions as well as the current one. | | `job_description` | `string \| null` | Job description text. | | `job_start_date` | `string \| null` | Start date (format: `YYYY-MM-DD`). | | `job_end_date` | `string \| null` | End date (`null` if current role). | | `job_is_current` | `boolean \| null` | Whether this is the current role. | | `job_contract_type` | `string \| null` | Contract type of the role, as listed on the profile. | | `job_work_arrangement` | `string \| null` | Work arrangement of the role, as listed on the profile. | | `job_location` | `object` | Job location: `city`, `state_code`, `country_code`. | ### Education Fields (`results[].education[]`) | Field | Type | Description | | :- | :- | :- | | `school_name` | `string` | Name of the school or university. | | `degree` | `string` | Degree obtained. | | `start_date` | `string` | Start date. | | `end_date` | `string` | End date. | **Key difference from Waterfall ICP**: Employee Finder return person fields **directly** in `results[]`. Waterfall ICP nests them inside `results[].person`. Plan your parsing logic accordingly. *** ## Pagination Employee Finder is page-based, but the SDK handles paging for you — iterate the returned result and it fetches each page on demand. ```javascript theme={null} theme={null} // Stream every matching employee across all pages. for await (const person of client.search.employee_finder({ company_linkedin_url: "https://www.linkedin.com/company/openai", job_level: ["VP", "Director"], max_results: 50, })) { console.log(`${person.full_name} — ${person.headline}`); } ``` Pagination is limited to 200 pages. Maximum to 10k results *** ## Combining with Enrichment Employee Finder returns LinkedIn profile URLs but **not** emails or phone numbers. Chain with enrichment endpoints to complete the data: Use Employee Finder to get `linkedin_url` for each matching person. Pass each `linkedin_url` to `POST /v2/enrichment/email` to get verified work emails. Pass each `linkedin_url` to `POST /v2/enrichment/phone` for direct mobile numbers. Map the enriched payload to your CRM fields and sync. Need to search across *many* companies at once? Use Find People. Need the *single best* contact? Use Waterfall instead. Full list of accepted values for job\_level, job\_function, and sales\_region. # Find People Source: https://docs.blitz-api.ai/guide/concepts/find-people # Find People > Search decision-makers across your entire ICP. Combine company-level filters with person-level filters in a single call.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**API Reference**: [`Find People` endpoint](/api-reference/people-search/find-people) — full request/response schema and try-it console. The **Find People** endpoint (`POST /v2/search/people`) is the most powerful entry point in the People Search family. Instead of being scoped to a single company (like [Employee Finder](/guide/concepts/employee-finder)) or returning a single best contact (like [Waterfall ICP Search](/guide/concepts/waterfall-logic)), Find People runs a **two-stage match**: it first qualifies companies that fit your ICP, then surfaces the people inside them that match your persona criteria. It is the right tool to build large, multi-account prospecting lists in one call — without first having to resolve every company URL. **Paid plans**: Unlimited — included in your flat monthly subscription. *** ## When to Use Find People vs. Other Endpoints | Use Case | Best Endpoint | | :- | :- | | Build a prospecting list across **many companies** matching an ICP | **Find People** | | Map *all* employees inside one specific company | [Employee Finder](/guide/concepts/employee-finder) | | Find the *single best* decision-maker at a known company | [Waterfall ICP](/guide/concepts/waterfall-logic) | | Combine company filters (industry, size, HQ) with persona filters | **Find People** | | Iterate through a long result set with stable pagination | **Find People** (cursor-based) | *** ## How It Works Find People accepts three top-level objects: 1. **`company`** — qualifies the accounts (industry, NAICS/SIC code, employee range, revenue, HQ, type, keywords, founded year, follower count, web traffic, Google ad spend, funding signals — total funding, last round amount/year/type, lead investors — or explicit `linkedin_url` list). 2. **`people`** — qualifies the contacts inside those accounts (job title keywords, job function, job level, location, minimum connections, education). 3. **`max_results`** + **`cursor`** — control how many results come back per call and how you paginate. The engine evaluates the company filter first, then walks the matching companies and returns people that satisfy the person filter — up to `max_results` per call. *** ## Request Parameters ### Top-Level Parameters | Parameter | Type | Required | Default | Description | | :- | :- | :- | :- | :- | | `company` | `object` | No\* | — | Company-level filters. See below. | | `people` | `object` | No\* | — | Person-level filters. See below. | | `max_results` | `number` | No | `10` | Results per page. Min: `1`, Max: `50`. | | `cursor` | `string` | No | `null` | Cursor returned by a previous call. Omit (or pass `null`) for the first call. (Hard limit on the 1,000th page) | \* You should provide at least one of `company` or `people` — otherwise the search is unbounded and will be rejected. ### `company` Filters | Field | Type | Description | | :- | :- | :- | | `linkedin_url` | `array` | Exact LinkedIn company URLs to target. Bypasses other company filters. | | `name.include` | `array` | Keywords that must appear in the company name. | | `name.exclude` | `array` | Keywords to exclude from the company name. | | `industry.include` | `array` | Normalized industry names. Case-sensitive — see [Field Normalization](/guide/reference/normalization/industries). | | `industry.exclude` | `array` | Industries to exclude. | | `type.include` | `array` | LinkedIn company type (`Privately Held`, `Public Company`, `Nonprofit`, `Government Agency`, …). | | `type.exclude` | `array` | Company types to exclude. | | `employee_range` | `array` | LinkedIn employee buckets: `1-10`, `11-50`, `51-200`, `201-500`, `501-1000`, `1001-5000`, `5001-10000`, `10001+`. | | `employee_count.min` | `number` | Minimum employee count (numeric). | | `employee_count.max` | `number` | Maximum employee count (numeric). | | `min_linkedin_followers` | `number` | Minimum number of LinkedIn followers on the company page. | | `revenue.min` | `number` | Minimum annual revenue (USD). `0` = unset. | | `revenue.max` | `number` | Maximum annual revenue (USD). `0` = unset. | | `naics_code.include` | `array` | Exact NAICS codes the company must match (e.g. `"541511"`). | | `naics_code.exclude` | `array` | NAICS codes to exclude. | | `sic_code.include` | `array` | Exact SIC codes the company must match (e.g. `"7372"`). | | `sic_code.exclude` | `array` | SIC codes to exclude. | | `web_traffic.min` | `number` | Minimum estimated monthly web visits. `0` = unset. | | `web_traffic.max` | `number` | Maximum estimated monthly web visits. `0` = unset. | | `ad_spend.min` | `number` | Minimum estimated monthly Google ad spend (USD). `0` = unset. | | `ad_spend.max` | `number` | Maximum estimated monthly Google ad spend (USD). `0` = unset. | | `total_funding.min` | `number` | Minimum total funding raised across all rounds (USD). `0` = unset. | | `total_funding.max` | `number` | Maximum total funding raised across all rounds (USD). `0` = unset. | | `last_funding_amount.min` | `number` | Minimum amount raised in the most recent funding round (USD). `0` = unset. | | `last_funding_amount.max` | `number` | Maximum amount raised in the most recent funding round (USD). `0` = unset. | | `last_funding_year.min` | `number` | Earliest year of the most recent funding round. `0` = unset. | | `last_funding_year.max` | `number` | Latest year of the most recent funding round. `0` = unset. | | `last_funding_type.include` | `array` | Last funding round types to include. Case-sensitive enum — see [Companies → Funding](/guide/reference/normalization/companies#funding). | | `last_funding_type.exclude` | `array` | Last funding round types to exclude. | | `lead_investors.include` | `array` | Keywords matched against lead investor names (e.g. `"Sequoia"`). | | `lead_investors.exclude` | `array` | Lead investor name keywords to exclude. | | `keywords.include` | `array` | Keywords searched across the company description, specialties, NAICS/SIC descriptions, and Crunchbase/G2 categories. Tokens within a phrase must all match in the same field. | | `keywords.exclude` | `array` | Phrases to exclude — companies that match in any of the above fields are filtered out. | | `founded_year.min` | `number` | Earliest founded year. | | `founded_year.max` | `number` | Latest founded year. | | `hq.city.include` | `array` | Keywords matched against the HQ city. | | `hq.city.exclude` | `array` | Keywords to exclude from the HQ city. | | `hq.country_code` | `array` | HQ country (2-letter ISO codes, e.g., `US`, `FR`). | | `hq.continent` | `array` | HQ continent. See [accepted values](/guide/reference/normalization/geography#continents). | | `hq.sales_region` | `array` | HQ sales region: `NORAM`, `LATAM`, `EMEA`, `APAC`. | ### `people` Filters | Field | Type | Description | | :- | :- | :- | | `job_title.include` | `array` | Keywords that must match the job title. | | `job_title.exclude` | `array` | Keywords to exclude from the job title. | | `include_linkedin_headline` | `boolean` | If `true`, `job_title` keywords also match the LinkedIn headline (not just the formal job title). Default: `false`. | | `job_function` | `array` | Department / function. Case-sensitive enum — see [Field Normalization](/guide/reference/normalization/job-levels#job-functions). | | `job_level` | `array` | Seniority: `C-Team`, `VP`, `Director`, `Manager`, `Staff`, `Other`. | | `min_connections` | `number` | Minimum LinkedIn connections (0–500). Useful to filter out inactive profiles. | | `location.city.include` | `array` | Keywords matched against the city where the person is based. | | `location.city.exclude` | `array` | Keywords to exclude from the person's city. | | `location.country_code` | `array` | Person country (2-letter ISO codes). | | `location.continent` | `array` | Person continent. | | `location.sales_region` | `array` | Person sales region: `NORAM`, `LATAM`, `EMEA`, `APAC`. | | `education.include` | `array` | Phrases matched against the person's education entries. Tokens within a phrase must co-occur in the same entry — wrap the year in the phrase (e.g. `"Stanford 2025"`) to correlate school and year. Token order does not matter (`"Stanford CS"` matches `"CS Stanford"`). | | `education.exclude` | `array` | Phrases to exclude — people with an education entry matching one of these phrases are filtered out. | All enum values (`industry`, `type`, `employee_range`, `last_funding_type`, `job_level`, `job_function`, `continent`, `sales_region`) are **case-sensitive**. Passing `"vp"` instead of `"VP"` or `"sales"` instead of `"Sales & Business Development"` returns a [`422`](/guide/reference/errors#validation-errors-422) that names the field and points you to the valid value. Copy-paste from the [Field Normalization reference](/guide/reference/normalization). *** ## Example Request Find VPs and Directors of Sales at IT Services companies between 51 and 500 employees, headquartered in EMEA: ```json cURL theme={null} curl -X POST "https://api.blitz-api.ai/v2/search/people" \ -H "Content-Type: application/json" \ -H "x-api-key: YOUR_API_KEY" \ -d '{ "company": { "industry": { "include": ["IT Services and IT Consulting"] }, "employee_range": ["51-200", "201-500"], "hq": { "sales_region": ["EMEA"] } }, "people": { "job_level": ["VP", "Director"], "job_function": ["Sales & Business Development"], "min_connections": 200 }, "max_results": 25 }' ``` ```javascript Node.js theme={null} const people = await client.search.people({ company: { industry: { include: ["IT Services and IT Consulting"] }, employee_range: ["51-200", "201-500"], hq: { sales_region: ["EMEA"] }, }, people: { job_level: ["VP", "Director"], job_function: ["Sales & Business Development"], min_connections: 200, }, max_results: 25, }); for (const person of people.data) { console.log(`${person.full_name} — ${person.headline}`); console.log(` LinkedIn: ${person.linkedin_url}`); } ``` ```python Python theme={null} people = client.search.people( company={ "industry": {"include": ["IT Services and IT Consulting"]}, "employee_range": ["51-200", "201-500"], "hq": {"sales_region": ["EMEA"]}, }, people={ "job_level": ["VP", "Director"], "job_function": ["Sales & Business Development"], "min_connections": 200, }, max_results=25, ) for person in people.results: print(f"{person.full_name} — {person.headline}") print(f" LinkedIn: {person.linkedin_url}") ``` *** ## Response Schema The JSON below is the **raw HTTP response**. The SDKs wrap this page and expose its items under a language-specific property — in the examples above, `people.data` (TypeScript/Node.js) and `people.results` (Python) refer to the same `results[]` array shown here. See [Page object shape](/sdks/pagination#page-object-shape) for the full mapping. ```json theme={null} { "total_results": 100, "results_length": 25, "max_results": 25, "cursor": "eyJvZmZzZXQiOjI1fQ==", "results": [ { "first_name": "Jane", "last_name": "Doe", "full_name": "Jane Doe", "nickname": null, "civility_title": null, "headline": "VP of Sales | @Acme", "about_me": "Experienced sales leader...", "location": { "city": "Paris", "state_code": null, "country_code": "FR", "continent": "Europe", "postal_code": null, "street_address": null }, "linkedin_url": "https://www.linkedin.com/in/janedoe", "connections_count": 2500, "profile_picture_url": null, "experiences": [ { "job_title": "VP of Sales", "company_linkedin_url": "https://www.linkedin.com/company/acme", "company_linkedin_id": "c51425c5-1b38-578d-a700-c5ca850261ae", "job_description": "Leading the EMEA sales team...", "job_start_date": "2024-01-15", "job_end_date": null, "job_is_current": true, "job_contract_type": null, "job_work_arrangement": null, "job_location": { "city": "Paris", "state_code": null, "country_code": "FR" } }, { "job_title": "Sales Director", "company_linkedin_url": "https://www.linkedin.com/company/globex", "company_linkedin_id": "9f31a72b-5c48-51ad-9e02-7b6d43c1af58", "job_description": null, "job_start_date": "2020-04-01", "job_end_date": "2023-12-31", "job_is_current": false, "job_contract_type": null, "job_work_arrangement": null, "job_location": { "city": "Lyon", "state_code": null, "country_code": "FR" } } ], "education": [], "skills": ["Sales Strategy", "B2B", "SaaS"], "certifications": [] } ] } ``` ### Top-Level Response Fields | Field | Type | Description | | | :- | :- | :- | - | | `total_results` | `number` | Total number of people matching the filters across all pages. | | | `results_length` | `number` | Number of results on this page. | | | `max_results` | `number` | The `max_results` value you sent. | | | `cursor` | \`string | null\` | Pass this back as `cursor` to fetch the next page. `null` means there are no more results. | | `results` | `array` | Array of person profiles (same shape as Employee Finder). | | The person object (`results[]`) is identical to [Employee Finder](/guide/concepts/employee-finder#person-fields-results) — same `experiences`, `education`, `skills`, and `certifications` structures. Person fields are returned **directly** in `results[]`, not nested in `.person`. **`experiences[]` carries the whole career.** Find People returns every position a person has held, in profile order, not only the position that matched your filters. Read `job_is_current` to pick out the current role. **Cursor vs. page**: Find People uses **cursor-based** pagination, while Employee Finder uses **page-based** pagination. Cursors are stable even if new profiles are added between calls — you will not see duplicates. *** ## Pagination Find People uses cursor-based pagination. With the SDK you don't manage cursors — iterate the returned page and it fetches each subsequent page for you. ```javascript theme={null} // Stream every match across all pages. for await (const person of client.search.people({ company: { industry: { include: ["IT Services and IT Consulting"] }, hq: { sales_region: ["EMEA"] }, }, people: { job_level: ["VP", "Director"], job_function: ["Sales & Business Development"], }, max_results: 50, })) { console.log(`${person.full_name} — ${person.headline}`); } ``` Pagination is limited to 1k pages. Maximum to 50k results *** ## Combining with Enrichment Find People returns LinkedIn profile URLs but **not** emails or phone numbers. Chain with enrichment endpoints to complete the data: Use Find People to get `linkedin_url` for each matching person across the ICP. Pass each `linkedin_url` to `POST /v2/enrichment/email` to get verified work emails. Pass each `linkedin_url` to `POST /v2/enrichment/phone` for direct mobile numbers. Map the enriched payload to your CRM fields and sync. Need every employee at *one* company? Use Employee Finder. Need the *single best* contact at a known account? Use Waterfall. Want only the company list (no people)? Use Company Search. Accepted values for industry, job\_level, job\_function, sales\_region… # Plans & Pricing Source: https://docs.blitz-api.ai/guide/concepts/pricing-unlimited # Plans & Pricing > Flat-rate unlimited access. No per-request fees, no surprises. Choose the plan that unlocks the APIs you need.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
BlitzAPI is a **flat-rate subscription**. Once subscribed, every endpoint is **unlimited** — no per-request fees, no overage surprises. One fixed monthly price, unlimited data. *** ## Subscription Plans **\$399 / month** For teams that need fresh company + people data, on repeat. **What's included:** * Unlimited Waterfall ICP Search * Unlimited Company Search * Unlimited Company Enrichment * Unlimited Employee Finder * Unlimited Domain → LinkedIn URL * 550M+ contacts * 65M+ companies **\$499 / month** ⭐ Most Popular For teams running cold email at scale — where deliverability matters. **Everything in Unlimited Leads, plus:** * Unlimited Email Enrichment * 65M+ verified emails * 97% email accuracy **\$599 / month** For high-output teams running true multi-channel outreach. **Everything in Unlimited Email, plus:** * Unlimited Phone Enrichment * 45M+ mobile phone numbers * US coverage only *** ## What's Included in Each Plan | API / Endpoint | Unlimited Leads (\$399) | Unlimited Email (\$499) | Unlimited Phone (\$599) | | :- | :-: | :-: | :-: | | **Waterfall ICP Search** | ✅ | ✅ | ✅ | | **Company Search** | ✅ | ✅ | ✅ | | **Company Enrichment** | ✅ | ✅ | ✅ | | **Employee Finder** | ✅ | ✅ | ✅ | | **Find People** | ✅ | ✅ | ✅ | | **Domain → LinkedIn URL** | ✅ | ✅ | ✅ | | **Reverse Lookups** (email, phone) | ✅ | ✅ | ✅ | | **Email Enrichment** (`/enrichment/email`) | ❌ | ✅ | ✅ | | **Phone Enrichment** (`/enrichment/phone`) | ❌ | ❌ | ✅ | *** ## Why Flat-Rate Unlimited No overage fees. Budget a fixed monthly amount and run your pipelines 24/7. Delete data, rerun requests, test new ICP configurations — zero additional cost. Enrich 100 leads or 100,000. The cost is identical. No marginal cost per lead. *** ## Choose Your Plan **Ideal for: ABM, list building, and account-level workflows.** You need to find the right decision-makers at scale and have an existing email enrichment provider (Clay, another waterfall). Use BlitzAPI for precision targeting and company/contact discovery. *Example: Map 50,000 companies to find every VP of Sales.* **Ideal for: Outbound agencies and cold email teams. (Most Popular)** You need to feed your sending tools (Smartlead, Instantly, Lemlist) with thousands of fresh, verified leads daily. *Example: Company Search → Waterfall ICP → Email Enrichment → Send.* **Ideal for: Multi-channel teams and call centers.** Your SDRs cold-call and need direct mobile numbers to bypass gatekeepers. US-based contacts only for phone numbers. *Example: Waterfall ICP → Email + Phone → Multichannel sequence in HubSpot.* *** ## Rate Limits Your requests-per-second (RPS) limit depends on your plan. It applies **per endpoint**: each endpoint has its own budget, so calls to `/enrichment/email` don't use up your budget on `/enrichment/phone`. Your key's exact limit is in the `max_requests_per_seconds` field of `GET /v2/account/key-info`, and in `fair_usage.rate_limit.requests_per_second` on every metered response. Set your client-side rate limiter from that value instead of hardcoding a number, so it stays correct when you change plan. *** ## Free Trial Every new account receives **1,000 free records** to test the API before subscribing. Records are consumed per result returned on trial accounts only. Paid plans are flat-rate and unlimited, subject to the [Fair Use Policy](/guide/reference/fair-use-policy). # Our Standard for Quality Source: https://docs.blitz-api.ai/guide/concepts/quality # Our Standard for Quality > Why we prioritize precision and verification over raw volume.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
In the B2B data market, there is a misconception that "more is better." At BlitzAPI, we have a different vision: **Data is a liability unless it is verified.** While traditional providers compete on the size of their database (often selling you contacts who left 6 months ago), we compete on the **precision of the signal**. We are not just a data provider; we are a **Verification Engine**. Top Quality B2B Data - BlitzAPI *** ## 🛡️ The "Zero-Guesswork" Philosophy Many tools use "pattern matching" to generate emails (e.g., trying `firstname.lastname@company.com` and hoping it works). This is dangerous for your domain reputation. **We do not guess.** Our infrastructure relies on a **Deterministic Approach**. We only deliver a contact point when we have cross-referenced multiple signals confirming that: 1. The person is **currently** active in this role. 2. The email address accepts messages **today**. > "We would rather return 'Not Found' than deliver a risky lead. Your sender reputation is our priority." *** ## The 30-Day Hygiene Loop B2B data decays at a rate of roughly 3-5% per month. People change jobs, domains expire, and servers change security rules. To combat this entropy, BlitzAPI runs a continuous, autonomous hygiene process: We do not let data sit stale. Our verified emails are re-tested against mail servers **at least once every 30 days**. We go beyond basic syntax checks. We perform deep SMTP handshakes to validate even the most difficult "Catch-All" domains. If a contact fails our internal check, they are immediately removed from our live circulation. You never pay for our "cleaning" process; you only see the result. *** ## The 3-Layer Verification Model When you request data from BlitzAPI, you aren't just querying a table. You are triggering a complex verification workflow that happens in milliseconds. **Is this person real?** We verify the digital footprint on professional networks to confirm the current Job Title and Company. If the person has moved, we detect it. **Is this contact info correct?** We match the identity against multiple compliant data touchpoints to find associated contact information. **Is it safe to send?** The final gate. We verify that the email address is valid and deliverable right now. *** ## Coverage & Accuracy | Data Type | Volume | Coverage | Notes | | :- | :- | :- | :- | | **Contacts (LinkedIn)** | 550M+ | Global | All contacts tied to LinkedIn profiles | | **Verified Emails** | 65M+ | Global | **97% accuracy**. Real emails only — no pattern guessing. | | **Phone Numbers** | 45M+ | **United States only** | \~90-95% mobile numbers. No international phone coverage. | | **Companies** | 65M+ | Global | Full LinkedIn company dataset | | **Job Postings** | 100M+ | Global | Live postings, searchable via the Job Search endpoints | **Phone enrichment is US-only.** If you need phone numbers for contacts outside the United States, BlitzAPI cannot provide them. *** ## Why this enables Automation High-quality data is the fuel for modern Growth Engineering. Because our error rate is exceptionally low, you can confidently remove manual review steps from your pipeline. * **Trust your Automations**: Plug BlitzAPI directly into your CRM or cold email tools (Smartlead, HubSpot). * **Protect your Domain**: Keep your bounce rates low to ensure your emails actually land in the Primary Inbox. # Waterfall Logic Source: https://docs.blitz-api.ai/guide/concepts/waterfall-logic # Waterfall Logic > Smart Lead Routing: Prioritize quality over quantity.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**API Reference**: [`Waterfall ICP (Keyword)` endpoint](/api-reference/people-search/waterfall-icp-search) — full request/response schema and try-it console. In modern B2B growth, **more leads is not the goal. Better leads are.** The **Waterfall ICP** engine (`POST /v2/search/waterfall-icp-keyword`) is designed to solve one specific problem: **Finding the best decision-makers** at a target company, in your order of preference, without manual sorting. Waterfall ICP - BlitzAPI ## The "Smart Routing" Concept Most APIs return a list of 50 employees and leave you to filter them. BlitzAPI works differently. You define a **Hierarchy of Preference** (a Cascade), and our engine executes a sequential search logic. It first looks for your "Dream Contact." Every person it finds takes one of the `max_results` slots. If the slots are not full, it moves to your "Plan B" and fills the slots that are left, and so on down the cascade. **"I want the CMO."** The API scans the company for tier 1 matches. Each match takes a slot, and tier 1 people always come first in the results. If tier 1 alone fills `max_results`, the search stops here. **"Then, if there are slots left, add the Marketing Manager."** If tier 1 found fewer people than `max_results`, the engine runs the second level of your cascade and fills the remaining slots. Someone already found in an earlier tier is not returned twice. **"And if there are still slots left, add the CEO."** The same rule applies to every tier that follows. The search ends when `max_results` is full or when there are no tiers left, so the founder can still make sure you don't leave the account empty-handed. **Example:** with `max_results: 5`, if tier 1 finds 1 person, you get that person plus up to 4 people from tier 2 and the tiers after it. If you only want the single best match, set `max_results: 1`. *** ## Real-World Example: The "Marketing First" Strategy Let's look at a complex query. Here, we want to target **Welcome to the Jungle**, but we have a very specific preference order. **The Strategy:** 1. **Tier 1**: Get the **Marketing Director/CMO** (Global). 2. **Tier 2**: If there are slots left, add a **Growth Manager** (Global). 3. **Tier 3**: If there are still slots left, add a **Brand/Comms Director** (Global). 4. **Tier 4**: Then try a broader keyword search in **North America only**. 5. **Tier 5**: Finally, add the **CEO**. ```json theme={null} theme={null} { "company_linkedin_url": "https://www.linkedin.com/company/wttj-fr", "cascade": [ { "include_title": ["Marketing Director", "Head Marketing", "Chief Marketing Officer"], "exclude_title": ["assistant", "intern", "product", "junior"], "location": ["WORLD"], "include_headline_search": false }, { "include_title": ["Marketing Manager", "Head Growth", "Growth manager"], "exclude_title": ["junior", "assistant", "intern", "hacker"], "location": ["WORLD"], "include_headline_search": false }, { "include_title": ["Communication Director", "Brand Director", "Content Director"], "exclude_title": ["junior", "assistant", "intern", "UX", "UI", "Design"], "location": ["WORLD"], "include_headline_search": false }, { "include_title": ["Communication", "marketing", "growth", "brand"], "exclude_title": ["junior", "assistant", "intern", "product"], "location": ["US", "CA"], "include_headline_search": true }, { "include_title": ["CEO", "founder", "cofounder", "owner", "General Director"], "exclude_title": ["junior", "assistant", "intern"], "location": ["WORLD"], "include_headline_search": false } ], "max_results": 10 } ``` ### Why this query is powerful * **Precision**: By using `exclude_title`, we focus the results on senior profiles and avoid matching interns or assistants who aren't decision-makers. * **Flexibility**: In step 4, we switch `include_headline_search` to `true`. This allows us to catch people whose LinkedIn headline says "Growth advisor for B2B SaaS", even if their job title is just "Consultant". Keywords match whole words, so the same headline written as "Helping companies grow" would **not** match `growth`. * **Safety Net**: The final step ensures that if the Marketing team is invisible, we still capture the CEO to start a top-down conversation. *** ## Endpoint **`POST /v2/search/waterfall-icp-keyword`** Queries BlitzAPI's proprietary dataset to deliver results instantly. * **Paid plans**: Unlimited * **Latency**: \< 600ms *** ## Request Parameters ### Top-Level Parameters | Parameter | Type | Required | Description | | :- | :- | :- | :- | | `company_linkedin_url` | `string` | Yes | The full LinkedIn URL of the target company (e.g., `"https://www.linkedin.com/company/openai"`). | | `cascade` | `array` | Yes | Ordered array of search tiers (**1 to 10 tiers**). The engine fills `max_results` starting from the first tier, and moves to the next tier while slots are left. | | `max_results` | `integer` | No | Maximum number of people to return across all tiers. Default: `10`. Max: `100`. | | `profile_min_connections` | `number` | No | Minimum number of LinkedIn connections a profile must have to be returned. Default: `0`. | ### Cascade Object Parameters (per tier) | Parameter | Type | Required | Description | | :- | :- | :- | :- | | `include_title` | `array` | Yes | Job title phrases to match (e.g., `["CEO", "CTO"]`). 1 to 50 phrases. Keyword matching: all words of a phrase must be in the title, in any order, as whole words. `"VP Sales"` matches `"VP of Sales"` and `"Sales VP"`. See [Keyword Filters](/guide/reference/normalization/filters). | | `exclude_title` | `array` | No | Title phrases to exclude, with the same matching rules. Use to filter out `["Assistant", "Intern", "Junior"]`. Up to 50 phrases. Also checked against the headline when `include_headline_search` is `true`. | | `location` | `array` | No | LinkedIn Country Codes (e.g., `["US", "FR"]`) of the **person**, not the company HQ. Use `["WORLD"]` or an empty list for no filter. Up to 50 values. Default: `["WORLD"]`. | | `include_headline_search` | `boolean` | No | If `true`, keywords also match against the person's LinkedIn **headline**, not just their formal job title. The "About" section is not searched. Default: `false`. | **Country Codes**: Use 2-letter ISO codes as used by LinkedIn (e.g., `US`, `GB`, `FR`). See the [Country Codes reference](/guide/reference/appendix#country-codes-linkedin) for the full list. ### Matching Rules * **Current roles only.** The waterfall only returns people who hold a **current** role at the target company. With `include_headline_search: true`, the headline can match, but the person must still work at the company now. * **Keywords, not substrings.** Each phrase in `include_title` and `exclude_title` follows the [Keyword Filters](/guide/reference/normalization/filters) rules: every word must appear, in any order, as a whole word. There is no stemming, no synonym and no abbreviation expansion, so `"Demand Gen"` does not match `"Demand Generation"`. To cover variants, list each form as its own phrase, for example `["VP Demand Gen", "VP Demand Generation", "Vice President Demand Generation"]`. * **`exclude_title` and the headline.** When `include_headline_search` is `true`, an `exclude_title` phrase that appears in the headline also removes the person, not only one that appears in the job title. * **No level or function filter.** The waterfall has no `job_level` or `job_function` parameter. Seniority comes from the words in `include_title` and from the order of your tiers. To filter the people of one company by level and function, use [Employee Finder](/guide/concepts/employee-finder). *** ## Response Schema A successful request returns a JSON object with the following structure: ```json theme={null} theme={null} { "results_length": 3, "results": [ { "icp": 1, "ranking": 1, "person": { "first_name": "Jane", "last_name": "Doe", "full_name": "Jane Doe", "headline": "VP of Sales | @Acme Corp", "about_me": "Scaling B2B revenue teams...", "location": { "city": "New York", "state_code": "NY", "country_code": "US", "continent": "North America", "postal_code": null, "street_address": null }, "linkedin_url": "https://www.linkedin.com/in/janedoe", "connections_count": 2500, "profile_picture_url": null, "experiences": [ { "job_title": "VP of Sales", "company_linkedin_url": "https://www.linkedin.com/company/acme", "job_start_date": "2023-03-01", "job_end_date": null, "job_is_current": true, "job_contract_type": null, "job_work_arrangement": null } ], "education": [], "skills": ["B2B Sales", "SaaS", "Revenue Operations"], "certifications": [] } }, { "icp": 2, "ranking": 2, "person": { "first_name": "Alice", "last_name": "Martin", "full_name": "Alice Martin", "headline": "Sales Director | @Acme Corp", "linkedin_url": "https://www.linkedin.com/in/alicemartin", "location": { "city": "London", "country_code": "GB", "continent": "Europe" } } } ] } ``` ### Top-Level Fields | Field | Type | Description | | :- | :- | :- | | `results_length` | `integer` | Total number of results returned. `0` if no match found. | | `results` | `array` | Array of matched people, ordered by cascade priority then relevance. | ### Result Fields (`results[]`) | Field | Type | Description | | :- | :- | :- | | `icp` | `integer` | Cascade **tier** that matched this person. `1` = highest priority (Tier 1), `2` = Tier 2, etc. | | `ranking` | `integer` | **Overall relevance rank** within the company (1 = most relevant). Use to adapt outreach strategy. | | `person` | `object` | Full person profile. Pass `person.linkedin_url` to enrichment endpoints for email/phone. | ### Person Object (`results[].person`) | Field | Type | Description | | :- | :- | :- | | `first_name` | `string \| null` | First name. | | `last_name` | `string \| null` | Last name. | | `full_name` | `string \| null` | Full display name. | | `headline` | `string \| null` | Built from the first position as ` \| @`. It is **not** the LinkedIn headline that `include_headline_search` matches, so don't look for your matched words here. | | `about_me` | `string \| null` | LinkedIn "About" section. | | `location` | `object` | Location with `city`, `state_code`, `country_code`, `continent`, `postal_code`, `street_address`. | | `linkedin_url` | `string` | Person LinkedIn URL — **use this** as input for `/v2/enrichment/email` and `/v2/enrichment/phone`. | | `connections_count` | `number \| null` | LinkedIn connections count. | | `profile_picture_url` | `string \| null` | Always `null`. Kept in the response so existing clients do not break. | | `experiences` | `array` | Work history. Each entry: `job_title`, `company_linkedin_url`, `job_start_date`, `job_end_date`, `job_is_current`, `job_contract_type`, `job_work_arrangement`, `job_location`. | | `education` | `array` | Education history. Each entry: `school_name`, `degree`, `start_date`, `end_date`. | | `skills` | `array` | List of skills (strings). | | `certifications` | `array` | List of certifications. Each entry: `name`, `authority`, `url`. | **`icp` vs `ranking` — how to use both:** * `icp` tells you *which tier* matched: route ICP 1–2 to your AE team, ICP 3–5 to SDR. * `ranking` tells you *position within the company*: apply multichannel (email+LinkedIn+call) to ranking 1–3, calling-only to 4–10, and nurturing sequences to 11+. *** ## Waterfall vs. the Rest of the People Search Family Waterfall ICP is account-scoped and returns **up to `max_results` people** (default 10, max 100), best tier first. If your need is different, pick the right tool: | Use Case | Best Endpoint | | :- | :- | | Best-fit decision-makers at a **known** company, in your priority order | **Waterfall ICP** (this page) | | Map *all* employees at one specific company | [Employee Finder](/guide/concepts/employee-finder) | | Search decision-makers across **many companies** in one call | [Find People](/guide/concepts/find-people) | | Just the company list (no people) | [Company Search](/guide/concepts/company-search) | Combine company filters and person filters in a single multi-account search. Browse every employee at a single company with paginated results. # Authentication Source: https://docs.blitz-api.ai/guide/getting-started/authentication # Authentication > How to securely authenticate your requests with BlitzAPI.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
BlitzAPI uses API Keys to authenticate requests. You can view and manage your API keys in the [BlitzAPI Dashboard](https://app.blitz-api.ai). ## The `x-api-key` Header Authentication to the API is handled via an HTTP header. Include your API key in every request using the `x-api-key` header. **Security Warning**: Your API keys carry many privileges. **Do not** use your API keys in client-side code (browsers, mobile apps). Always route requests through your own backend server to keep your keys secret. ### Example Request Here is how to set the header in various environments: ```bash cURL theme={null} theme={null} curl "https://api.blitz-api.ai/v2/account/key-info" \ -H "x-api-key: YOUR_API_KEY" ``` ```python Python theme={null} theme={null} from blitz_api import BlitzAPI # Pass the key explicitly, or set BLITZ_API_KEY and call BlitzAPI(). # The SDK sends it in the x-api-key header on every request. client = BlitzAPI(api_key="YOUR_API_KEY") ``` ```ts TypeScript theme={null} theme={null} import { BlitzAPI } from "blitz-api-js"; // Pass the key explicitly, or set BLITZ_API_KEY and call new BlitzAPI(). // The SDK sends it in the x-api-key header on every request. const client = new BlitzAPI({ api_key: "YOUR_API_KEY" }); ``` **Using an AI tool?** The [MCP Server](/guide/integrations/MCP) can sign you in with your Blitz account via OAuth, so there's no key to copy. It also accepts your API key in the same `x-api-key` header. ## Verifying your Key To check if your key is active, use the `GET /v2/account/key-info` endpoint. This is a great way to "health check" your integration before running batch jobs. ```python Python theme={null} theme={null} info = client.account.key_info() print(info.valid, info.records_remaining, info.max_requests_per_seconds) ``` ```ts TypeScript theme={null} theme={null} const info = await client.account.key_info(); console.log(info.valid, info.records_remaining, info.max_requests_per_seconds); ``` **Response:** ```json theme={null} theme={null} { "valid": true, "id": "key_abc123", "records_remaining": 950, "next_reset_at": "2026-02-12T17:48:25.199Z", "max_requests_per_seconds": 10, "allowed_apis": [ "/search/waterfall-icp-keyword", "/enrichment/email", "/enrichment/phone" ], "active_plans": [ { "name": "Unlimited Leads", "status": "active", "started_at": "2026-01-12T17:48:25.200Z" } ] } ``` **Response Fields:** | Field | Type | Description | | :- | :- | :- | | `valid` | `boolean` | `true` if the key is active and can make requests. | | `id` | `string` | Internal identifier for your API key. | | `records_remaining` | `number` or `"unlimited"` | Records left on your plan. Returns the string `"unlimited"` on unlimited plans. | | `next_reset_at` | `string` | ISO 8601 timestamp of when your allowance resets. | | `max_requests_per_seconds` | `integer` | Your plan's rate limit, applied independently per endpoint. Use this value to configure your rate limiter client-side. | | `allowed_apis` | `array` | List of endpoint paths your key is authorized to call. | | `active_plans` | `array` | Your active subscription(s) with name, status, and start date. | ## Errors If authentication fails, the API will return a `401 Unauthorized` error. | **Code** | **Meaning** | **Solution** | | - | - | - | | `401` | **Unauthorized** | Missing or invalid API key. Check that the `x-api-key` header is present and correct. | | `402` | **Payment Required** | Your key is valid, but your account has reached its limit. Upgrade your plan. | | `404` | **Not Found** | The API Key provided does not exist in our system. | For every other status code, including `422` validation errors, see [Errors](/guide/reference/errors). # Quickstart Source: https://docs.blitz-api.ai/guide/getting-started/quickstart # Quickstart > Make your first API request in less than 2 minutes.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
Welcome to BlitzAPI! In this guide, we will perform a simple but powerful task: **finding a verified professional email** from a LinkedIn profile URL. **Prerequisites**: You need an API Key. You can grab one from your [BlitzAPI Dashboard](https://app.blitz-api.ai). BlitzAPI is a standard REST API, so you can use it with any language. For Python or JavaScript/TypeScript, the fastest path is the **official SDK** — it handles auth, retries, rate limiting, and pagination for you. Prefer **cURL** for a quick terminal test, or call the REST API directly from any other language. Skip this step if you're using cURL. ```bash Python theme={null} theme={null} pip install blitz-api-py ``` ```bash Node.js theme={null} theme={null} npm install blitz-api-js ``` See the [SDK guides](/sdks/overview) for the full API surface. We will use the `POST /v2/enrichment/email` endpoint. Replace `YOUR_API_KEY` with your actual key, or set it as the `BLITZ_API_KEY` environment variable (the SDKs read it automatically). ```bash cURL theme={null} theme={null} curl --request POST \ --url https://api.blitz-api.ai/v2/enrichment/email \ --header 'Content-Type: application/json' \ --header 'x-api-key: YOUR_API_KEY' \ --data '{ "person_linkedin_url": "https://www.linkedin.com/in/example-person" }' ``` ```python Python theme={null} theme={null} from blitz_api import BlitzAPI client = BlitzAPI(api_key="YOUR_API_KEY") # or set BLITZ_API_KEY result = client.enrichment.email( person_linkedin_url="https://www.linkedin.com/in/example-person", ) print(result.found, result.email) ``` ```ts Node.js theme={null} theme={null} import { BlitzAPI } from "blitz-api-js"; const client = new BlitzAPI({ api_key: "YOUR_API_KEY" }); // or set BLITZ_API_KEY const result = await client.enrichment.email({ person_linkedin_url: "https://www.linkedin.com/in/example-person", }); console.log(result.found, result.email); ``` You should receive a JSON object containing the verified email and its status. ```json theme={null} theme={null} { "found": true, "email": "jane.doe@acme.com", "all_emails": [ { "email": "jane.doe@acme.com", "job_order_in_profile": 1, "company_linkedin_url": "https://www.linkedin.com/company/acme", "email_domain": "acme.com" } ] } ``` **Response Fields:** | Field | Type | Description | | :- | :- | :- | | `found` | `boolean` | `true` if a verified email was found. `false` if no email exists in the database. | | `email` | `string` | The primary verified work email address. `null` if `found: false`. | | `all_emails` | `array` | All verified email addresses found for this profile (usually 1). | | `all_emails[].email` | `string` | The verified email address. | | `all_emails[].job_order_in_profile` | `integer` | Position of the associated job in the person's LinkedIn profile (1 = current job). | | `all_emails[].company_linkedin_url` | `string` | LinkedIn URL of the company associated with this email. | | `all_emails[].email_domain` | `string` | Domain of the email address. | All paid plans include **unlimited** requests — included in your flat monthly subscription. ## What just happened? 1. **Authentication**: You passed your key via the `x-api-key` header. 2. **Identity Matching**: BlitzAPI matched the LinkedIn profile URL against our verified B2B dataset. 3. **Verification**: We validated email deliverability (SMTP handshake) before returning it. ## Next Steps Now that you have the basics down, explore our more advanced features. Typed Python and TypeScript/JavaScript SDKs with built-in retries, rate limiting, and pagination. Let Claude, Cursor, or any MCP client call Blitz endpoints for you — one-click setup. Source decision-makers across an entire ICP in one call — combine company and person filters. Don't have a profile URL? Find the best contact at a known company by cascade. End-to-end recipe: Find People → enrich → CRM-ready output. Learn how to process thousands of leads efficiently. # MCP Server Source: https://docs.blitz-api.ai/guide/integrations/MCP # MCP Server > Connect your AI tool to Blitz API — it can call every endpoint, read the docs, and use built-in skills, all from one server.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
## What is the Blitz API MCP Server? The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard that lets AI assistants connect directly to external tools and data instead of relying on their training data. The **Blitz API MCP Server** lets your AI assistant work with Blitz data directly. It can find and enrich people and companies, search jobs, look up the documentation when it needs to, and follow built-in skills for common workflows. Setup takes one click: add the server URL to your AI tool, sign in with your Blitz account, and you're connected. No API key to copy and paste. **MCP Server URL** ```text theme={null} theme={null} https://api.blitz-api.ai/mcp ``` *** ## What can it do? The server exposes three things to your AI tool. | Capability | What it gives your AI | | :- | :- | | **API tools** | One tool for every Blitz API endpoint — your AI can search, enrich, and fetch data itself instead of just writing code. | | **Docs access** | Search and read the full Blitz documentation — endpoints, parameters, response schemas, and guides. | | **Built-in skills** | Blitz's own playbooks, served as MCP resources, that teach your AI how to use the server and build GTM workflows. | Tools are named after what they return, so your AI can find the right one quickly: | Tool prefix | What it does | | :- | :- | | `people_*` | Find and enrich people — including `people_employee_finder` and `people_waterfall_icp` | | `company_*` | Find and enrich companies, including TAM and headcount distribution | | `job_*` | Search job postings | | `docs_*` | Search and read the Blitz documentation (start with `docs_search`) | | Account, util & changelog tools | Check your key, use utilities, and read the changelog | | `send_feedback` | Report a bug, request a feature, or send feedback to the Blitz team | Each API tool maps to exactly one [API endpoint](/api-reference), so everything you know about a request's parameters and response applies unchanged. The server is built to keep token usage low. Docs and skills are read on demand rather than loaded up front, and its built-in guidance steers your AI to hand large jobs off to a script instead of pulling big payloads into the conversation. See [Tips for large jobs](#tips-for-large-jobs). *** ## Setup 1. Open [Claude.ai](https://claude.ai) and start a new conversation. 2. Click the **"+"** or attachments button. 3. Select **"Manage Connectors"** and click on **"Add custom Connector"**. 4. Copy / Paste this URL into "Remote MCP server URL": [https://api.blitz-api.ai/mcp](https://api.blitz-api.ai/mcp). 5. Click **Connect** and sign in with your Blitz account. You may need to explicitly enable the connector for each new conversation using the attachments button. Add the server from your terminal: ```bash theme={null} theme={null} claude mcp add --transport http blitz-api https://api.blitz-api.ai/mcp ``` Then run `/mcp` inside Claude Code, select **blitz-api**, and sign in with your Blitz account. Prefer an API key? Pass it as a header instead: ```bash theme={null} theme={null} claude mcp add --transport http blitz-api https://api.blitz-api.ai/mcp \ --header "x-api-key: YOUR_API_KEY" ``` Press `Cmd + Shift + P` (macOS) or `Ctrl + Shift + P` (Windows/Linux) to open the command palette, then search for **"Open MCP Settings"**. In your `mcp.json` file, add: ```json theme={null} theme={null} { "mcpServers": { "blitz-api": { "url": "https://api.blitz-api.ai/mcp" } } } ``` Cursor will prompt you to sign in with your Blitz account. To use an API key instead, add a `headers` block: ```json theme={null} theme={null} { "mcpServers": { "blitz-api": { "url": "https://api.blitz-api.ai/mcp", "headers": { "x-api-key": "YOUR_API_KEY" } } } } ``` In Cursor's Agent chat, ask: `"What tools do you have available?"` — you should see the Blitz `people_*`, `company_*`, `job_*`, and `docs_*` tools listed. Make sure the MCP server shows a **green status indicator** in your MCP settings after adding it. In your project root, create a `.vscode/mcp.json` file (or open it if it already exists): ```json theme={null} theme={null} { "servers": { "blitz-api": { "type": "http", "url": "https://api.blitz-api.ai/mcp" } } } ``` VS Code will prompt you to sign in with your Blitz account. To use an API key, add a `headers` entry with `x-api-key`, and keep the key out of version control. Older versions of Claude Desktop don't support remote MCP servers natively. Use the `mcp-remote` wrapper: ```json theme={null} theme={null} { "mcpServers": { "blitz-api": { "command": "npx", "args": ["-y", "mcp-remote", "https://api.blitz-api.ai/mcp"] } } } ``` Save this in your Claude Desktop config file and restart the application. A browser window opens for you to sign in with your Blitz account. If you use an API key in a config file, treat it like a password. Never commit it to a repository or share it in screenshots. See [Authentication](/guide/getting-started/authentication). *** ## Example Prompts Once connected, try these prompts with your AI tool: ```text theme={null} theme={null} Using Blitz, find the Head of Sales at stripe.com and get their work email. ``` ```text theme={null} theme={null} Find 25 VPs of Marketing at B2B SaaS companies in the US with 50-200 employees. Show name, title, company, and LinkedIn URL in a table. ``` ```text theme={null} theme={null} How many records do I have left on my Blitz plan, and what's my rate limit? ``` ```text theme={null} theme={null} What parameters does the waterfall ICP keyword search accept? Show me a complete example JSON body. ``` ```text theme={null} theme={null} Write a Python script that takes a list of company domains, converts each to a LinkedIn URL, then finds the VP of Sales using Blitz waterfall search. Save the results to a CSV and include retry logic. ``` *** ## Tips for large jobs Tool results come back into your AI's context, so big pulls get expensive quickly. For anything beyond a small lookup: * **Ask for a script, not a giant tool call.** Have your AI use the docs tools to write a Python or JavaScript script that fetches and enriches the data and saves it locally. This keeps large payloads out of the conversation. * **Request only what you need.** Ask for the specific fields and the small page size you actually want. * **Know how pagination works.** Most search tools take `max_results` and a `cursor` that you send back until it is `null`. `people_employee_finder` takes a `page` number instead, and `people_waterfall_icp` returns in one shot. * **Stay under the depth ceiling.** Each search stops at a maximum number of records: 50,000 for people, company, and TAM searches, 10,000 for `people_employee_finder`, and 5,000 for jobs. The last page can look like a clean end, so slice a bigger pull into filters that each stay under the limit. For production pipelines, the Python and TypeScript SDKs handle retries, rate limiting, and auto-pagination for you. *** ## Docs-only server If you only need your AI to read the documentation — no account, no API calls — you can connect to the docs server instead. It needs no sign-in and uses no records. ```text theme={null} theme={null} https://docs.blitz-api.ai/mcp ``` Setup is the same as above with this URL. The main server at `https://api.blitz-api.ai/mcp` already includes docs access through its `docs_*` tools, so you don't need both. *** ## Troubleshooting Some AI tools require you to explicitly enable the connector for each conversation. In Claude, use the attachments button to select the Blitz API connector. In Cursor, make sure the MCP server shows a green status indicator in your MCP settings. Restart your AI tool after adding the MCP configuration. Most clients need a full restart to detect new MCP servers. Verify the URL is exactly `https://api.blitz-api.ai/mcp`. The server didn't receive valid credentials. Complete the sign-in prompt in your AI tool, or send your API key in the `x-api-key` header. Don't put an API key in the `Authorization: Bearer` header — Bearer only accepts OAuth access tokens. Older versions of Claude Desktop don't support remote MCP servers natively. Use the `mcp-remote` wrapper shown in the Claude Desktop tab above. That's expected. The MCP endpoint only accepts requests from MCP clients, so a plain browser visit returns an error even when the server is healthy. Check the connection status in your AI tool's MCP settings instead. Every search has a depth ceiling (see [Tips for large jobs](#tips-for-large-jobs)), and the page that hits it looks like a normal end of results. Split the query into narrower filters — for example by country, industry, or company size — so each one stays under the limit. Check your network connection, restart your AI tool, and try again. If the issue persists, note the time of the request and the error message so you can report it to the Blitz team. # Clay Integration Source: https://docs.blitz-api.ai/guide/integrations/clay # Clay Integration > Enrich thousands of leads using the Clay HTTP API (Sculptor or Manual).
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**Clay** is the ultimate partner for BlitzAPI. By combining our **Unlimited Data** with Clay's spreadsheet interface, you can build massive enrichment waterfalls without writing a single line of code. ## 🚀 The "Sculptor" Method (Fastest) Clay's new **Sculptor** feature allows you to setup the integration simply by copy-pasting our documentation. Go to our [API Reference](/api-reference) or [Quickstart](/guide/getting-started/quickstart) and copy any **cURL** command. *Example:* ```bash theme={null} theme={null} curl -X POST "https://api.blitz-api.ai/v2/search/waterfall-icp-keyword"\ -H "Content-Type: application/json"\ -H "x-api-key: YOUR_KEY"\ -d '{ "company_linkedin_url": "..." }' ``` In your Clay table: 1. Click **Add Enrichment** > **HTTP API**. 2. Look for the **"Paste cURL"** or **"Sculptor"** button. 3. Paste the code. Clay's AI will automatically detect the `company_linkedin_url` (or other parameters) in the code and ask you which column in your table matches that data. Simply select the correct column, and you are ready to run! *** ## ⚙️ Manual Setup (Standard) If you prefer to configure the HTTP node manually, follow these settings. 1. **Method**: `POST` 2. **URL**: `https://api.blitz-api.ai/v2/search/waterfall-icp-keyword` (or other endpoint) 3. **Headers**: * `content-type`: `application/json` * `x-api-key`: `YOUR_API_KEY` 4. **Body**: ```json theme={null} theme={null} { "company_linkedin_url": "https://www.linkedin.com/company/wttj-fr", "cascade": [ { "include_title": ["HRD", "Human Director"], "exclude_title": ["assistant", "intern", "product", "junior"], "location": ["US", "CA"], "include_headline_search": false }, { "include_title": ["HRD", "Human Director"], "exclude_title": ["junior", "assistant", "intern", "hacker"], "location": ["WORLD"], "include_headline_search": false }, { "include_title": ["HR", "Human resources "], "exclude_title": ["junior", "assistant", "intern", "UX", "UI", "Design"], "location": ["US", "CA"], "include_headline_search": false }, { "include_title": ["HR", "Human resources"], "exclude_title": ["junior", "assistant", "intern", "product"], "location": ["US", "CA"], "include_headline_search": true }, { "include_title": ["Talent", "Staff", "Office"], "exclude_title": ["junior", "assistant", "intern"], "location": ["WORLD"], "include_headline_search": false } ], "max_results": 10 } ``` *** ## 🛑 Critical: Rate Limiting To respect BlitzAPI's throughput and ensure stability, you **must** configure the rate limit settings in Clay. Your requests-per-second limit depends on your plan and applies per endpoint; your key's exact limit is in the `max_requests_per_seconds` field of `GET /v2/account/key-info`. In the HTTP Enrichment settings, go to **Rate Limit** and set exactly: | Setting | Value | | :- | :- | | **Max Requests** | **5** | | **Time Period** | **1000** ms | **Strict Requirement**: Failure to set this limit to `1000ms` will result in `429 Too Many Requests` errors during bulk runs. *** ## Popular Clay Payloads Copy-paste these JSON bodies directly into your integration. ### 1. Waterfall Search (Find Decision Maker) *Target: Find Marketing Decision Maker.* ```json theme={null} theme={null} { "company_linkedin_url": "https://www.linkedin.com/company/wttj-fr", "cascade": [ { "include_title": ["Marketing Director", "Head Marketing", "Chief Marketing Officer"], "exclude_title": ["assistant", "intern", "product", "junior"], "location": ["WORLD"], "include_headline_search": false }, { "include_title": ["Marketing Manager", "Head Growth", "Growth manager"], "exclude_title": ["junior", "assistant", "intern", "hacker"], "location": ["WORLD"], "include_headline_search": false }, { "include_title": ["Communication Director", "Brand Director", "Content Director"], "exclude_title": ["junior", "assistant", "intern", "UX", "UI", "Design"], "location": ["WORLD"], "include_headline_search": false }, { "include_title": ["Communication", "marketing", "growth", "brand"], "exclude_title": ["junior", "assistant", "intern", "product"], "location": ["US", "CA"], "include_headline_search": true }, { "include_title": ["CEO", "founder", "cofounder", "owner", "General Director"], "exclude_title": ["junior", "assistant", "intern"], "location": ["WORLD"], "include_headline_search": false } ], "max_results": 10 } ``` ### 2. Find People (ICP Sourcing across many companies) *Target: Build a fresh list of VPs and Directors of Sales at IT Services companies (51–500 employees) headquartered in EMEA.* **Endpoint**: `POST https://api.blitz-api.ai/v2/search/people` ```json theme={null} theme={null} { "company": { "industry": { "include": ["IT Services and IT Consulting"] }, "employee_range": ["51-200", "201-500"], "hq": { "sales_region": ["EMEA"] } }, "people": { "job_level": ["VP", "Director"], "job_function": ["Sales & Business Development"], "min_connections": 200 }, "max_results": 50, "cursor": "{{Previous Cursor Column}}" } ``` In Clay, store the returned `cursor` in a column and feed it back into the next run to paginate. Stop when `cursor` is `null`. See the [ICP List Building recipe](/guide/recipes/icp-list-building) for the full pattern. ### 3. Enrich Email (Find Work Email) *Target: Get verified email from a Profile URL.* ```json theme={null} theme={null} { "person_linkedin_url": "{{Linkedin Profile Column}}" } ``` *** ## Mapping the Output Once the request runs successfully: 1. Hover over the `results` cell in Clay. 2. Click **"Add to Table"**. 3. Select the fields you need (e.g., `email`, `phone`, `person_linkedin_url`). Always map the `icp` field. It tells you which tier of your cascade was matched (`1` = Top Priority / Tier 1), helping you score and route your leads instantly. # Make (Integromat) Integration Source: https://docs.blitz-api.ai/guide/integrations/make # Make (Integromat) Integration > Build powerful enrichment scenarios using the HTTP module in Make.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**Make** (formerly Integromat) allows you to integrate BlitzAPI into thousands of apps (Airtable, Hubspot, Google Sheets) visually. Since BlitzAPI follows standard REST principles, you will use the generic **HTTP** app to interact with our endpoints. ## Standard Configuration You will need the **HTTP** app > **Make a request** module. Create a new scenario and add the HTTP module. * **URL**: Paste your endpoint (e.g., `https://api.blitz-api.ai/v2/search/waterfall-icp-keyword`) * **Method**: `POST` Do not use the "User name/Password" fields. Instead, add a generic Header. * **Item 1**: * **Name**: `x-api-key` * **Value**: `YOUR_BLITZ_API_KEY` * **Item 2** (Optional but recommended): * **Name**: `Content-Type` * **Value**: `application/json` Make offers a key-value interface, but for nested objects like our Waterfall Cascade, you must use **Raw** mode. * **Body type**: `Raw` * **Content type**: `JSON (application/json)` * **Request content**: Paste the JSON recipe below and map your variables (the colorful bubbles) inside the quote marks. *** ## ⚡ Handling Rate Limits Make processes scenarios instantly. If you trigger a run with 500 rows from Google Sheets, Make will fire 500 requests in a split second, triggering a `429 Too Many Requests` error from BlitzAPI. To fix this, you must slow down the execution loop. ### The "Sleep" Tool Solution 1. Click on the **Tools** icon (Purple wrench) at the bottom of your screen. 2. Select **Sleep**. 3. Place this module **immediately after** your HTTP module. 4. Set **Delay** to `1` second. **Result**: Make will wait 1 second between each operation, keeping you safely under your plan's per-endpoint rate limit. *** ## JSON Recipes (Raw Body) Copy these payloads into the **"Request content"** field of your HTTP module. *`Note: Replace {{1.company_url}} with your actual mapped variable from previous modules.`* ### Scenario A: The Sales Leader *Logic: Find the CRO or VP Sales. If not available, fallback to a Director level.* ```json theme={null} theme={null} { "company_linkedin_url": "{{1.company_linkedin_url}}", "cascade": [ { "include_title": ["Chief Revenue Officer", "CRO", "VP Sales"], "location": ["US", "GB"], "include_headline_search": false }, { "include_title": ["Head of Sales", "Sales Director"], "location": ["US", "GB"], "include_headline_search": true } ], "max_results": 1 } ``` ### Scenario B: The Marketing Decision Maker Logic: Prioritize the CMO globally. Fallback to VP or Head of Marketing. ```json theme={null} theme={null} { "company_linkedin_url": "{{1.company_linkedin_url}}", "cascade": [ { "include_title": ["Chief Marketing Officer", "CMO"], "location": ["WORLD"], "include_headline_search": false }, { "include_title": ["VP Marketing", "Head of Marketing"], "exclude_title": ["Assistant", "Intern"], "location": ["WORLD"], "include_headline_search": false } ], "max_results": 1 } ``` ### Scenario C: Find People (ICP-wide search) Target: Source decision-makers across an entire ICP in one HTTP module — combine company filters and person filters. Endpoint: `POST https://api.blitz-api.ai/v2/search/people` ```json theme={null} theme={null} { "company": { "industry": { "include": ["IT Services and IT Consulting"] }, "employee_range": ["51-200", "201-500"], "hq": { "sales_region": ["EMEA"] } }, "people": { "job_level": ["VP", "Director"], "job_function": ["Sales & Business Development"], "min_connections": 200 }, "max_results": 50, "cursor": "{{1.cursor}}" } ``` **Pagination in Make**: wrap the HTTP module in a *Repeater* and store the returned `cursor` in a Data Store (or feed it directly via `{{1.cursor}}`). Stop the loop when the response field `cursor` equals `null`. See the [ICP List Building recipe](/guide/recipes/icp-list-building) for the end-to-end pattern. ### Scenario D: Enrich Email Target: Convert a Profile URL to a Verified Email. Endpoint: `POST https://api.blitz-api.ai/v2/enrichment/email` ```json theme={null} theme={null} { "person_linkedin_url": "{{1.person_linkedin_url}}" } ``` ## Troubleshooting Check your Quotes. In Make's editor, it's easy to accidentally delete a quote mark " when dragging and dropping a variable bubble. Ensure your JSON syntax is valid. Check Content Type. Ensure you explicitly selected JSON (application/json) in the Content type dropdown of the HTTP module. If you leave it blank, the API might not interpret the body correctly. Parse the JSON. The HTTP module returns a raw JSON string/buffer. To use the data in the next step (e.g., update HubSpot), you must place a JSON > Parse JSON module after the HTTP request to convert the string back into mapped variables. # n8n Integration Source: https://docs.blitz-api.ai/guide/integrations/n8n # n8n Integration > Automate your enrichment pipelines using the HTTP Request node in n8n.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**n8n** is the ideal orchestrator for complex BlitzAPI workflows. Its node-based architecture allows you to chain our **Waterfall Search**, **Enrichment**, and **CRM Sync** steps into a single autonomous agent. ## Standard Configuration You will interact with BlitzAPI using the native **HTTP Request** node. To avoid copy-pasting your key in every node, create a reusable credential. 1. Go to **Credentials** > **New** > Search for **"Header Auth"**. 2. **Name**: `x-api-key` 3. **Value**: `YOUR_BLITZ_API_KEY` 4. Save as "BlitzAPI Production". Drag an **HTTP Request** node to your canvas. * **Method**: `POST` * **URL**: `https://api.blitz-api.ai/v2/search/waterfall-icp-keyword` * **Authentication**: Select `Generic Credential Type` -> `Header Auth`. * **Credential**: Select the "BlitzAPI Production" credential you just created. Set **Send Body** to `active` and **Body Content Type** to `JSON`. Use the **Expression Editor** to map your input data (e.g., `{{ $json.company_url }}`) into the JSON structure. *** ## ⚡ Handling Rate Limits (Crucial) n8n executes workflows extremely fast. If you process 1,000 items through a single endpoint without precautions, you will hit BlitzAPI's **per-endpoint rate limit** (set by your plan) immediately, causing `429` errors. To scale safely, you must implement a **Throttling Pattern**. ### The "Split In Batches" Pattern Do not connect the trigger directly to the HTTP Request. Use this structure: 1. **Split In Batches** Node: * Set **Batch Size** to `1` (or `5` maximum). 2. **HTTP Request** (BlitzAPI): * Connect it after the split. 3. **Wait** Node: * Connect it after the HTTP Request. * Set **Amount** to `200` milliseconds. 4. **Loop Back**: * Connect the Wait node back to the input of the "Split In Batches" node. **Why?** This forces n8n to process items sequentially (or in small groups) with a tiny pause, ensuring you never exceed the API throughput capacity. *** ## Waterfall Recipes (Copy-Paste) Here are optimized JSON payloads for common targeting scenarios. ### Scenario A: The Sales Leader *Logic: Find the CRO or VP Sales. If not available, fallback to a Director level.* ```json theme={null} theme={null} { "company_linkedin_url": "{{ $json.company_linkedin_url }}", "cascade": [ { "include_title": ["Chief Revenue Officer", "CRO", "VP Sales"], "location": ["US", "GB"], "include_headline_search": false }, { "include_title": ["Head of Sales", "Sales Director"], "location": ["US", "GB"], "include_headline_search": true } ], "max_results": 1 } ``` ### Scenario B: The Marketing Decision Maker *Logic: Prioritize the CMO globally. Fallback to VP or Head of Marketing.* ```json theme={null} theme={null} { "company_linkedin_url": "{{ $json.company_linkedin_url }}", "cascade": [ { "include_title": ["Chief Marketing Officer", "CMO"], "location": ["WORLD"], "include_headline_search": false }, { "include_title": ["VP Marketing", "Head of Marketing"], "exclude_title": ["Assistant", "Intern"], "location": ["WORLD"], "include_headline_search": false } ], "max_results": 1 } ``` ### Scenario C: The Founder (SMB Targeting) *Logic: Find the Owner or CEO, specifically in France or Germany.* ```json theme={null} theme={null} { "company_linkedin_url": "{{ $json.company_linkedin_url }}", "cascade": [ { "include_title": ["Founder", "Co-Founder", "Owner"], "location": ["FR", "DE"], "include_headline_search": true }, { "include_title": ["CEO", "PDG", "Gerant"], "location": ["FR", "DE"], "include_headline_search": false } ], "max_results": 1 } ``` *** ## Find People in n8n (Cursor Pagination Pattern) [Find People](/guide/concepts/find-people) (`POST /v2/search/people`) lets you source decision-makers across **many companies in one call**. It uses **cursor-based pagination**, which differs from the page-based pattern of Employee Finder — here is the canonical n8n loop. ### Workflow shape 1. **Set node** → initialize `cursor = null`. 2. **HTTP Request node** → call `/v2/search/people` with the body below. 3. **Item Lists (Split Out Items)** → fan out `results[]` for downstream enrichment. 4. **IF node** → check `{{$json.cursor}} !== null`. 5. **Set node** → update `cursor = {{$json.cursor}}` and loop back to step 2. ### Request body ```json theme={null} theme={null} { "company": { "industry": { "include": ["IT Services and IT Consulting"] }, "employee_range": ["51-200", "201-500"], "hq": { "sales_region": ["EMEA"] } }, "people": { "job_level": ["VP", "Director"], "job_function": ["Sales & Business Development"], "min_connections": 200 }, "max_results": 50, "cursor": "={{ $json.cursor }}" } ``` **Cursor vs. page**: do not try to compute pages from `total_results / max_results`. The `cursor` returned by the API is the only safe way to paginate — it's stable even if new profiles are added between calls. Stop the loop when the response field `cursor` equals `null`. *** ## Troubleshooting **Check Expression Mode.** In the Body parameter, ensure you are in **JSON mode** (not Form-Urlencoded). If using expressions like `{{ $json.id }}`, make sure they resolve to valid strings, not objects. **Check n8n Data Structure.** BlitzAPI returns a `results` array for searches. You might need to add an **"Item Lists"** node (operation: *Split Out Items*) after the HTTP Request to flatten the `results` array into separate n8n items. **Check Credential Name.** In your "Header Auth" credential, the name of the header **must** be exactly `x-api-key`. If you named it `api-key` or `Authorization`, it will fail. # Skills Source: https://docs.blitz-api.ai/guide/integrations/skills # Blitz Skills > Drop-in agent skills that teach your AI coding agent to go to market with Blitz API.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
## What are Blitz Skills? [Blitz Skills](https://skills.sh/api-blitz/skills) are small, composable agent skills for going to market with Blitz API — lead-finding scripts, outreach, content, analytics, and lifecycle automation, plus the engineering that powers them. They work with **any model** and any compatible coding agent. They're designed to be easy to adapt: install them, then make them your own. **Skills vs. MCP** — The [MCP Server](/guide/integrations/MCP) lets your AI tool call every Blitz API endpoint directly and read the docs, and it comes with built-in skills. The skills on this page are installable *playbooks* — scripts, prompts, and workflows your coding agent can execute, and that you can adapt. They complement each other; use both. *** ## Quickstart Install in about 30 seconds with the [skills.sh](https://skills.sh) CLI. ```bash theme={null} theme={null} npx skills@latest add api-blitz/skills --skill '*' ``` Pick the skills you want, and select which coding agents to install them on. You're ready to go. Ask your agent to run a GTM motion with Blitz — for example, "build me a lead list of VPs of Sales at Series B SaaS companies." *** ## Available skills Every skill available today lives in the **Blitz** bucket, and the three chain into one workflow — scope the ICP, generate the script, then audit it before you run at scale. Each also works on its own. | Skill | What it does | | :- | :- | | **blitz-gtm-brainstorm** | Interviews you about a go-to-market goal and produces a validated brief (`gtm-brief.yaml`) — the right Blitz endpoint, an enum-checked ICP, an enrichment plan, and a volume estimate. | | **blitz-create-script** | Turns that brief into a runnable script on the official Blitz SDK (`blitz-api-py` / `blitz-api-js`) — installs dependencies, handles pagination, and adds API-key safety and error handling. | | **blitz-reviewer** | Audits an existing Blitz integration before you run it — checks MCP, SDK, and skill versions, scans your code for wrong methods and case-sensitive enum typos, and reports your key's rate limit and record balance. | Starting a new motion? Run them in order — **brainstorm** to scope the ICP, **create-script** to build it, **reviewer** to preflight before you scale. The collection also ships two buckets that are still growing: * **GTM** — general go-to-market work: outreach, content, analytics, and lifecycle automation. * **Productivity** — general workflow tools, not GTM-specific. *** ## Learn more See every available skill and what it does. Read, fork, and adapt the skills — they're meant to be hacked on. # CRM Hygiene Playbook Source: https://docs.blitz-api.ai/guide/recipes/crm-hygiene # CRM Hygiene Playbook > Dynamic enrichment and automated cleaning workflows.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
Data decay is inevitable, but manual cleaning is obsolete. With BlitzAPI's **Unlimited Model**, RevOps teams can shift from "Annual Cleaning" to **"Continuous Hygiene"**. Instead of buying static lists, you can build **Dynamic Playbooks** that trigger exactly when you need them. *** ## Playbook 1: The "Dynamic Account" Enrichment *(The "Surgical Strike" Approach)* **The Scenario**: A Sales Rep is working a high-priority Account in Salesforce/HubSpot. The account has potential, but the Rep lacks the *right* contacts (e.g., the VP of Sales is missing). **The Solution**: Instead of asking the Rep to go to LinkedIn and manually copy-paste data, you give them an **"Enrich Now" button** in the CRM. The Rep clicks a button in the CRM (via a Webhook/Flow). The CRM account must have either a **Company LinkedIn URL** or a **Company Domain** stored. BlitzAPI requires a **Company LinkedIn URL** as its primary matching key — a domain alone is not a reliable identifier. * **If the CRM already stores the LinkedIn URL**: use it directly as `company_linkedin_url`. * **If only a domain is available**: first call `POST /v2/enrichment/domain-to-linkedin` to resolve the domain into a LinkedIn URL, then pass the result to the next step. Send the Company LinkedIn URL to BlitzAPI's **Waterfall ICP** endpoint (`POST /v2/search/waterfall-icp-keyword`). * *Example query*: "Find the VP Sales or CRO in the US for this company." BlitzAPI returns the matched contact's LinkedIn URL and profile. Pass it to the enrichment endpoints to retrieve the **Verified Email** and/or **Phone**. The automation creates the Contact in the CRM and assigns it to the Rep instantly. *** ## Playbook 2: Net-New Sourcing from your ICP *(The "Fill the Funnel" Approach)* **The Scenario**: Cleaning what's already in the CRM is necessary, but it doesn't grow the pipeline. You also need a steady stream of **net-new** decision-makers matching your ICP — without buying static lists. **The Solution**: A scheduled job that runs [Find People](/guide/concepts/find-people) against your ICP definition, diffs the results against existing CRM contacts (by `linkedin_url`), and inserts only the new ones. Store your ICP as a JSON request body (industry + employee\_range + HQ + persona). See the [ICP List Building recipe](/guide/recipes/icp-list-building) for a complete template. A weekly cron in n8n/Make calls `POST /v2/search/people`, paginating with the `cursor` until exhausted. For each returned person, check if `linkedin_url` already exists in your CRM. Skip duplicates. Pass each net-new `linkedin_url` to `/v2/enrichment/email` (and `/v2/enrichment/phone` for US contacts), validate, then create the Contact in the CRM. > **RevOps Insight**: Pair this Net-New Sourcing playbook with Playbook 1 (Dynamic Account Enrichment). One *fills* the funnel from your ICP; the other *deepens* coverage on accounts already in motion. *** ## Scaling with Low-Code (n8n, Make, Clay) The true power of BlitzAPI is unleashed when combined with automation platforms. Because our plans are **Unlimited**, you can run massive loops without worrying about per-request costs. > **RevOps Insight**: With the Unlimited Plan, you can set up a "Weekend Job" in n8n that scans your entire CRM, re-enriches every email, and updates job titles, ensuring your team walks in on Monday to a pristine database. Emails returned by `/v2/enrichment/email` are already verified at source — re-tested against mail servers at least once every 30 days — so no separate validation step is needed. *** ## Ready to build? Start building your dynamic playbooks today. Copy-paste recipes for your favorite automation tools. # ABM Playbook Source: https://docs.blitz-api.ai/guide/recipes/enrichment-workflow # ABM Playbook > Penetrate strategic accounts with surgical precision — from a named-account list to a multi-threaded buying committee.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**No named-account list yet?** This recipe starts from a **known company list**. If you instead want to *generate* the list of decision-makers from an ICP definition (industry + size + persona), use the [ICP List Building recipe](/guide/recipes/icp-list-building) which is built around the [Find People](/guide/concepts/find-people) endpoint. **The Challenge**: You have a list of 500 "Dream Accounts" (ICP) in your CRM. **The Old Way**: Your SDRs spend days manually searching LinkedIn, copying random emails, and hitting "Send" to whoever they find. **The Blitz Way**: Automate the entire breakthrough process. Identify the buying committee, verify their data, and enroll them in sequences---instantly. This playbook demonstrates how to build an **Account Breakthrough Engine** using BlitzAPI. *** ## The Stack * **Orchestrator**: n8n or Make (to glue everything together). * **Data engine**: BlitzAPI (Waterfall ICP + Enrichment). * **Source of truth**: HubSpot / Salesforce (input). * **Execution**: Smartlead / Lemlist (cold email). *** ## The Workflow We will move from a "Target Account List" to "Active Conversations" in up to 5 automated steps. BlitzAPI's **Waterfall ICP** endpoint takes a `company_linkedin_url` as its primary input — not a domain. A LinkedIn URL is the only reliable company identifier in our dataset. See Step 1 for how to handle both cases. Your CRM account record must provide a **Company LinkedIn URL** to run the Waterfall search. * **If the CRM stores the LinkedIn URL directly**: use it as-is — skip to Step 1. * **If only a domain is stored** (e.g., `stripe.com`): call `POST /v2/enrichment/domain-to-linkedin` first to resolve it into a Company LinkedIn URL. ```json theme={null} theme={null} POST /v2/enrichment/domain-to-linkedin { "domain": "stripe.com" } ``` This returns the canonical `company_linkedin_url` to use in the next step. Your workflow pulls the target accounts from your CRM. For each account, you now have a `company_linkedin_url` (either stored directly or resolved in Step 0). We don't just want *any* contact. We want the **Economic Buyer** first, then the **Champion**. Send the `company_linkedin_url` to BlitzAPI with a strict priority hierarchy: 1. **Tier 1**: C-Level & VPs (The Decision Makers). 2. **Tier 2**: Directors (The Champions). 3. **Tier 3**: Managers (The Entry Points). Pass each matched `linkedin_url` to `POST /v2/enrichment/email` (and `/v2/enrichment/phone` for US contacts). Emails are verified at source and re-tested every 30 days — no separate validation step needed. Push data back to the CRM with context tags: * `Tag: Tier 1 - Decision Maker` * `Tag: Tier 2 - Champion` This allows Smartlead/Lemlist to send **different scripts** to the VP (Strategic value) vs. the Manager (Operational pain). *** ## Waterfall Configuration This is the brain of the operation. By setting `max_results: 5`, we ensure we penetrate the account with multiple touchpoints without spamming the entire directory. **Endpoint**: `POST /v2/search/waterfall-icp-keyword` ```json theme={null} theme={null} { "company_linkedin_url": "https://www.linkedin.com/company/target-account", "cascade": [ { "include_title": ["Chief Revenue Officer", "CRO", "VP Sales", "Head of Growth"], "location": ["US", "GB"], "include_headline_search": false }, { "include_title": ["Sales Director", "Director of Business Development"], "location": ["US", "GB"], "include_headline_search": true }, { "include_title": ["Sales Manager", "Account Executive Team Lead"], "location": ["US", "GB"], "include_headline_search": false } ], "max_results": 5 } ``` **Pro Tip**: Notice the `max_results: 5`. BlitzAPI will fill these 5 slots starting from the top of your cascade. If it finds 5 C-Levels, it stops there. If it only finds 1 C-Level, it fills the remaining 4 slots with Directors. **You always get the best possible seniority mix.** *** ## Why the Unlimited Model Enables This Traditional per-call providers make this strategy prohibitively expensive at scale. With BlitzAPI's flat monthly subscription: * **No metering**: run the playbook on 1,000 or 100,000 accounts for the same price. * **Refresh anytime**: re-run quarterly to catch job changes and new hires without watching a meter. * **Multi-thread freely**: pull 5 personas per account instead of 1 to maximize reply rates. See our n8n templates to orchestrate this flow. Prefer spreadsheets? Run this logic inside Clay. # List Building Playbook Source: https://docs.blitz-api.ai/guide/recipes/icp-list-building # List Building Playbook > Build a fresh, enriched prospecting list across your entire ICP — from zero to CRM-ready in one workflow.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
Most "list building" workflows are painful because they require **two passes**: first build a company list (Company Search), then loop over each company to fetch employees (Employee Finder), then enrich each person. **Find People collapses the first two steps into one call.** This recipe shows how to go from a blank ICP definition to a fully-enriched prospecting list ready to push to your CRM or sequencer. *** ## What You'll Build A repeatable pipeline that: 1. Takes a single ICP definition (industry + size + geography + persona). 2. Calls **Find People** with cursor-based pagination to collect every matching decision-maker. 3. Enriches each person with a verified work email (and optionally a US phone). 4. Outputs a clean CSV / CRM payload. *** ## Step 1 — Define the ICP The ICP lives entirely in the Find People request body. Combine **company filters** (who you sell to) with **people filters** (who you talk to inside those companies). ```json theme={null} theme={null} { "company": { "industry": { "include": ["IT Services and IT Consulting", "Software Development"] }, "employee_range": ["51-200", "201-500"], "hq": { "sales_region": ["EMEA"] }, "type": { "include": ["Privately Held"] } }, "people": { "job_level": ["VP", "Director"], "job_function": ["Sales & Business Development", "Advertising & Marketing"], "min_connections": 200 }, "max_results": 50 } ``` Iterate this JSON like you would iterate a SQL query. Loosen one filter at a time (`employee_range`, then `industry`, then `min_connections`) until your `total_results` lands in the right ballpark for your campaign volume. *** ## Step 2 — Paginate with the cursor Find People uses **cursor-based** pagination, but the SDK handles it — iterate (or `collect()`) the returned page and it fetches each subsequent page for you. Each page holds up to `max_results` (max `50`). ```javascript Node.js theme={null} theme={null} async function buildIcpList(icp, maxItems = 1000) { // The SDK paginates automatically; collect() gathers every match into an array. // max_results is only the page size — max_items is the client-side total cap that // actually bounds spend (the API bills 1 record per result returned). return client.search.people({ ...icp, max_results: 50, max_items: maxItems }).collect(); } ``` ```python Python theme={null} theme={null} def build_icp_list(icp, max_items=1000): # The SDK paginates automatically; auto_paging_iter streams every match across pages. # max_results is only the page size — max_items is the client-side total cap that # actually bounds spend (the API bills 1 record per result returned). return list( client.search.people(**icp, max_results=50).auto_paging_iter(max_items=max_items) ) ``` *** ## Step 3 — Enrich emails (and phones) Find People returns LinkedIn profile URLs but no contact points. Pass each `linkedin_url` to the enrichment endpoints. `POST /v2/enrichment/email` with `person_linkedin_url`. Returns a verified email or `found: false`. `POST /v2/enrichment/phone` with `person_linkedin_url`. Skip people whose `location.country_code` is not `US`. Emails returned by `/v2/enrichment/email` are already verified at source — they're re-tested against mail servers at least once every 30 days. You can push them straight to your sequencer without an additional validation step. ```javascript theme={null} theme={null} async function enrichPerson(person) { const email = await client.enrichment.email({ person_linkedin_url: person.linkedin_url, }); const phone = person.location?.country_code === "US" ? await client.enrichment.phone({ person_linkedin_url: person.linkedin_url, }) : null; return { ...person, email: email.email ?? null, phone: phone?.phone ?? null }; } ``` The SDK enforces the per-endpoint rate limit for you (a single client instance stays under your limit on each endpoint) and retries automatically on `429`. Reuse one `client` across your enrichment calls — see [Configuration](/sdks/typescript#configuration). *** ## Step 4 — Output for CRM / Sequencer Map the Find People + enrichment payload to the columns your CRM expects: | CRM Field | Source | | :- | :- | | `first_name` | `person.first_name` | | `last_name` | `person.last_name` | | `title` | `person.experiences[0].job_title` (current role) | | `company` | `person.experiences[0].company_linkedin_url` → enrich later | | `linkedin_url` | `person.linkedin_url` | | `email` | `enrichment.email` | | `phone` | `enrichment.phone` (US only) | | `country` | `person.location.country_code` | | `seniority` | derived from `experiences[0].job_title` | *** ## When to Re-Run Re-run the same ICP definition on a schedule (weekly or monthly) to capture **net-new** decision-makers as people change roles. Diff against your existing CRM by `linkedin_url` to insert only new contacts. For *cleaning* existing CRM contacts (vs. sourcing new ones), use the [CRM Hygiene Playbook](/guide/recipes/crm-hygiene) instead. *** Full filter reference and response schema. Need to penetrate a *named* account list instead? Use the Waterfall recipe. Clean and re-enrich your existing contacts on a schedule. Case-sensitive enums for industry, job level, job function, sales region. # Reference & Standards Source: https://docs.blitz-api.ai/guide/reference/appendix # Reference & Standards > Endpoint index, country codes, data logic, and performance details.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
This section covers technical standards and logic details to help you build reliable integrations with BlitzAPI. ## 📋 Endpoint Index All v2 endpoints at a glance. Base URL: `https://api.blitz-api.ai`. All endpoints use `POST` except `key-info`. | Endpoint | Method | Description | Minimum plan | | :- | :- | :- | :- | | `/v2/account/key-info` | `GET` | Check API key validity and rate limit | Any | | `/v2/search/waterfall-icp-keyword` | `POST` | Find decision-makers via cascade hierarchy (cached data, \<600ms) | Unlimited Leads | | `/v2/search/employee-finder` | `POST` | Search employees at one company by role and seniority level | Unlimited Leads | | `/v2/search/people` | `POST` | Search people across many companies (company + person filters) | Unlimited Leads | | `/v2/search/companies` | `POST` | Find companies by filters (industry, size, location, keywords) | Unlimited Leads | | `/v2/enrichment/email` | `POST` | LinkedIn profile URL → verified work email | Unlimited Email | | `/v2/enrichment/phone` | `POST` | LinkedIn profile URL → phone number (**US only**) | Unlimited Phone Numbers | | `/v2/enrichment/email-to-person` | `POST` | Work email → full person profile | Unlimited Leads | | `/v2/enrichment/phone-to-person` | `POST` | Phone number → full person profile | Unlimited Leads | | `/v2/enrichment/company` | `POST` | Company LinkedIn URL → full company profile | Unlimited Leads | | `/v2/enrichment/domain-to-linkedin` | `POST` | Website domain → Company LinkedIn URL | Unlimited Leads | | `/v2/enrichment/linkedin-to-domain` | `POST` | Company LinkedIn URL → verified email domain | Unlimited Leads | | `/v2/enrichment/company-distribution-by-country` | `POST` | Company LinkedIn URL → employee distribution by country | Unlimited Leads | | `/v2/enrichment/company-distribution-by-department` | `POST` | Company LinkedIn URL → employee distribution by department | Unlimited Leads | | `/v2/utils/current-date` | `POST` | Get current server date/time for a timezone | Any | Search endpoints require a **Company LinkedIn URL** as input (not a domain). If you only have a domain, use `/v2/enrichment/domain-to-linkedin` first. *** ## 🌍 Country Codes (LinkedIn) All BlitzAPI search endpoints use **2-letter country codes** following the ISO 3166-1 alpha-2 standard (consistent with LinkedIn). Using the wrong format (e.g., `USA` instead of `US`) will return 0 results. See the [Field Normalization reference](/guide/reference/normalization/geography#country-codes) for the full list. Use `"WORLD"` to search globally without geographic restriction. | Country | Code | | :- | :- | | **United States** | `US` | | **United Kingdom** | `GB` | | **France** | `FR` | | **Canada** | `CA` | | **Germany** | `DE` | | **Australia** | `AU` | | **India** | `IN` | | **Brazil** | `BR` | | **Singapore** | `SG` | [*For a full list of supported codes, refer to the Microsoft LinkedIn Documentation.*](https://learn.microsoft.com/en-us/linkedin/shared/references/reference-tables/country-codes) *** ## 📧 Email Logic: Matching vs. Guessing A common misconception is that enrichment APIs "guess" emails (permutations like `first.last@domain.com`). **BlitzAPI does not do this.** ### How we work 1. **Identity Matching**: We match the LinkedIn profile against a massive dataset of known, verified identities. 2. **No Permutations**: We only return an email if we have a concrete record of it linked to that specific individual. 3. **Freshness Guarantee**: * We do not serve stale data. * Every email in our database is re-validated **at least once every 30 days**. * If an email bounces during our internal checks, it is immediately removed from the circulation. This approach ensures a significantly lower bounce rate compared to "pattern-matching" tools. *** ## 🚦 Rate Limits & Latency To ensure stability for all users: * **Rate limit**: Your requests-per-second (RPS) limit depends on your plan and applies **per endpoint**. Each endpoint has its own independent budget, so calls to `/enrichment/email` and `/enrichment/phone` don't compete. Use the `max_requests_per_seconds` field from `/v2/account/key-info` to get your exact per-endpoint limit. * **Burst**: Short bursts above the limit may be queued, but sustained overage returns `429 Too Many Requests`. * **Retry on 429**: Wait at least 60 seconds before retrying after a server-side `429`. Client-side rate limiting should prevent this. **Recommended Client Timeouts:** | Endpoint Type | Recommended Timeout | | :- | :- | | Waterfall ICP, Employee Finder, Find People, Company Search | 10 seconds | | Enrichment (email, phone, company) | 10 seconds | **Error Codes:** | Code | Meaning | Solution | | :- | :- | :- | | `400` | Bad Request | The request body is not valid JSON. | | `401` | Unauthorized | Missing or invalid `x-api-key` header. | | `402` | Payment Required | Account limit reached. Upgrade your plan. | | `404` | Not Found | API key does not exist. | | `422` | Unprocessable Entity | A request field is unknown or has an invalid value. The `errors` list names each one. | | `429` | Too Many Requests | Exceeded an endpoint's rate limit. Throttle client-side to your plan's `max_requests_per_seconds`. | | `500` | Internal Server Error | Transient server error. Retry with exponential backoff. | See [Errors](/guide/reference/errors) for the `422` response format. # Errors Source: https://docs.blitz-api.ai/guide/reference/errors HTTP status codes returned by the Blitz API and how to handle them. A 422 lists every invalid or unknown request field with its path and the closest valid field or value, and uses no records. # Errors > Every error returns JSON with `success: false` and a readable `message`. A `422` also lists each invalid field.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
## Status codes | Code | Meaning | What to do | | :- | :- | :- | | `400` | Bad Request | The request body is not valid JSON. Send a JSON object with the header `Content-Type: application/json`. | | `401` | Unauthorized | Missing or invalid `x-api-key` header. | | `402` | Payment Required | Account limit reached. Upgrade your plan. | | `404` | Not Found | API key does not exist. | | `422` | Unprocessable Entity | A request field is unknown or has an invalid value. Fix the fields listed in `errors` and resend. See [below](#validation-errors-422). | | `429` | Too Many Requests | Exceeded an endpoint's rate limit. Throttle client-side to your plan's `max_requests_per_seconds`. | | `500` | Internal Server Error | Transient server error. Retry with exponential backoff. | | `503` | Service Unavailable | The service is temporarily unavailable. Retry with exponential backoff. | Only `429`, `500`, and `503` are worth retrying as-is. A `400` or `422` fails the same way until you change the request. *** ## Validation errors (422) The API checks the request body before it runs the request, so a `422` never uses records. A body is rejected when it contains: * **A field the endpoint does not define**, at any depth. A misspelled filter such as `company.industry.includes` returns a `422` instead of being ignored. * **A value outside an accepted list**, such as an industry, job level, or employee range. These values are case-sensitive: copy them from [Field Normalization](/guide/reference/normalization). * **A wrong type or an out-of-range value**, such as a string for `max_results` or more than 50 items in a filter list. ```json Invalid value theme={null} { "success": false, "message": "Invalid request body. company.industry.include[0]: Invalid value \"Software\". Did you mean \"Computer Software\", \"Software Development\" or \"Embedded Software Products\"?", "errors": [ { "field": "company.industry.include[0]", "message": "Invalid value \"Software\". Did you mean \"Computer Software\", \"Software Development\" or \"Embedded Software Products\"?" } ] } ``` | Field | Type | Description | | :- | :- | :- | | `success` | `boolean` | Always `false`. | | `message` | `string` | One-line summary of the first three errors, for logs. | | `errors` | `array` | One item per problem, up to 20. | | `errors[].field` | `string` | Path to the problem. Dots mark nesting and `[n]` marks an array item, e.g. `company.industry.include[0]`. | | `errors[].message` | `string` | What is wrong. When the input is close to a valid field or value, it suggests the closest match. Otherwise a short list of allowed fields or values is given in full. | For an unknown field, `field` is the object that contains it (`body` for a top-level field) and `message` names the rejected field: ```json Unknown field theme={null} { "success": false, "message": "Invalid request body. company.industry: Unknown field \"includes\". Did you mean \"include\"?", "errors": [ { "field": "company.industry", "message": "Unknown field \"includes\". Did you mean \"include\"?" } ] } ``` Read `errors[].field` to find what to fix, and treat `message` as text for humans: its wording can change. Free-text filters such as `name`, `keywords`, `job_title`, `city`, and `country_code` are not checked against a list. A typo in one of them is not an error: the search runs and returns 0 results. See [Troubleshooting](/guide/reference/normalization#troubleshooting). # Fair Use Policy Source: https://docs.blitz-api.ai/guide/reference/fair-use-policy # Fair Use Policy > All plans, including unlimited plans, are subject to a fair use policy to prevent abuse of our systems.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
BlitzAPI plans are flat-rate and unlimited for normal business use. To keep the platform fast and reliable for everyone, **every plan is subject to a fair use policy**. It exists for one reason: to prevent abuse of our systems. If your workload is legitimately high-volume, contact support before scaling up. We would much rather size a plan with you than throttle you mid-pipeline. *** ## Terms & Conditions The fair use policy is part of our contractual terms. The authoritative version, including our rights and your obligations, lives in the Terms & Conditions. Full legal terms governing your use of BlitzAPI, including the fair use policy. # Companies Source: https://docs.blitz-api.ai/guide/reference/normalization/companies # Companies > Accepted values, code references, and units for the company-level filters in Company Search and Find People — `company.type`, `company.employee_range`, `company.naics_code`, `company.sic_code`, `company.revenue`, `company.web_traffic`, `company.ad_spend`, and the funding filters (`company.total_funding`, `company.last_funding_amount`, `company.last_funding_year`, `company.last_funding_type`, `company.lead_investors`).
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
## Employee Range Used in: **Company Search**, **Find People** (`company.employee_range` filter) | Value | Headcount | | :- | :- | | `"1-10"` | 1-10 employees | | `"11-50"` | 11-50 employees | | `"51-200"` | 51-200 employees | | `"201-500"` | 201-500 employees | | `"501-1000"` | 501-1,000 employees | | `"1001-5000"` | 1,001-5,000 employees | | `"5001-10000"` | 5,001-10,000 employees | | `"10001+"` | More than 10,000 employees | *** ## Company Type Used in: **Company Search**, **Find People** (`company.type.include` and `company.type.exclude` filters). * `"Educational"` * `"Educational Institution"` * `"Government Agency"` * `"Nonprofit"` * `"Partnership"` * `"Privately Held"` * `"Public Company"` * `"Self-Employed"` * `"Self-Owned"` * `"Sole Proprietorship"` *** ## NAICS Code Used in: **Company Search**, **Find People** (`company.naics_code.include` and `company.naics_code.exclude` filters). NAICS (North American Industry Classification System) codes are 2–6 digit strings maintained by the US Census Bureau. Codes are matched **exactly as strings** — a 6-digit query (`"541511"`) will not match a company stored at the 4-digit parent (`"5415"`) or vice versa. Use the most specific code you have. | Example | Industry | | :- | :- | | `"5112"` | Software Publishers | | `"5182"` | Data Processing, Hosting | | `"541511"` | Custom Computer Programming Services | | `"541512"` | Computer Systems Design Services | | `"541613"` | Marketing Consulting Services | Browse the full catalog at [census.gov/naics](https://www.census.gov/naics/). *** ## SIC Code Used in: **Company Search**, **Find People** (`company.sic_code.include` and `company.sic_code.exclude` filters). SIC (Standard Industrial Classification) codes are 4-digit strings — the older US classification still widely used by the SEC and credit databases. Like NAICS, matches are **exact strings** with no implicit prefix expansion. | Example | Industry | | :- | :- | | `"7372"` | Prepackaged Software | | `"7371"` | Computer Programming Services | | `"7389"` | Business Services, NEC | | `"6199"` | Finance Services | | `"5961"` | Catalog, Mail-Order Houses | Browse the full catalog at [osha.gov/sic-manual](https://www.osha.gov/data/sic-manual). *** ## Revenue, Web Traffic, Ad Spend Used in: **Company Search**, **Find People** (`company.revenue`, `company.web_traffic`, `company.ad_spend` filters). These three filters share the same `{ min, max }` shape. Pass `0` for either bound to leave it open — `{ min: 1_000_000, max: 0 }` means "at least 1M, no upper limit". | Filter | Unit | Accepted range | | :- | :- | :- | | `revenue` | USD per year | `0` – `9.01e15` | | `web_traffic` | Monthly visits (estimated) | `0` – `2.15e9` | | `ad_spend` | USD per month on Google Ads (est.) | `0` – `1e12` | `revenue` is matched as a range intersection: a company stored with the band `[5M, 50M]` matches a query of `{ min: 10M, max: 20M }`. `web_traffic` and `ad_spend` are matched as point ranges against the latest known monthly value. Many companies have no public revenue, traffic, or ad-spend signal. Applying these filters narrows results aggressively — combine with a broad `industry` or `naics_code` rather than a strict `linkedin_url` list. *** ## Funding Used in: **Company Search**, **Find People** (`company.total_funding`, `company.last_funding_amount`, `company.last_funding_year`, `company.last_funding_type`, `company.lead_investors` filters). Qualify accounts by their fundraising history. The amount and year filters share the `{ min, max }` range shape — pass `0` on either bound to leave it open. `last_funding_type` and `lead_investors` use the `{ include, exclude }` shape. | Filter | Shape | Unit / Values | | :- | :- | :- | | `total_funding` | `{ min, max }` | Total raised across all rounds, USD. `0` = unset. | | `last_funding_amount` | `{ min, max }` | Amount raised in the most recent round, USD. `0` = unset. | | `last_funding_year` | `{ min, max }` | Calendar year of the most recent round. `0` = unset. | | `last_funding_type` | `{ include, exclude }` | Most recent round type — case-sensitive enum (see below). | | `lead_investors` | `{ include, exclude }` | Keyword search across lead investor names (e.g. `"Sequoia"`). | ### Last Funding Type `last_funding_type.include` and `last_funding_type.exclude` accept these **case-sensitive** values: * `"Series unknown"` * `"Pre seed"` * `"Seed"` * `"Series A"` * `"Series B"` * `"Series C"` * `"Series D"` * `"Series E-J"` * `"Grant"` * `"Angel"` * `"Private equity"` * `"Debt financing"` * `"Non equity assistance"` * `"Post IPO equity"` * `"Undisclosed"` * `"Post IPO debt"` * `"Product crowdfunding"` * `"Equity crowdfunding"` * `"Corporate round"` * `"Convertible note"` * `"Secondary market"` * `"Initial coin offering"` * `"Post IPO secondary"` `last_funding_amount` and `last_funding_type` describe the **most recent** round; `total_funding` is the cumulative amount across **all** rounds. `lead_investors` is a keyword search — `"Sequoia"` matches "Sequoia Capital" and "Sequoia Capital China". Funding signals are sparse for many private companies. Applying these filters narrows results aggressively — combine them with a broad `industry` or `employee_range` rather than relying on funding alone. # Keyword Filters Source: https://docs.blitz-api.ai/guide/reference/normalization/filters # Keyword Filters > How `include` / `exclude` keyword search works across BlitzAPI Search endpoints, plus the exact-match bracket syntax.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
`.include` and `.exclude` filters are used as keyword search filters. The phrases in one array work as OR filters. Inside one phrase, **all words must appear** in the value, in any order (see [How a phrase matches](#how-a-phrase-matches)). For example, if you want to look for "Director" in the search results, you can use the following filter: ```json theme={null} { "include": ["Director"], "exclude": [] } ``` ```json theme={null} [ "Director", "Director of Sales", "Director of Marketing", "Director of Product", ... ] ``` ```json theme={null} { "include": ["Director", "Manager"], "exclude": ["Sales", "Marketing", "Product"] } ``` Giving: ```json theme={null} [ "Director of IT", "Director of Finance", "Engineering Manager", "Finance Manager", ... ] ``` This will result in the following search: ```mermaid theme={null} graph LR Q[Query] subgraph Includes[Include OR branches] I1[Director] I2[Manager] end E[Exclude on every branch:
Sales, Marketing, Product] Q --> I1 Q --> I2 I1 --> D1[Director of IT] I1 --> D2[Director of Sales] I1 --> D3[Director of Marketing] I1 --> D4[Director of Finance] I2 --> M1[Engineering Manager] I2 --> M2[Sales Manager] I2 --> M3[Marketing Manager] I2 --> M4[Finance Manager] E -. remove .-> D2 E -. remove .-> D3 E -. remove .-> M2 E -. remove .-> M3 classDef excluded fill:#ffecec,stroke:#ff4d4f,color:#a8071a,stroke-width:1px; class D2,D3,M2,M3 excluded; ```
## How a phrase matches A phrase with more than one word is not searched as a fixed string. These rules apply to every `include` / `exclude` value without brackets, for example job titles in [Find People](/guide/concepts/find-people) and [Waterfall ICP](/guide/concepts/waterfall-logic): * **All words must appear.** `"Head Marketing"` needs both `head` and `marketing` in the title. * **The word order is free.** `"Head Marketing"` matches `Marketing Head` as well as `Head of Marketing`. * **Words match as whole words.** `"Demand Gen"` does not match `Demand Generation`, and `"grow"` does not match `growth`. * **Nothing is stemmed or expanded.** There are no synonyms, no abbreviation expansion (`VP` is not `Vice President`) and no stop-word removal, so `of` counts as a word when you write it. * **Case and accents are ignored.** `"Céo"` and `"ceo"` are the same word. * **Hyphens and punctuation split words.** `Co-CEO` is read as `co` + `ceo`, so the phrase `"CEO"` also matches it. * **The phrases in one array are OR'd.** A value matches as soon as one of the phrases matches. | Phrase | Matches | Does not match | | :- | :- | :- | | `"Head Marketing"` | `Head of Marketing`, `Marketing Head`, `Head, Marketing`, `Head of Product Marketing` | `Head of Sales`, `Marketing Manager` | | `"Head of Marketing"` | `Head of Marketing`, `Head of Product Marketing` | `Marketing Head`, `Head, Marketing` (no `of`) | | `"Demand Gen"` | `Demand Gen Manager`, `VP Demand Gen` | `Demand Generation Manager` | | `"VP Sales"` | `VP of Sales`, `Sales VP`, `Senior VP Sales` | `Vice President of Sales`, `SVP Sales` | To cover the variants of a title, list each form as its own phrase, for example `["VP Demand Gen", "VP Demand Generation", "Vice President Demand Generation"]`. Phrases in one array are OR'd, so any of them can match. ## Exact Match Syntax On top of the regular keyword search, you can also use the exact match syntax. Wrap a value in **square brackets** to switch to **exact match**: `"[CEO]"` matches only values whose lowercased, unaccented form equals `"ceo"`. | Value | Behavior | Matches ✅ | Does **not** match ❌ | Case sensitive | Accent sensitive | | :- | :- | :- | :- | :- | :- | | `"CEO"` | Keyword search (default) | `CEO`, `Co ceo`, `ceo Office` | — | No | No | | `"[CEO]"` | Exact (case- and accent-insensitive) | `CEO`, `ceo`, `Céo` | `Co ceo`, `CEO Office` | No | No | The bracket syntax works in both `include` and `exclude`, and you can mix it in the same array — e.g. `["[CEO]", "Founder"]` means *exact `"ceo"` OR keyword `"Founder"`*. # Geography Source: https://docs.blitz-api.ai/guide/reference/normalization/geography # Geography > Sales regions, continents, and country codes (ISO 3166-1 alpha-2) for `location` filters across BlitzAPI Search endpoints.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
## Sales Regions Used in: **Employee Finder**, **Find People** (`people.location.sales_region` and `company.hq.sales_region`) | Value | Coverage | | :- | :- | | `"NORAM"` | North America (US, Canada) | | `"LATAM"` | Latin America | | `"EMEA"` | Europe, Middle East, and Africa | | `"APAC"` | Asia-Pacific | *** ## Continents Used in: **Employee Finder**, **Find People** (`people.location.continent` and `company.hq.continent`) | Value | | :- | | `"Africa"` | | `"Antarctica"` | | `"Asia"` | | `"Europe"` | | `"North America"` | | `"Oceania"` | | `"South America"` | *** ## Country Codes Used in: **Waterfall ICP** (`location` field), **Employee Finder** (`country_code` field), **Company Search** (`hq.country_code` field). Country codes follow the **ISO 3166-1 alpha-2** standard (consistent with LinkedIn). For **Waterfall ICP Search**, use `"WORLD"` to search globally without geographic restriction. For **Employee Finder**, use `["WORLD"]` as `country_code` default or simply omit the field. For **Company Search** omit the location/hq fields entirely or pass empty arrays. ### Common Codes | Country | Code | | :- | :- | | United States | `US` | | United Kingdom | `GB` | | France | `FR` | | Canada | `CA` | | Germany | `DE` | | Australia | `AU` | | Netherlands | `NL` | | Spain | `ES` | | Italy | `IT` | | India | `IN` | | Brazil | `BR` | | Singapore | `SG` | | Sweden | `SE` | | Switzerland | `CH` | | Belgium | `BE` | | Denmark | `DK` | | Norway | `NO` | | Finland | `FI` | | Poland | `PL` | | Israel | `IL` | | Japan | `JP` | | South Korea | `KR` | | China | `CN` | | Mexico | `MX` | | Argentina | `AR` | | Chile | `CL` | | Colombia | `CO` | | South Africa | `ZA` | | UAE | `AE` | | Saudi Arabia | `SA` | For the complete list of all country codes, refer to the [official ISO 3166-1 standard](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) or the [Microsoft LinkedIn Documentation](https://learn.microsoft.com/en-us/linkedin/shared/references/reference-tables/country-codes). # Field Normalization Source: https://docs.blitz-api.ai/guide/reference/normalization/index # Field Normalization > Accepted values for industry, employee range, job level, job function, company type, sales region, and country codes. All values are case-sensitive.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
BlitzAPI Search endpoints (Company Search, Employee Finder, **Find People**, Waterfall ICP) use **normalized values** for categorical filters. Passing a value outside the accepted list (e.g., `"SaaS"` instead of `"Software Development"`) returns a [`422`](/guide/reference/errors#validation-errors-422) that names the field and, when a valid value is close, suggests it. A `422` uses no records. Free-text filters such as `country_code`, `city`, `job_title`, and `keywords` are not checked against a list, so a wrong value there returns 0 results instead of an error. All enum values are **case-sensitive** and must match exactly. Copy-paste from the linked pages to avoid typos. *** ## Sections This reference is split across the following pages so each is small enough to load fast and easy to copy from: `include` / `exclude` keyword search behavior, exact-match brackets, and the visual diagram of how branches and exclusions combine. The full list of 534 accepted industry values for `company.industry.include` and `company.industry.exclude`. `people.job_level` enum (C-Team, VP, Director, …) and the 22-value `people.job_function` enum. `company.type` and `employee_range` enums, NAICS / SIC code references, units for `revenue`, `web_traffic`, and `ad_spend`, and the funding filters (`last_funding_type` values, `total_funding`, `lead_investors`). Sales regions, continents, and country codes (ISO 3166-1 alpha-2) for `location` filters. Accepted LinkedIn URL formats and what BlitzAPI normalizes for you. *** ## Troubleshooting The most common cause is a wrong value in a free-text filter such as `country_code`, `city`, `job_title`, or `keywords`. These are not checked against a list, so a wrong value returns 0 results instead of an error. The usual one: * **Country code**: `"USA"` is not valid, use `"US"`. `"United Kingdom"` is not valid, use `"GB"`. See [Geography](/guide/reference/normalization/geography#country-codes) for every accepted country code. A value outside an accepted list, or a field the endpoint does not define, returns a [`422`](/guide/reference/errors#validation-errors-422) instead of results. Each item in `errors` gives the `field` to fix and a `message` with the closest valid value. Common causes: * **Industry**: `"Tech"` is not valid, use `"Information Technology and Services"` or `"Computer Software"` or `"Internet"`. * **Employee range**: `"50-200"` is not valid, use `"51-200"`. * **Job level**: `"vp"` is not valid, use `"VP"`. `"C-Level"` is not valid, use `"C-Team"`. * **Job function**: `"Sales"` is not valid, use `"Sales & Business Development"`. * **Sales region**: `"NA"` is not valid, use `"NORAM"`. * **Field name**: `"includes"` is not a field, use `"include"`. All values are case-sensitive. Copy-paste from the linked pages. LinkedIn's industry taxonomy is granular. Try using multiple values in your `industry.include` array to broaden the search. For example, instead of just `"Computer Software"`, also include `"Information Technology and Services"` and `"Internet"`. Check that you're using the right combination of `job_level` and `job_function`. For example, to find senior sales leaders, use `"job_level": ["C-Team", "VP", "Director"]` combined with `"job_function": ["Sales & Business Development"]`. If the request succeeds but returns nothing: * Make sure at least one of `company` or `people` is provided. * Avoid over-filtering: combining a narrow `industry`, a small `employee_range` bucket, **and** a strict `hq.country_code` will quickly empty the result set. * For person geography, set `people.location.country_code` (not `company.hq.country_code`) — those are independent filters. Find People uses **cursor-based** pagination (not page-based). Pass the `cursor` value from the previous response back into the next request and stop when the API returns `cursor: null`. Do not assume `total_results / max_results` — use the cursor as the source of truth. # Industry Source: https://docs.blitz-api.ai/guide/reference/normalization/industries # Industry > The full list of 534 accepted industry values for `company.industry.include` and `company.industry.exclude` filters.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
Used in: **Company Search**, **Find People** (`company.industry.include` and `company.industry.exclude`) Industry values are **case-sensitive** and must match exactly. Copy-paste from this page to avoid typos. * `"Abrasives and Nonmetallic Minerals Manufacturing"` * `"Accessible Architecture and Design"` * `"Accessible Hardware Manufacturing"` * `"Accommodation and Food Services"` * `"Accounting"` * `"Administration of Justice"` * `"Administrative and Support Services"` * `"Advertising Services"` * `"Agricultural Chemical Manufacturing"` * `"Agriculture; Construction; Mining Machinery Manufacturing"` * `"Air; Water; and Waste Program Management"` * `"Airlines and Aviation"` * `"Airlines/Aviation"` * `"Alternative Dispute Resolution"` * `"Alternative Fuel Vehicle Manufacturing"` * `"Alternative Medicine"` * `"Ambulance Services"` * `"Amusement Parks and Arcades"` * `"Animal Feed Manufacturing"` * `"Animation"` * `"Animation and Post-production"` * `"Apparel Manufacturing"` * `"Apparel and Fashion"` * `"Appliances; Electrical; and Electronics Manufacturing"` * `"Architectural and Structural Metal Manufacturing"` * `"Architecture and Planning"` * `"Armed Forces"` * `"Artificial Rubber and Synthetic Fiber Manufacturing"` * `"Artists and Writers"` * `"Arts and Crafts"` * `"Audio and Video Equipment Manufacturing"` * `"Automation Machinery Manufacturing"` * `"Automotive"` * `"Aviation and Aerospace"` * `"Aviation and Aerospace Component Manufacturing"` * `"Baked Goods Manufacturing"` * `"Banking"` * `"Bars; Taverns; and Nightclubs"` * `"Bed-and-Breakfasts; Hostels; Homestays"` * `"Beverage Manufacturing"` * `"Biomass Electric Power Generation"` * `"Biotechnology"` * `"Biotechnology Research"` * `"Blockchain Services"` * `"Blogs"` * `"Boilers; Tanks; and Shipping Container Manufacturing"` * `"Book Publishing"` * `"Book and Periodical Publishing"` * `"Breweries"` * `"Broadcast Media"` * `"Broadcast Media Production and Distribution"` * `"Building Construction"` * `"Building Equipment Contractors"` * `"Building Finishing Contractors"` * `"Building Materials"` * `"Building Structure and Exterior Contractors"` * `"Business Consulting and Services"` * `"Business Content"` * `"Business Intelligence Platforms"` * `"Business Supplies and Equipment"` * `"Cable and Satellite Programming"` * `"Capital Markets"` * `"Caterers"` * `"Chemical Manufacturing"` * `"Chemical Raw Materials Manufacturing"` * `"Chemicals"` * `"Child Day Care Services"` * `"Chiropractors"` * `"Circuses and Magic Shows"` * `"Civic and Social Organization"` * `"Civic and Social Organizations"` * `"Civil Engineering"` * `"Claims Adjusting; Actuarial Services"` * `"Clay and Refractory Products Manufacturing"` * `"Climate Data and Analytics"` * `"Climate Technology Product Manufacturing"` * `"Coal Mining"` * `"Collection Agencies"` * `"Commercial Real Estate"` * `"Commercial and Industrial Equipment Rental"` * `"Commercial and Industrial Machinery Maintenance"` * `"Commercial and Service Industry Machinery Manufacturing"` * `"Communications Equipment Manufacturing"` * `"Community Development and Urban Planning"` * `"Community Services"` * `"Computer Games"` * `"Computer Hardware"` * `"Computer Hardware Manufacturing"` * `"Computer Networking"` * `"Computer Networking Products"` * `"Computer Software"` * `"Computer and Network Security"` * `"Computers and Electronics Manufacturing"` * `"Conservation Programs"` * `"Construction"` * `"Construction Hardware Manufacturing"` * `"Consumer Electronics"` * `"Consumer Goods"` * `"Consumer Goods Rental"` * `"Consumer Services"` * `"Correctional Institutions"` * `"Cosmetics"` * `"Cosmetology and Barber Schools"` * `"Courts of Law"` * `"Credit Intermediation"` * `"Cutlery and Handtool Manufacturing"` * `"Dairy"` * `"Dairy Product Manufacturing"` * `"Dance Companies"` * `"Data Infrastructure and Analytics"` * `"Data Security Software Products"` * `"Death Care Services"` * `"Defense and Space"` * `"Defense and Space Manufacturing"` * `"Dentists"` * `"Design"` * `"Design Services"` * `"Desktop Computing Software Products"` * `"Digital Accessibility Services"` * `"Distilleries"` * `"E-Learning Providers"` * `"E-learning"` * `"Economic Programs"` * `"Education"` * `"Education Administration Programs"` * `"Education Management"` * `"Electric Lighting Equipment Manufacturing"` * `"Electric Power Generation"` * `"Electric Power Transmission; Control; and Distribution"` * `"Electrical Equipment Manufacturing"` * `"Electrical and Electronic Manufacturing"` * `"Electronic and Precision Equipment Maintenance"` * `"Embedded Software Products"` * `"Emergency and Relief Services"` * `"Energy Technology"` * `"Engineering Services"` * `"Engines and Power Transmission Equipment Manufacturing"` * `"Entertainment"` * `"Entertainment Providers"` * `"Environmental Quality Programs"` * `"Environmental Services"` * `"Equipment Rental Services"` * `"Events Services"` * `"Executive Office"` * `"Executive Offices"` * `"Executive Search Services"` * `"Fabricated Metal Products"` * `"Facilities Services"` * `"Family Planning Centers"` * `"Farming"` * `"Farming; Ranching; Forestry"` * `"Fashion Accessories Manufacturing"` * `"Financial Services"` * `"Fine Art"` * `"Fine Arts Schools"` * `"Fire Protection"` * `"Fisheries"` * `"Fishery"` * `"Flight Training"` * `"Food Production"` * `"Food and Beverage Manufacturing"` * `"Food and Beverage Retail"` * `"Food and Beverage Services"` * `"Food and Beverages"` * `"Footwear Manufacturing"` * `"Footwear and Leather Goods Repair"` * `"Forestry and Logging"` * `"Fossil Fuel Electric Power Generation"` * `"Freight and Package Transportation"` * `"Fruit and Vegetable Preserves Manufacturing"` * `"Fuel Cell Manufacturing"` * `"Fundraising"` * `"Funds and Trusts"` * `"Funeral Services"` * `"Furniture"` * `"Furniture and Home Furnishings Manufacturing"` * `"Gambling Facilities and Casinos"` * `"Gambling and Casinos"` * `"Geothermal Electric Power Generation"` * `"Glass Product Manufacturing"` * `"Glass; Ceramics and Concrete"` * `"Glass; Ceramics and Concrete Manufacturing"` * `"Golf Courses and Country Clubs"` * `"Government Administration"` * `"Government Relations"` * `"Government Relations Services"` * `"Graphic Design"` * `"Ground Passenger Transportation"` * `"HVAC and Refrigeration Equipment Manufacturing"` * `"Health and Human Services"` * `"Health; Wellness and Fitness"` * `"Higher Education"` * `"Highway; Street; and Bridge Construction"` * `"Historical Sites"` * `"Holding Companies"` * `"Home Health Care Services"` * `"Horticulture"` * `"Hospital and Health Care"` * `"Hospitality"` * `"Hospitals"` * `"Hospitals and Health Care"` * `"Hotels and Motels"` * `"Household Appliance Manufacturing"` * `"Household Services"` * `"Household and Institutional Furniture Manufacturing"` * `"Housing Programs"` * `"Housing and Community Development"` * `"Human Resources"` * `"Human Resources Services"` * `"Hydroelectric Power Generation"` * `"IT Services and IT Consulting"` * `"IT System Custom Software Development"` * `"IT System Data Services"` * `"IT System Design Services"` * `"IT System Installation and Disposal"` * `"IT System Operations and Maintenance"` * `"IT System Testing and Evaluation"` * `"IT System Training and Support"` * `"Import and Export"` * `"Individual and Family Services"` * `"Industrial Automation"` * `"Industrial Machinery Manufacturing"` * `"Industry Associations"` * `"Information Services"` * `"Information Technology and Services"` * `"Insurance"` * `"Insurance Agencies and Brokerages"` * `"Insurance Carriers"` * `"Insurance and Employee Benefit Funds"` * `"Interior Design"` * `"International Affairs"` * `"International Trade and Development"` * `"Internet"` * `"Internet Marketplace Platforms"` * `"Internet News"` * `"Internet Publishing"` * `"Interurban and Rural Bus Services"` * `"Investment Advice"` * `"Investment Banking"` * `"Investment Management"` * `"Janitorial Services"` * `"Judiciary"` * `"Landscaping Services"` * `"Language Schools"` * `"Laundry and Drycleaning Services"` * `"Law Enforcement"` * `"Law Practice"` * `"Leasing Non-residential Real Estate"` * `"Leasing Residential Real Estate"` * `"Leather Product Manufacturing"` * `"Legal Services"` * `"Legislative Offices"` * `"Leisure; Travel and Tourism"` * `"Libraries"` * `"Lime and Gypsum Products Manufacturing"` * `"Loan Brokers"` * `"Logistics and Supply Chain"` * `"Luxury Goods and Jewelry"` * `"Machinery"` * `"Machinery Manufacturing"` * `"Magnetic and Optical Media Manufacturing"` * `"Management Consulting"` * `"Manufacturing"` * `"Maritime"` * `"Maritime Transportation"` * `"Market Research"` * `"Marketing Services"` * `"Marketing and Advertising"` * `"Mattress and Blinds Manufacturing"` * `"Measuring and Control Instrument Manufacturing"` * `"Meat Products Manufacturing"` * `"Mechanical Or Industrial Engineering"` * `"Media Production"` * `"Media and Telecommunications"` * `"Medical Device"` * `"Medical Equipment Manufacturing"` * `"Medical Practice"` * `"Medical Practices"` * `"Medical and Diagnostic Laboratories"` * `"Mental Health Care"` * `"Metal Ore Mining"` * `"Metal Treatments"` * `"Metal Valve; Ball; and Roller Manufacturing"` * `"Metalworking Machinery Manufacturing"` * `"Military"` * `"Military and International Affairs"` * `"Mining"` * `"Mining and Metals"` * `"Mobile Computing Software Products"` * `"Mobile Food Services"` * `"Mobile Games"` * `"Mobile Gaming Apps"` * `"Motion Pictures and Film"` * `"Motor Vehicle Manufacturing"` * `"Motor Vehicle Parts Manufacturing"` * `"Movies and Sound Recording"` * `"Movies; Videos; and Sound"` * `"Museums"` * `"Museums and Institutions"` * `"Museums; Historical Sites; and Zoos"` * `"Music"` * `"Musicians"` * `"Nanotechnology"` * `"Nanotechnology Research"` * `"Natural Gas Distribution"` * `"Natural Gas Extraction"` * `"Newspaper Publishing"` * `"Newspapers"` * `"Non-profit Organization Management"` * `"Non-profit Organizations"` * `"Nonmetallic Mineral Mining"` * `"Nonresidential Building Construction"` * `"Nuclear Electric Power Generation"` * `"Nursing Homes and Residential Care Facilities"` * `"Office Administration"` * `"Office Furniture and Fixtures Manufacturing"` * `"Oil Extraction"` * `"Oil and Coal Product Manufacturing"` * `"Oil and Energy"` * `"Oil and Gas"` * `"Oil; Gas; and Mining"` * `"Online Audio and Video Media"` * `"Online Media"` * `"Online and Mail Order Retail"` * `"Operations Consulting"` * `"Optometrists"` * `"Other"` * `"Outpatient Care Centers"` * `"Outsourcing and Offshoring Consulting"` * `"Outsourcing/Offshoring"` * `"Package/Freight Delivery"` * `"Packaging and Containers"` * `"Packaging and Containers Manufacturing"` * `"Paint; Coating; and Adhesive Manufacturing"` * `"Paper and Forest Product Manufacturing"` * `"Paper and Forest Products"` * `"Parts Distribution"` * `"Pension Funds"` * `"Performing Arts"` * `"Performing Arts and Spectator Sports"` * `"Periodical Publishing"` * `"Personal Care Product Manufacturing"` * `"Personal Care Services"` * `"Personal and Laundry Services"` * `"Pet Services"` * `"Pharmaceutical Manufacturing"` * `"Pharmaceuticals"` * `"Philanthropic Fundraising Services"` * `"Philanthropy"` * `"Photography"` * `"Physical; Occupational and Speech Therapists"` * `"Physicians"` * `"Pipeline Transportation"` * `"Plastics"` * `"Plastics Manufacturing"` * `"Plastics and Rubber Product Manufacturing"` * `"Political Organization"` * `"Political Organizations"` * `"Postal Services"` * `"Primary Metal Manufacturing"` * `"Primary and Secondary Education"` * `"Primary/Secondary Education"` * `"Printing"` * `"Printing Services"` * `"Professional Organizations"` * `"Professional Services"` * `"Professional Training and Coaching"` * `"Program Development"` * `"Public Assistance Programs"` * `"Public Health"` * `"Public Policy"` * `"Public Policy Offices"` * `"Public Relations and Communications"` * `"Public Relations and Communications Services"` * `"Public Safety"` * `"Public Works"` * `"Publishing"` * `"Racetracks"` * `"Radio and Television Broadcasting"` * `"Rail Transportation"` * `"Railroad Equipment Manufacturing"` * `"Railroad Manufacture"` * `"Ranching"` * `"Ranching and Fisheries"` * `"Real Estate"` * `"Real Estate Agents and Brokers"` * `"Real Estate and Equipment Rental Services"` * `"Recreational Facilities"` * `"Recreational Facilities and Services"` * `"Regenerative Design"` * `"Religious Institutions"` * `"Renewable Energy Equipment Manufacturing"` * `"Renewable Energy Power Generation"` * `"Renewable Energy Semiconductor Manufacturing"` * `"Renewables and Environment"` * `"Repair and Maintenance"` * `"Research"` * `"Research Services"` * `"Residential Building Construction"` * `"Restaurants"` * `"Retail"` * `"Retail Apparel and Fashion"` * `"Retail Appliances; Electrical; and Electronic Equipment"` * `"Retail Art Dealers"` * `"Retail Art Supplies"` * `"Retail Books and Printed News"` * `"Retail Building Materials and Garden Equipment"` * `"Retail Florists"` * `"Retail Furniture and Home Furnishings"` * `"Retail Gasoline"` * `"Retail Groceries"` * `"Retail Health and Personal Care Products"` * `"Retail Luxury Goods and Jewelry"` * `"Retail Motor Vehicles"` * `"Retail Musical Instruments"` * `"Retail Office Equipment"` * `"Retail Office Supplies and Gifts"` * `"Retail Pharmacies"` * `"Retail Recyclable Materials and Used Merchandise"` * `"Reupholstery and Furniture Repair"` * `"Robot Manufacturing"` * `"Robotics Engineering"` * `"Rubber Products Manufacturing"` * `"Satellite Telecommunications"` * `"Savings Institutions"` * `"School and Employee Bus Services"` * `"Seafood Product Manufacturing"` * `"Secretarial Schools"` * `"Securities and Commodity Exchanges"` * `"Security Guards and Patrol Services"` * `"Security Systems Services"` * `"Security and Investigations"` * `"Semiconductor Manufacturing"` * `"Semiconductors"` * `"Services for Renewable Energy"` * `"Services for the Elderly and Disabled"` * `"Sheet Music Publishing"` * `"Shipbuilding"` * `"Shuttles and Special Needs Transportation Services"` * `"Sightseeing Transportation"` * `"Skiing Facilities"` * `"Smart Meter Manufacturing"` * `"Soap and Cleaning Product Manufacturing"` * `"Social Networking Platforms"` * `"Software Development"` * `"Solar Electric Power Generation"` * `"Sound Recording"` * `"Space Research and Technology"` * `"Specialty Trade Contractors"` * `"Spectator Sports"` * `"Sporting Goods"` * `"Sporting Goods Manufacturing"` * `"Sports"` * `"Sports Teams and Clubs"` * `"Sports and Recreation Instruction"` * `"Spring and Wire Product Manufacturing"` * `"Staffing and Recruiting"` * `"Steam and Air-Conditioning Supply"` * `"Strategic Management Services"` * `"Subdivision of Land"` * `"Sugar and Confectionery Product Manufacturing"` * `"Supermarkets"` * `"Surveying and Mapping Services"` * `"Taxi and Limousine Services"` * `"Technical and Vocational Training"` * `"Technology; Information and Internet"` * `"Technology; Information and Media"` * `"Telecommunications"` * `"Telecommunications Carriers"` * `"Telephone Call Centers"` * `"Temporary Help Services"` * `"Textile Manufacturing"` * `"Textiles"` * `"Theater Companies"` * `"Think Tanks"` * `"Tobacco"` * `"Tobacco Manufacturing"` * `"Translation and Localization"` * `"Transportation Equipment Manufacturing"` * `"Transportation Programs"` * `"Transportation/Trucking/Railroad"` * `"Transportation; Logistics; Supply Chain and Storage"` * `"Travel Arrangements"` * `"Truck Transportation"` * `"Trusts and Estates"` * `"Turned Products and Fastener Manufacturing"` * `"Urban Transit Services"` * `"Utilities"` * `"Utilities Administration"` * `"Utility System Construction"` * `"Vehicle Repair and Maintenance"` * `"Venture Capital and Private Equity"` * `"Venture Capital and Private Equity Principals"` * `"Veterinary"` * `"Veterinary Services"` * `"Vocational Rehabilitation Services"` * `"Warehousing"` * `"Warehousing and Storage"` * `"Waste Collection"` * `"Waste Treatment and Disposal"` * `"Water Supply and Irrigation Systems"` * `"Water; Waste; Steam; and Air Conditioning Services"` * `"Wellness and Fitness Services"` * `"Wholesale"` * `"Wholesale Alcoholic Beverages"` * `"Wholesale Apparel and Sewing Supplies"` * `"Wholesale Appliances; Electrical; and Electronics"` * `"Wholesale Building Materials"` * `"Wholesale Chemical and Allied Products"` * `"Wholesale Computer Equipment"` * `"Wholesale Drugs and Sundries"` * `"Wholesale Food and Beverage"` * `"Wholesale Footwear"` * `"Wholesale Furniture and Home Furnishings"` * `"Wholesale Hardware; Plumbing; Heating Equipment"` * `"Wholesale Import and Export"` * `"Wholesale Luxury Goods and Jewelry"` * `"Wholesale Machinery"` * `"Wholesale Metals and Minerals"` * `"Wholesale Motor Vehicles and Parts"` * `"Wholesale Paper Products"` * `"Wholesale Petroleum and Petroleum Products"` * `"Wholesale Photography Equipment and Supplies"` * `"Wholesale Raw Farm Products"` * `"Wholesale Recyclable Materials"` * `"Wind Electric Power Generation"` * `"Wine and Spirits"` * `"Wineries"` * `"Wireless"` * `"Wireless Services"` * `"Women\'s Handbag Manufacturing"` * `"Wood Product Manufacturing"` * `"Writing and Editing"` * `"Zoos and Botanical Gardens"` # Job Levels & Functions Source: https://docs.blitz-api.ai/guide/reference/normalization/job-levels # Job Levels & Functions > Accepted values for `people.job_level` and `people.job_function` filters in Employee Finder and Find People.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
## Job Levels Used in: **Employee Finder**, **Find People** (`people.job_level` filter) | Value | Description | | :- | :- | | `"C-Team"` | C-Level executives (CEO, CTO, CFO, CMO, CRO…) | | `"VP"` | Vice Presidents | | `"Director"` | Directors | | `"Manager"` | Managers | | `"Staff"` | Individual contributors, specialists, analysts | | `"Other"` | Roles that don't fit the above categories | ### How a title gets its level The level comes from the words of the job title. When a title matches several rows below, the first rule that matches wins. `Other` signals and a short list of exceptions (such as `Account Manager` or `Chief of Staff`) are checked first, then `C-Team`, `VP`, `Director`, `Manager` and `Staff`, in that order. A title that matches no rule becomes `Staff`. | Title wording | Level | | :- | :- | | Chief X Officer, CEO, CTO, CFO, CMO, Founder, Co-founder, Owner, President, Chair, Managing Director, Managing Partner, Partner | `"C-Team"` | | VP, Vice President, SVP, EVP, AVP | `"VP"` | | Director, **Head of X**, Board Member, General Director | `"Director"` | | Manager, Team Lead, Lead, Supervisor, General Manager | `"Manager"` | | Account Manager, Relationship Manager, Chief of Staff, Lead Generation, Business Partner, HR Partner | `"Staff"` | | Intern, Student, Trainee, Volunteer, Retired | `"Other"` | For example, `Head of Marketing` is a `"Director"`, and `Vice President of Sales` is a `"VP"`. The level depends on the wording of the title, so an unusual wording can get a lower level. `Marketing Head` (no `of`) matches no rule and becomes `"Staff"`, while `Head of Marketing` is a `"Director"`. When you need exact titles, use title keywords instead of, or together with, `job_level`: `people.job_title` in [Find People](/guide/concepts/find-people) or `include_title` in [Waterfall ICP](/guide/concepts/waterfall-logic). See [Keyword Filters](/guide/reference/normalization/filters) for how they match. *** ## Job Functions Used in: **Employee Finder**, **Find People** (`people.job_function` filter) * `"Advertising & Marketing"` * `"Art, Culture and Creative Professionals"` * `"Construction"` * `"Customer/Client Service"` * `"Education"` * `"Engineering"` * `"Finance & Accounting"` * `"General Business & Management"` * `"Healthcare & Human Services"` * `"Human Resources"` * `"Information Technology"` * `"Legal"` * `"Manufacturing & Production"` * `"Operations"` * `"Other"` * `"Public Administration & Safety"` * `"Purchasing"` * `"Research & Development"` * `"Sales & Business Development"` * `"Science"` * `"Supply Chain & Logistics"` * `"Writing/Editing"` # LinkedIn URLs Source: https://docs.blitz-api.ai/guide/reference/normalization/urls
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
This is a list of all supported LinkedIn URL formats (for fields such as `person_linkedin_url` or `company_linkedin_url`). ## People ### Supported | Format | Example | | :- | :- | | Profile URL | `https://www.linkedin.com/in/john-smith-2a1ba6258` | | Profile URL with LinkedIn's token | `https://www.linkedin.com/in/ACoAAB1cD2eF3gH...` | | Sales Navigator lead URL | `https://www.linkedin.com/sales/lead/ACwAAA...,NAME_SEARCH,VAKJ` | | Sales Navigator people URL | `https://www.linkedin.com/sales/people/ACwAAA...` | | Profile URN | `urn:li:fsd_profile:ACoAAB1cD2eF3gH...` | | Sales Navigator profile URN | `urn:li:fs_salesProfile:(ACwAAA...,NAME_SEARCH,VAKJ)` | | Numeric member URN | `urn:li:member:122138853` | ### Not supported * Sales Navigator profile-view URLs — `/sales/profile/...` * Recruiter URLs — `/talent/profile/...` * Legacy URLs — `/pub/...` and `/public-profile/in/...` * Shortened links — `lnkd.in/...` * `urn:li:person:...` — the public-API person URN is opaque and scoped to a single LinkedIn developer application, so it cannot be resolved to a profile * A bare token on its own (e.g. `ACoAAB...`), without the surrounding `/in/` URL or `urn:li:` wrapper ## Companies ### Supported | Format | Example | | :- | :- | | Company URL (vanity name) | `https://www.linkedin.com/company/microsoft` | | Company URL (numeric ID) | `https://www.linkedin.com/company/1035` | | Sales Navigator company URL | `https://www.linkedin.com/sales/company/90878032` | | Organization URN | `urn:li:organization:1035` | | Company URN | `urn:li:company:1035` | # Welcome to BlitzAPI Source: https://docs.blitz-api.ai/index High-performance B2B data infrastructure for Growth & Revenue teams.
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
**BlitzAPI** provides a programmable interface to access **verified B2B data** from a proprietary LinkedIn-based dataset covering 550M+ contacts worldwide. We enable Growth Engineers and RevOps teams to build automated lead pipelines at scale — no scrapers to maintain, no static databases to manage. BlitzAPI - B2B Data Enrichment *** ## ⚡ Core Logic: Waterfall ICP BlitzAPI's most popular feature is the **Waterfall ICP Search**. It solves a common engineering challenge: mapping a target account to a specific decision-maker without manual filtering. Instead of retrieving a raw list of employees, you define a **priority hierarchy**. The API executes a cascading search until it matches your criteria. You configure a JSON rule: *"First, look for the CEO in the US. If not found, look for the VP of Sales. If not found, look for a Sales Director."* The API queries our proprietary dataset in priority order, stopping as soon as your criteria are matched. You receive the single most relevant decision-maker for that company, ready for enrichment. See how to construct hierarchical queries to maximize relevance. *** ## ♾️ Flat-Rate Unlimited BlitzAPI is a **flat monthly subscription — no per-request fees, no overage surprises**. Choose the plan that unlocks the APIs you need. | Plan | Price | Includes | | :- | :- | :- | | **Unlimited Leads** | \$399/mo | Waterfall ICP, Company Search, Employee Finder, Domain→LinkedIn, and more | | **Unlimited Email** | \$499/mo | Everything above + Email Enrichment (65M+ emails, 97% accuracy) | | **Unlimited Phone Numbers** | \$599/mo | Everything above + Phone Enrichment (US only, 45M+ mobile numbers) | Detailed feature matrix, use case guide, and free trial info. *** ## People Search Family Three complementary endpoints — pick the one that matches your scope. Search decision-makers across **many companies** in one call. Combine company filters (industry, size, HQ) with person filters (job title, level, location). Map **all employees** at one specific company with paginated, filtered results. Get the **single best** decision-maker at a known company via a priority cascade. *** ## What do you want to build? Select the documentation path that matches your technical goal. Get your API Key and run your first enrichment request via the SDK or cURL. Typed Python and TypeScript/JavaScript clients with retries, rate limiting, and auto-pagination. One-click setup for Claude, Cursor, and more. Your AI can call every endpoint, read the docs, and use built-in skills. Generate a fresh prospecting list across hundreds of accounts in one Find People call. Chain Search, Enrichment, and Validation into a single automated pipeline. Interactive OpenAPI documentation to test endpoints and view schema definitions. *** ## Supported Integrations BlitzAPI acts as the data engine behind your existing stack. | Category | Compatible Tools | | :- | :- | | **Orchestrators** | n8n, Make (Integromat), Zapier | | **Data Operations** | Clay, Airtable, Google Sheets | | **CRM & Sales** | HubSpot, Salesforce, Pipedrive | | **Outreach** | Smartlead, Instantly, Lemlist | | **AI Tools** | Claude, GPT, Cursor, Cursor | **Building a custom integration?** Our API is platform-agnostic. As long as your tool can make an HTTP POST request, it works with BlitzAPI. # Official SDKs Source: https://docs.blitz-api.ai/sdks/overview
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
Blitz ships official, fully typed SDKs for **Python** and **TypeScript / JavaScript**. Both wrap the same v2 REST API, use the exact same **snake\_case** field names you see in the [API reference](/api-reference/account/get-api-key-details), and handle the boilerplate for you — client-side rate limiting, retries with backoff on `429`/`5xx`, auto-pagination, and a typed error hierarchy. `pip install blitz-api-py` — sync + async clients, Pydantic v2 models, Python 3.10+. `npm install blitz-api-js` — Zod-validated types, ESM + CJS, Node 20+. ## Install ```bash Python theme={null} theme={null} pip install blitz-api-py # or: uv add blitz-api-py ``` ```bash JavaScript / TypeScript theme={null} theme={null} npm install blitz-api-js # or: pnpm add blitz-api-js / yarn add blitz-api-js ``` ## Why use an SDK? * **Fully typed** — Pydantic v2 (Python) / Zod-inferred types (TS) for every request filter and response field, with editor autocomplete. * **Auto-pagination** — iterate every result across pages without writing a cursor or page loop. * **Resilient by default** — automatic retries with backoff on `429` and `5xx`, plus a typed exception hierarchy. * **Usage metering built in** — every metered response carries a `fair_usage` block: the records the call consumed, the balance left, your rate-limit headroom, and a request id. * **Client-side rate limiting** — a single client instance stays under your per-endpoint request-per-second limit. * **Forward-compatible** — fields the API adds later are preserved, never dropped or rejected. **Never expose your API key in client-side code** (browsers, mobile apps). Both SDKs send the key in the `x-api-key` header — always call Blitz from your backend. See [Authentication](/guide/getting-started/authentication). ## Quickstart Both SDKs read the key from the `BLITZ_API_KEY` environment variable (or take it explicitly), then expose the same seven namespaces. ```python Python theme={null} theme={null} from blitz_api import BlitzAPI with BlitzAPI() as client: # LinkedIn profile URL -> verified work email. email = client.enrichment.email( person_linkedin_url="https://www.linkedin.com/in/example-person", ) if email.found: print(email.email) ``` ```ts TypeScript theme={null} theme={null} import { BlitzAPI } from "blitz-api-js"; const client = new BlitzAPI(); // LinkedIn profile URL -> verified work email. const email = await client.enrichment.email({ person_linkedin_url: "https://www.linkedin.com/in/example-person", }); if (email.found) console.log(email.email); ``` ## Endpoint coverage Every v2 endpoint is a typed method, grouped into seven namespaces. Method names and fields are identical across both SDKs. | Namespace | Method | REST endpoint | API reference | | :- | :- | :- | :- | | `account` | `key_info()` | `GET /v2/account/key-info` | [Get API key details](/api-reference/account/get-api-key-details) | | `search` | `people()` | `POST /v2/search/people` | [Find people](/api-reference/people-search/find-people) | | `search` | `companies()` | `POST /v2/search/companies` | [Company search](/api-reference/company-search/company-search) | | `search` | `employee_finder()` | `POST /v2/search/employee-finder` | [Employee finder](/api-reference/people-search/employee-finder) | | `search` | `waterfall_icp()` | `POST /v2/search/waterfall-icp-keyword` | [Waterfall ICP](/api-reference/people-search/waterfall-icp-search) | | `jobs` | `search()` | `POST /v2/jobs/search` | [Search jobs](/api-reference/job-search/search-jobs) | | `jobs` | `company()` | `POST /v2/jobs/company` | [Search company jobs](/api-reference/job-search/company-jobs) | | `company` | `tam_by_jobs()` | `POST /v2/company/tam-by-jobs` | [TAM By Jobs](/api-reference/company-search/tam-by-jobs) | | `enrichment` | `email()` | `POST /v2/enrichment/email` | [Find work email](/api-reference/people-enrichment/find-work-email) | | `enrichment` | `phone()` | `POST /v2/enrichment/phone` | [Find mobile & direct phone](/api-reference/people-enrichment/find-mobile-&-direct-phone) | | `enrichment` | `email_to_person()` | `POST /v2/enrichment/email-to-person` | [Reverse email lookup](/api-reference/people-enrichment/reverse-email-lookup) | | `enrichment` | `phone_to_person()` | `POST /v2/enrichment/phone-to-person` | [Reverse phone lookup](/api-reference/people-enrichment/reverse-phone-lookup) | | `enrichment` | `company()` | `POST /v2/enrichment/company` | [Company enrichment](/api-reference/company-enrichment/company-enrichment) | | `enrichment` | `domain_to_linkedin()` | `POST /v2/enrichment/domain-to-linkedin` | [Domain to LinkedIn](/api-reference/company-enrichment/domain-to-linkedin-url) | | `enrichment` | `linkedin_to_domain()` | `POST /v2/enrichment/linkedin-to-domain` | [LinkedIn to domain](/api-reference/company-enrichment/linkedin-url-to-domain) | | `enrichment` | `company_distribution_by_country()` | `POST /v2/enrichment/company-distribution-by-country` | [Company distribution by country](/api-reference/utilities/company-employment-distribution) | | `enrichment` | `company_distribution_by_department()` | `POST /v2/enrichment/company-distribution-by-department` | [Company distribution by department](/api-reference/utilities/company-department-distribution) | | `utils` | `current_date()` | `POST /v2/utils/current-date` | [Current date & time](/api-reference/utilities/get-current-date-and-time) | | `changelog` | `list()` | `GET /changelog` | [Get Changelog](/api-reference/changelog/changelog) | ## Next steps Install, auth, async, pagination, configuration, and error handling for `blitz-api-py`. Install, auth, pagination, configuration, and error handling for `blitz-api-js`. Stream results across pages and cap spend with `max_items`. The client-side limiter, automatic `429`/`5xx` retries, and timeout behavior. How API keys work and how to health-check your key. Full request/response schemas and an interactive try-it console. # Pagination Source: https://docs.blitz-api.ai/sdks/pagination
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
The search methods return an **auto-paginating page**. Iterate it and the SDK fetches each subsequent page for you — no cursor or page bookkeeping. This works identically in Python and TypeScript; only the syntax differs. ## Which methods paginate | Method | Pagination | | :- | :- | | `client.search.people()` | Cursor-based | | `client.search.companies()` | Cursor-based | | `client.search.employee_finder()` | Page-based | | `client.company.tam_by_jobs()` | Cursor-based | | `client.jobs.search()` | Cursor-based | | `client.jobs.company()` | Cursor-based | | `client.search.waterfall_icp()` | None — one ranked result set | | `client.changelog.list()` | None (a plain array of entries) | | `client.enrichment.*` / `client.utils.*` / `client.account.*` | None — a single response | Cursor vs page is an implementation detail — the SDK exposes the same interface for both. Cursors are stable even if new records are added between calls, so you won't see duplicates. `company.tam_by_jobs` pages carry no `total_results` (the API omits it for TAM), so iterate until the `cursor` is `null`. `job.min_per_company` can also make a page come back partial: keep paging rather than stopping on a short page. ## Stream every result Iterate the returned page to walk every match across all pages. Each page is fetched on demand, through the client's [rate limiter](/sdks/rate-limits). ```python Python theme={null} theme={null} # The SDK fetches each subsequent page for you. for person in client.search.people(people={"job_level": ["VP"]}): print(person.full_name) ``` ```ts TypeScript theme={null} theme={null} // The SDK fetches each subsequent page for you. for await (const person of client.search.people({ people: { job_level: ["VP"] } })) { console.log(person.full_name); } ``` `max_results` is the **page size** (1–50), not a total, and the API bills **1 record per result returned**. A bare loop streams *every* match up to the server-side cap (people / companies: 50,000 results or 1,000 pages; employee finder: 10,000; jobs: 5,000). Bound it with `max_items`, `break` out of the loop, or drive pages manually (below). ## Bound how much you pull `max_items` is a **client-side** total cap — it stops the SDK fetching once reached and is never sent on the wire. Use it (with `max_results` tuned for page size) to keep spend predictable. ```python Python theme={null} theme={null} # Stop after 200 results, across however many pages that takes. for person in client.search.people(people={"job_level": ["VP"]}).auto_paging_iter(max_items=200): print(person.full_name) ``` ```ts TypeScript theme={null} theme={null} // max_items goes in the options object. for await (const person of client.search.people({ people: { job_level: ["VP"] }, max_items: 200 })) { console.log(person.full_name); } // Or collect into an array (also honors max_items): const people = await client.search.people({ people: { job_level: ["VP"] }, max_items: 200 }).collect(); ``` ## Per-page and manual control Take the first page, inspect totals and cursors, and fetch the next page yourself when you need explicit control (your loop, your spend). ```python Python theme={null} theme={null} # First page + manual paging. page = client.search.people(people={"job_level": ["VP"]}, max_results=50) print(page.results, page.cursor) # items on this page; cursor is None once exhausted nxt = page.get_next_page() # None once exhausted # Or walk pages and inspect totals as you go. for p in client.search.companies(company={"industry": {"include": ["Software Development"]}}).iter_pages(max_pages=5): print(p.total_results, len(p.results), p.cursor) ``` ```ts TypeScript theme={null} theme={null} // First page + manual paging. const page = await client.search.companies({ company: { industry: { include: ["Software Development"] } }, max_results: 25 }); page.data; // Company[] — items on this page page.response.total_results; // the full parsed response (snake_case, 1:1 with the API) if (page.has_next_page()) { const next = await page.get_next_page(); } // Or walk pages directly: const first = await client.search.employee_finder({ company_linkedin_url: "https://www.linkedin.com/company/openai", max_results: 50 }); for await (const p of first.iter_pages()) { console.log(`page ${p.response.page}/${p.response.total_pages} — ${p.data.length} items`); } ``` ## Page object shape * **Python** — items are on `page.results`; cursor on `page.cursor`. The page types (`CursorPage`, `PageNumberPage`, and their `Async*` variants) are exported from `blitz_api`. * **TypeScript** — items are on `page.data`; the full parsed response (snake\_case, 1:1 with the API — e.g. `total_results`, `page`, `total_pages`) is on `page.response`. ## Next steps How the client-side limiter and automatic `429`/`5xx` retries work. Full method reference for `blitz-api-py`. Full method reference for `blitz-api-js`. Request/response schemas and a try-it console. # Python SDK Source: https://docs.blitz-api.ai/sdks/python
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
`blitz-api-py` is the official, typed Python SDK for the Blitz API. It ships sync and async clients over `httpx`, Pydantic v2 response models, `TypedDict` request filters, and a `py.typed` marker so mypy/pyright see the types in your own code. `blitz-api-py` on the Python Package Index. Source, changelog, and issues. ## Install ```bash theme={null} theme={null} pip install blitz-api-py # or: uv add blitz-api-py ``` Requires Python 3.10+. ## Quickstart ```python theme={null} theme={null} from blitz_api import BlitzAPI from blitz_api.types import Industry, JobLevel # api_key defaults to the BLITZ_API_KEY environment variable. with BlitzAPI() as client: # Health-check the key before a batch job. info = client.account.key_info() print(info.valid, info.records_remaining, info.max_requests_per_seconds) # LinkedIn profile URL -> verified work email. email = client.enrichment.email( person_linkedin_url="https://www.linkedin.com/in/example-person", ) if email.found: print(email.email) # Search people with typed, autocompleted filters. people = client.search.people( company={"industry": {"include": [Industry.SOFTWARE_DEVELOPMENT]}}, people={"job_level": [JobLevel.VP]}, max_results=10, ) for person in people.results: print(person.full_name, person.headline) ``` ## Authentication Pass the key explicitly or via the `BLITZ_API_KEY` environment variable. It is sent in the `x-api-key` header on every request. ```python theme={null} theme={null} client = BlitzAPI(api_key="sk_...") # explicit client = BlitzAPI() # reads BLITZ_API_KEY ``` Never expose your API key in client-side code (browsers, mobile apps). Always call Blitz from your backend. ## Async Use `AsyncBlitzAPI` for `async`/`await`. Every method mirrors the sync client. ```python theme={null} theme={null} import asyncio from blitz_api import AsyncBlitzAPI async def main() -> None: async with AsyncBlitzAPI() as client: result = await client.enrichment.company( company_linkedin_url="https://www.linkedin.com/company/openai", ) print(result.company.name if result.company else None) asyncio.run(main()) ``` ## Endpoints All methods are grouped into seven namespaces. Enum-backed filter fields (e.g. `Industry`, `JobLevel`, `Continent`) accept either an enum member or a raw string. ### `client.account` ```python theme={null} theme={null} info = client.account.key_info() print(info.valid, info.records_remaining, info.max_requests_per_seconds) print(info.allowed_apis) ``` ### `client.search` ```python theme={null} theme={null} # People across many companies (cursor-paginated — see Pagination below). people = client.search.people( company={ "industry": {"include": ["IT Services and IT Consulting"]}, "employee_range": ["51-200", "201-500"], "hq": {"sales_region": ["EMEA"]}, }, people={ "job_level": ["VP", "Director"], "job_function": ["Sales & Business Development"], "min_connections": 200, }, max_results=25, ) for person in people.results: print(person.full_name, person.headline, person.linkedin_url) # Companies by ICP (cursor-paginated). companies = client.search.companies( company={ "keywords": {"include": ["SaaS"]}, "industry": {"include": ["Software Development"]}, "hq": {"country_code": ["FR", "DE"]}, "employee_range": ["51-200", "201-500"], }, max_results=25, ) for company in companies.results: print(company.name, company.industry, company.employees_on_linkedin) # All employees at one company (page-paginated). employees = client.search.employee_finder( company_linkedin_url="https://www.linkedin.com/company/openai", job_level=["C-Team", "VP", "Director"], job_function=["Sales & Business Development"], sales_region=["NORAM"], max_results=50, ) print(f"Page {employees.page} of {employees.total_pages}") for person in employees.results: print(person.full_name, person.headline) # Single best decision-maker via a priority cascade. match = client.search.waterfall_icp( company_linkedin_url="https://www.linkedin.com/company/openai", cascade=[ {"include_title": ["CTO", "VP Engineering"], "location": ["WORLD"], "include_headline_search": False}, {"include_title": ["Engineering Director", "Engineering Manager"], "location": ["WORLD"], "include_headline_search": False}, ], max_results=5, ) for item in match.results: print(f"[Tier {item.icp} | Rank #{item.ranking}]", item.person.full_name) ``` ### `client.jobs` ```python theme={null} theme={null} # Live job postings across companies (cursor-paginated — see Pagination below). jobs = client.jobs.search( job={ "title": {"include": ["Head of Sales"]}, "seniority": {"include": ["5-10"]}, "employment_type": {"include": ["FULL_TIME"]}, "work_arrangement": {"include": ["Hybrid", "Remote OK"]}, "date_posted": {"last_days": 30}, }, company={ "industry": {"include": ["Software Development"]}, "size": {"include": ["51-200", "201-500"]}, }, max_results=25, ) for job in jobs.results: print(job.company_name, job.title, job.location.city if job.location else None) # Postings at one company (cursor-paginated). company_jobs = client.jobs.company( company_linkedin_url="https://www.linkedin.com/company/openai", job={"field": {"include": ["Software Engineering"]}}, max_results=25, ) for job in company_jobs.results: print(job.title, job.url) ``` ### `client.company` ```python theme={null} theme={null} # Companies hiring for a role (deduplicated), each with its matching-posting count. tam = client.company.tam_by_jobs( job={ "title": {"include": ["Account Executive"]}, "min_per_company": 3, }, company={"industry": {"include": ["Software Development"]}}, max_results=50, ) for match in tam.results: print(match.company.name if match.company else None, match.matched_jobs) ``` ### `client.enrichment` ```python theme={null} theme={null} # LinkedIn profile URL -> verified work email. email = client.enrichment.email(person_linkedin_url="https://www.linkedin.com/in/example-person") if email.found: print(email.email) # LinkedIn profile URL -> direct phone (US only). phone = client.enrichment.phone(person_linkedin_url="https://www.linkedin.com/in/example-person") if phone.found: print(phone.phone) # Work email -> full person profile. by_email = client.enrichment.email_to_person(email="jane.doe@acme.com") if by_email.found: print(by_email.person.full_name) # Phone number -> full person profile (US only). by_phone = client.enrichment.phone_to_person(phone="+14155551234") if by_phone.found: print(by_phone.person.full_name) # Company LinkedIn URL -> full company profile. company = client.enrichment.company(company_linkedin_url="https://www.linkedin.com/company/openai") print(company.company.name, company.company.industry, company.company.employees_on_linkedin) # Website domain -> Company LinkedIn URL. to_li = client.enrichment.domain_to_linkedin(domain="openai.com") if to_li.found: print(to_li.company_linkedin_url) # Company LinkedIn URL -> email domain. to_domain = client.enrichment.linkedin_to_domain(company_linkedin_url="https://www.linkedin.com/company/openai") if to_domain.found: print(to_domain.email_domain) # Company employees grouped by country. by_country = client.enrichment.company_distribution_by_country( company_linkedin_url="https://www.linkedin.com/company/openai", ) for row in by_country.distribution: print(row.country, row.count, row.percentage_ratio) # Company employees grouped by department. by_department = client.enrichment.company_distribution_by_department( company_linkedin_url="https://www.linkedin.com/company/openai", ) for row in by_department.distribution: print(row.department, row.count, row.percentage_ratio) ``` ### `client.utils` ```python theme={null} theme={null} # Current server date/time. now = client.utils.current_date() ``` ### `client.changelog` ```python theme={null} theme={null} # Public API changelog, newest first. No API key required, and not paginated. entries = client.changelog.list(days=30, limit=10) for entry in entries: print(entry.date, entry.type, entry.title, entry.affected_endpoints) ``` ## Pagination The list methods (`search.people`, `search.companies`, `search.employee_finder`, `jobs.search`, `jobs.company`, `company.tam_by_jobs`) return an **auto-paginating page** — iterate it and the SDK fetches each subsequent page for you. ```python theme={null} theme={null} # Stream every match across all pages — no cursor handling needed. for person in client.search.people(people={"job_level": ["VP"]}): print(person.full_name) ``` See **[Pagination](/sdks/pagination)** for `max_items`, manual paging, page metadata, and the per-result billing caveat. ## Usage & rate limit Every metered `/v2` response carries a `fair_usage` block: what the call cost, what is left on the plan, your rate-limit headroom, and a request id to quote to support. Read it to meter a long run without extra `key_info()` calls. ```python theme={null} theme={null} result = client.enrichment.email(person_linkedin_url="https://www.linkedin.com/in/example-person") if result.fair_usage is not None: print(result.fair_usage.records_used) # records this call consumed print(result.fair_usage.records_remaining) # a number, or "unlimited" print(result.fair_usage.next_reset_at) # None on an unlimited plan print(result.fair_usage.request_id) # quote this to support if result.fair_usage.rate_limit is not None: # omitted where the API doesn't send it print(result.fair_usage.rate_limit.remaining_this_second) # Pages carry the block from the request that fetched them. for page in client.search.people(people={"job_level": ["VP"]}).iter_pages(max_pages=5): print(page.fair_usage.records_used if page.fair_usage else None) ``` `InsufficientRecordsError` (`402`) carries the block too, so you can read `next_reset_at` without a second call. Two endpoints don't return it: the public `changelog.list()`, which is not metered, and `account.key_info()`, which reports the balance in its own top-level `records_remaining`, `next_reset_at`, and `max_requests_per_seconds` fields. ## Configuration ```python theme={null} theme={null} client = BlitzAPI( api_key=None, # falls back to BLITZ_API_KEY base_url="https://api.blitz-api.ai", timeout=30.0, # seconds, or an httpx.Timeout max_retries=3, # retries on 429 / 5xx / network errors rate_limit_rps=5.0, # client-side throttle, per endpoint; None to disable ) ``` A single client instance stays under your per-endpoint request-per-second limit and retries automatically on `429`; see **[Rate limits & retries](/sdks/rate-limits)**. `rate_limit_rps` defaults to `5`; set it to your key's `max_requests_per_seconds` to use your plan's full per-endpoint throughput. Each method also accepts a per-call `timeout`: ```python theme={null} theme={null} client.search.people(people={"job_level": ["VP"]}, timeout=10.0) ``` ## Error handling ```python theme={null} theme={null} from blitz_api import ( BlitzError, AuthenticationError, InsufficientRecordsError, NotFoundError, RateLimitError, APIStatusError, APIConnectionError, APITimeoutError, APIResponseValidationError, ) try: client.enrichment.email(person_linkedin_url="...") except InsufficientRecordsError as err: ... # 402: out of records; err.fair_usage.next_reset_at except AuthenticationError: ... # 401 — bad key except APIStatusError as err: print(err.status_code, err.message, err.body) except APIResponseValidationError: ... # 2xx whose body didn't match the model except BlitzError: ... # base class for everything this SDK raises ``` `401` / `402` / `404` raise immediately; `429` and `5xx` are retried automatically; read timeouts surface as `APITimeoutError` (not retried). `InsufficientCreditsError` still exists as a deprecated alias of `InsufficientRecordsError`, so older `except` blocks keep working. See **[Rate limits & retries](/sdks/rate-limits)** for the full retry and timeout behavior. A `400` or `422` also raises immediately, as `APIStatusError`. For a `422`, `err.body["errors"]` lists each invalid field as `{"field": ..., "message": ...}`; see **[Errors](/guide/reference/errors#validation-errors-422)**. ## Types & enums Response models are Pydantic v2 objects with attribute access and IDE autocomplete. Enum helpers live in `blitz_api.types`: ```python theme={null} theme={null} from blitz_api.types import Industry, JobLevel, Continent client.search.people( company={"industry": {"include": [Industry.SOFTWARE_DEVELOPMENT]}}, people={"job_level": [JobLevel.VP]}, ) ``` Enum-backed fields accept an enum member **or** a raw string, so a value missing from the vendored taxonomy never blocks you. New fields the API adds are preserved on the parsed model rather than breaking deserialization. ## Next steps The same API surface for Node and the browser-adjacent runtimes. Accepted values for industry, job level, job function, and geography filters. Full request/response schemas and an interactive try-it console. End-to-end workflows: build an ICP list, enrich it, and sync to your CRM. # Rate limits & retries Source: https://docs.blitz-api.ai/sdks/rate-limits
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
Blitz enforces a **per-endpoint** request-per-second limit that depends on your plan. The limit applies independently to each endpoint, so calls to `/enrichment/email` and `/enrichment/phone` run at the same time without competing for the same budget. Both SDKs handle this for you: a client-side limiter keeps your outgoing requests under the cap, and any `429` that still slips through is retried automatically. In most cases you don't need to write any rate-limit handling yourself. ## Find your limit Your per-endpoint limit is on `key_info()`. Read it rather than hard-coding a number, so your code stays correct when you change plan. ```python Python theme={null} theme={null} info = client.account.key_info() print(info.max_requests_per_seconds) # your per-endpoint req/s limit ``` ```ts TypeScript theme={null} theme={null} const info = await client.account.key_info(); console.log(info.max_requests_per_seconds); // your per-endpoint req/s limit ``` Every metered `/v2` response also reports live headroom in its `fair_usage` block, so you can watch the budget mid-run without a second call: ```python Python theme={null} theme={null} result = client.enrichment.email(person_linkedin_url="...") if result.fair_usage and result.fair_usage.rate_limit: print(result.fair_usage.rate_limit.remaining_this_second) # calls left this second ``` ```ts TypeScript theme={null} theme={null} const result = await client.enrichment.email({ person_linkedin_url: "..." }); console.log(result.fair_usage?.rate_limit?.remaining_this_second); // calls left this second ``` See [Authentication](/guide/getting-started/authentication) for the full `key_info` response. ## Client-side rate limiting Each client throttles its outgoing requests to `rate_limit_rps` (default `5`) **per endpoint**: every endpoint path gets its own limiter, mirroring the API's per-endpoint budget. In Python it's a **sliding window** (at most N requests to a given endpoint in any rolling second); in TypeScript it's a **token bucket** (admits at most N per second, per endpoint). A single client instance therefore stays under the API limit on every endpoint on its own, as long as `rate_limit_rps` doesn't exceed your plan's limit. Set it to `None` / `null` to disable. ```python Python theme={null} theme={null} client = BlitzAPI(rate_limit_rps=5.0) # default; None to disable ``` ```ts TypeScript theme={null} theme={null} const client = new BlitzAPI({ rate_limit_rps: 5 }); // default; null to disable ``` **Reuse one client per process.** The limiter lives on the client instance, so a single shared `client` keeps every endpoint's calls under its limit. If your plan allows more than 5 req/s, the default leaves throughput on the table: set `rate_limit_rps` to `max_requests_per_seconds` from your key to use the full budget. ## Automatic retries `429` (rate limited) and `5xx` (server errors) are retried automatically with exponential backoff — TypeScript adds jitter — up to `max_retries` (default `3`). `400` / `401` / `402` / `404` / `422` are **not** retried; they raise immediately. If the retries are exhausted, the error surfaces as `RateLimitError` (`429`) or `ServerError` / `APIStatusError` (`5xx`). ```python Python theme={null} theme={null} from blitz_api import BlitzAPI, RateLimitError client = BlitzAPI(max_retries=5) # default 3 try: client.search.people(people={"job_level": ["VP"]}) except RateLimitError: ... # still 429 after retries — back off and try again later ``` ```ts TypeScript theme={null} theme={null} import { BlitzAPI, RateLimitError } from "blitz-api-js"; const client = new BlitzAPI({ max_retries: 5 }); // default 3 try { await client.search.people({ people: { job_level: ["VP"] } }); } catch (err) { if (err instanceof RateLimitError) { // still 429 after retries — back off and try again later } } ``` ## Timeouts are not retried Each method takes a per-call `timeout` (Python keyword arg; TypeScript options object as the last argument). Unlike `429`/`5xx`, a **read timeout is not retried** — the server may already have processed (and billed) the request, so the SDK surfaces `APITimeoutError` immediately rather than risk a double charge. Raise the per-call timeout for genuinely slow endpoints instead of relying on retries. ```python Python theme={null} theme={null} client.enrichment.email(person_linkedin_url="...", timeout=10.0) ``` ```ts TypeScript theme={null} theme={null} await client.enrichment.email({ person_linkedin_url: "..." }, { timeout: 10 }); ``` ## Running many workers The limiter is **per client instance** (per process), and the API limit is **per endpoint**. If you fan the SDK out across multiple processes or workers that hit the **same endpoint**, their combined rate can exceed that endpoint's limit and you'll see `429`s — the retry path absorbs occasional ones, but for steady throughput divide `rate_limit_rps` across the workers sharing an endpoint (e.g. 5 workers all calling `/enrichment/email` on a 10 req/s key → `rate_limit_rps = 2` each). Workers calling **different** endpoints don't compete — each endpoint has its own budget. ## Next steps Stream results across pages and cap spend with `max_items`. The full exception hierarchy for `blitz-api-py`. The full exception hierarchy for `blitz-api-js`. Request/response schemas and a try-it console. # TypeScript / JavaScript SDK Source: https://docs.blitz-api.ai/sdks/typescript
> **Agents & LLMs**: a Markdown version of this page is available by appending `.md` to the URL, and the full documentation index is at [llms.txt](https://docs.blitz-api.ai/llms.txt).
`blitz-api-js` is the official, typed TypeScript SDK for the Blitz API. It is `fetch`-based, Zod-validated, ships both ESM and CommonJS builds with `.d.ts` / `.d.cts` types, and uses **snake\_case** request and response fields that match the [API reference](/api-reference/account/get-api-key-details) exactly. `blitz-api-js` on the npm registry. Source, changelog, and issues. ## Install ```bash theme={null} theme={null} npm install blitz-api-js # or: pnpm add blitz-api-js / yarn add blitz-api-js ``` Requires Node.js 20+ (or any runtime with a global `fetch`). Ships both ESM and CommonJS builds. ## Quickstart ```ts theme={null} theme={null} import { BlitzAPI } from "blitz-api-js"; // api_key defaults to the BLITZ_API_KEY environment variable. const client = new BlitzAPI(); // Health-check the key before a batch job. const info = await client.account.key_info(); console.log(info.valid, info.records_remaining, info.max_requests_per_seconds); // LinkedIn profile URL -> verified work email. const email = await client.enrichment.email({ person_linkedin_url: "https://www.linkedin.com/in/example-person", }); if (email.found) console.log(email.email); // Search people — list methods are paginated; one page's items live on `.data`. const page = await client.search.people({ company: { industry: { include: ["Software Development"] } }, people: { job_level: ["VP"] }, max_results: 10, }); for (const person of page.data) { console.log(person.full_name, person.headline); } ``` CommonJS works too: ```js theme={null} theme={null} const { BlitzAPI } = require("blitz-api-js"); ``` ## Authentication Pass the key explicitly or via the `BLITZ_API_KEY` environment variable. It is sent in the `x-api-key` header on every request. ```ts theme={null} theme={null} const explicit = new BlitzAPI({ api_key: "sk_..." }); // explicit const fromEnv = new BlitzAPI(); // reads BLITZ_API_KEY ``` Never expose your API key in client-side code (browsers, mobile apps). Always call Blitz from your backend. ## Endpoints All methods are grouped into seven namespaces. Each takes a single options object (snake\_case keys) and returns a typed, Zod-validated response. The six **list** methods (`search.people`, `search.companies`, `search.employee_finder`, `jobs.search`, `jobs.company`, `company.tam_by_jobs`) return a paginated `PagePromise` (see [Pagination](#pagination)); `waterfall_icp`, `changelog.list`, and the `enrichment` / `utils` / `account` methods return their response directly. ### `client.account` ```ts theme={null} theme={null} const info = await client.account.key_info(); console.log(info.valid, info.records_remaining, info.max_requests_per_seconds); console.log(info.allowed_apis); ``` ### `client.search` ```ts theme={null} theme={null} // People across many companies (cursor-paginated — see Pagination below). const people = await client.search.people({ company: { industry: { include: ["IT Services and IT Consulting"] }, employee_range: ["51-200", "201-500"], hq: { sales_region: ["EMEA"] }, }, people: { job_level: ["VP", "Director"], job_function: ["Sales & Business Development"], min_connections: 200, }, max_results: 25, }); for (const person of people.data) { console.log(person.full_name, person.headline, person.linkedin_url); } // Companies by ICP (cursor-paginated). const companies = await client.search.companies({ company: { keywords: { include: ["SaaS"] }, industry: { include: ["Software Development"] }, hq: { country_code: ["FR", "DE"] }, employee_range: ["51-200", "201-500"], }, max_results: 25, }); for (const company of companies.data) { console.log(company.name, company.industry, company.employees_on_linkedin); } // All employees at one company (page-paginated). const employees = await client.search.employee_finder({ company_linkedin_url: "https://www.linkedin.com/company/openai", job_level: ["C-Team", "VP", "Director"], job_function: ["Sales & Business Development"], sales_region: ["NORAM"], max_results: 50, }); console.log(`Page ${employees.response.page} of ${employees.response.total_pages}`); for (const person of employees.data) { console.log(person.full_name, person.headline); } // Single best decision-maker via a priority cascade (returned directly). const match = await client.search.waterfall_icp({ company_linkedin_url: "https://www.linkedin.com/company/openai", cascade: [ { include_title: ["CTO", "VP Engineering"], location: ["WORLD"], include_headline_search: false }, { include_title: ["Engineering Director", "Engineering Manager"], location: ["WORLD"], include_headline_search: false }, ], max_results: 5, }); for (const item of match.results) { console.log(`[Tier ${item.icp} | Rank #${item.ranking}]`, item.person.full_name); } ``` ### `client.jobs` ```ts theme={null} theme={null} // Live job postings across companies (cursor-paginated — see Pagination below). const jobs = await client.jobs.search({ job: { title: { include: ["Head of Sales"] }, seniority: { include: ["5-10"] }, employment_type: { include: ["FULL_TIME"] }, work_arrangement: { include: ["Hybrid", "Remote OK"] }, date_posted: { last_days: 30 }, }, company: { industry: { include: ["Software Development"] }, size: { include: ["51-200", "201-500"] }, }, max_results: 25, }); for (const job of jobs.data) { console.log(job.company_name, job.title, job.location?.city); } // Postings at one company (cursor-paginated). const companyJobs = await client.jobs.company({ company_linkedin_url: "https://www.linkedin.com/company/openai", job: { field: { include: ["Software Engineering"] } }, max_results: 25, }); for (const job of companyJobs.data) { console.log(job.title, job.url); } ``` ### `client.company` ```ts theme={null} theme={null} // Companies hiring for a role (deduplicated), each with its matching-posting count. for await (const match of client.company.tam_by_jobs({ job: { title: { include: ["Account Executive"] }, min_per_company: 3 }, company: { industry: { include: ["Software Development"] } }, max_results: 50, max_items: 200, })) { console.log(match.company?.name, match.matched_jobs); } ``` ### `client.enrichment` ```ts theme={null} theme={null} // LinkedIn profile URL -> verified work email. const email = await client.enrichment.email({ person_linkedin_url: "https://www.linkedin.com/in/example-person" }); if (email.found) console.log(email.email); // LinkedIn profile URL -> direct phone (US only). const phone = await client.enrichment.phone({ person_linkedin_url: "https://www.linkedin.com/in/example-person" }); if (phone.found) console.log(phone.phone); // Work email -> full person profile. const byEmail = await client.enrichment.email_to_person({ email: "jane.doe@acme.com" }); if (byEmail.found) console.log(byEmail.person.full_name); // Phone number -> full person profile (US only). const byPhone = await client.enrichment.phone_to_person({ phone: "+14155551234" }); if (byPhone.found) console.log(byPhone.person.full_name); // Company LinkedIn URL -> full company profile. const company = await client.enrichment.company({ company_linkedin_url: "https://www.linkedin.com/company/openai" }); console.log(company.company.name, company.company.industry, company.company.employees_on_linkedin); // Website domain -> Company LinkedIn URL. const toLinkedin = await client.enrichment.domain_to_linkedin({ domain: "openai.com" }); if (toLinkedin.found) console.log(toLinkedin.company_linkedin_url); // Company LinkedIn URL -> email domain. const toDomain = await client.enrichment.linkedin_to_domain({ company_linkedin_url: "https://www.linkedin.com/company/openai" }); if (toDomain.found) console.log(toDomain.email_domain); // Company employees grouped by country. const byCountry = await client.enrichment.company_distribution_by_country({ company_linkedin_url: "https://www.linkedin.com/company/openai", }); for (const row of byCountry.distribution) { console.log(row.country, row.count, row.percentage_ratio); } // Company employees grouped by department. const byDepartment = await client.enrichment.company_distribution_by_department({ company_linkedin_url: "https://www.linkedin.com/company/openai", }); for (const row of byDepartment.distribution) { console.log(row.department, row.count, row.percentage_ratio); } ``` ### `client.utils` ```ts theme={null} theme={null} // Current server date/time. const now = await client.utils.current_date(); ``` ### `client.changelog` ```ts theme={null} theme={null} // Public API changelog, newest first. No API key required, and not paginated. const entries = await client.changelog.list({ days: 30, limit: 10 }); for (const entry of entries) console.log(entry.date, entry.type, entry.title); ``` ## Pagination The list methods (`search.people`, `search.companies`, `search.employee_finder`, `jobs.search`, `jobs.company`, `company.tam_by_jobs`) return a `PagePromise` — `await` it for the first page, or `for await` to stream every item across all pages (each fetched on demand). ```ts theme={null} theme={null} // Stream every match across all pages — no cursor handling needed. for await (const person of client.search.people({ people: { job_level: ["VP"] } })) { console.log(person.full_name); } ``` See **[Pagination](/sdks/pagination)** for `max_items`, `.collect()`, manual paging, page metadata, and the per-result billing caveat. ## Usage & rate limit Every metered `/v2` response carries a `fair_usage` block reporting what the request cost and what is left, so you can meter a batch job without a second `key_info()` call. ```ts theme={null} theme={null} const email = await client.enrichment.email({ person_linkedin_url: "https://www.linkedin.com/in/example-person" }); const usage = email.fair_usage; console.log(usage?.records_used); // records this request consumed console.log(usage?.records_remaining); // a number, or "unlimited" console.log(usage?.next_reset_at); // null on an unlimited plan console.log(usage?.rate_limit?.remaining_this_second); // calls left this second console.log(usage?.request_id); // quote this id to support // On a paginated method the block belongs to each page's raw body. const page = await client.search.people({ people: { job_level: ["VP"] }, max_results: 50 }); console.log(page.response.fair_usage?.records_used); ``` Two endpoints don't return the block: the public `changelog.list()`, which is not metered, and `account.key_info()`, which reports the balance in its own top-level `records_remaining`, `next_reset_at`, and `max_requests_per_seconds` fields. Every field is optional, so a response predating the block still parses. ## Configuration ```ts theme={null} theme={null} const client = new BlitzAPI({ api_key: undefined, // falls back to BLITZ_API_KEY base_url: "https://api.blitz-api.ai", timeout: 30, // default per-request timeout, seconds (via AbortSignal.timeout) max_retries: 3, // retries on 429 / 5xx / pre-response network errors rate_limit_rps: 5, // client-side token bucket, per endpoint; null to disable fetch: undefined, // custom fetch implementation (tests / runtimes) }); // Override the timeout for a single call — pass an options object as the last argument: await client.enrichment.email({ person_linkedin_url: "..." }, { timeout: 5 }); ``` A single client instance stays under your per-endpoint request-per-second limit and retries automatically on `429`; see **[Rate limits & retries](/sdks/rate-limits)**. `rate_limit_rps` defaults to `5`; set it to your key's `max_requests_per_seconds` to use your plan's full per-endpoint throughput. ## Error handling ```ts theme={null} theme={null} import { APIConnectionError, APIResponseValidationError, APIStatusError, APITimeoutError, AuthenticationError, BlitzError, FairUsageLimitError, NotFoundError, RateLimitError, ServerError, } from "blitz-api-js"; try { await client.enrichment.email({ person_linkedin_url: "..." }); } catch (err) { if (err instanceof FairUsageLimitError) { // 402: Fair Use record limit reached; err.fair_usage?.next_reset_at } else if (err instanceof AuthenticationError) { // 401 — bad key } else if (err instanceof APIResponseValidationError) { // 2xx, but the body wasn't valid JSON or didn't match the schema } else if (err instanceof APIStatusError) { console.log(err.status_code, err.message, err.body, err.request_id); } else if (err instanceof BlitzError) { // base class for everything this SDK raises } } ``` `401` / `402` / `404` throw immediately; `429` and `5xx` are retried automatically; timeouts surface as `APITimeoutError` (not retried). `InsufficientCreditsError` is still exported as a deprecated alias of `FairUsageLimitError` (the same class, not a subclass), so existing `instanceof` checks keep working. See **[Rate limits & retries](/sdks/rate-limits)** for the full retry and timeout behavior. A `400` or `422` also throws immediately, as `APIStatusError`. For a `422`, `err.body.errors` lists each invalid field as `{ field, message }`; see **[Errors](/guide/reference/errors#validation-errors-422)**. The API rejects any field it does not define, so an extra key in a params object returns a `422` even when TypeScript does not flag it. ## Types & enums Response objects keep their snake\_case wire keys and **preserve unknown fields** — if the API adds a property before this SDK models it, the value is still present (typed as `unknown`); known fields stay precisely typed. ```ts theme={null} theme={null} import { INDUSTRY } from "blitz-api-js"; // the full value array (534 industries) import type { CompanyFilter, Industry } from "blitz-api-js"; ``` Enum-backed filter fields (e.g. `industry`, `job_level`, `continent`) accept a known value — autocompleted from a union like `Industry` — or any raw string, so a value missing from the vendored taxonomy never blocks you. ## Next steps The same API surface with sync + async clients. Accepted values for industry, job level, job function, and geography filters. Full request/response schemas and an interactive try-it console. End-to-end workflows: build an ICP list, enrich it, and sync to your CRM.