# API key Source: https://docs.pipecorn.com/api-reference/API-key Where to generate the API key that authenticates every request. ## Get my API key You need your personal API key to use the Pipecorn API, which you can generate [here](https://app.pipecorn.com/settings/apis/keys). # Create a new list Source: https://docs.pipecorn.com/api-reference/create-a-new-list /api-reference/specs/list.json post /lists Creates a new list in the system. # Credits vs limits Source: https://docs.pipecorn.com/api-reference/credits-vs-limits Enrichment credits are a paid balance you spend. Plan limits are quotas included in your plan. They are tracked, exhausted, and refilled differently. Pipecorn meters usage with two separate mechanisms that are easy to confuse, partly because the `GET /credits` response uses the word "credits" for both. This page tells them apart so you know which one a request draws on, which one an error is about, and what actually unblocks you. **One-line version.** A **credit** is a paid unit you spend on enrichment (emails, phones, company and people data). A **limit** is a quota bundled with your plan that caps how many profiles or companies you can extract per day or month. Buying credits never raises a limit, and a limit resetting never adds credits. ## Side by side | | Enrichment credits | Plan limits | | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | What it is | A prepaid balance owned by your workspace | Daily and monthly quotas included in your plan | | What draws on it | Enrichment: waterfall email and phone, account and people enrichment, hiring and tech-stack lookups, WhatsApp validation | Extraction: pulling people profiles or importing companies from a search, a Sales Navigator URL, or a post | | Unit | Credits per result (for example 3 per email, 30 per phone, 1 per enriched company) | One profile or one company per unit | | How it goes down | Spent per successful result. A lookup that resolves nothing costs nothing | Consumed per extracted profile or imported company | | How it goes back up | Buy credits, or wait for your plan renewal to add the plan's monthly allocation | Resets automatically: daily quotas every day, the monthly company quota every month | | How to get more | [Top up](https://app.pipecorn.com/settings/subscriptions/credits) at any time | Upgrade your plan, or contact support | | Where to check | `credits.enrichment` in [`GET /credits`](/api-reference/endpoints/miscellaneous/account-credits), or [`GET /credits_consumption`](/api-reference/endpoints/miscellaneous/credit-consumption) for a date range | `credits.daily_profile_scraping`, `credits.daily_company_import`, `credits.monthly_company_import` (remaining) and `limits.*` (ceiling) in `GET /credits` | | Error when exhausted | `402 Payment Required`, `code: "insufficient_credits"`, with a `top_up_url` | `422 Unprocessable Entity`, message `"Can't proceed with the request. Plan limit reached."` | Preview endpoints (`/leads/advanced_search/preview`, `/accounts/search/preview`, `/intents/accounts/stack/preview`) draw on neither. They are free and never return either error. ## Enrichment credits Credits are the paid resource. Every endpoint that returns enriched data checks your balance before doing any work and charges only for what it actually returns: * Waterfall enrichment: **3 credits** per email, **30 credits** per phone ([single](/api-reference/endpoints/enrichments/single), [bulk](/api-reference/endpoints/enrichments/batch), [synchronous](/api-reference/endpoints/contacts/sync_single_enrich)) * [Enrich account](/api-reference/endpoints/accounts/single) and [Enrich people](/api-reference/endpoints/leads/single): **1 credit** per resolved company or person * [Company hiring](/api-reference/endpoints/accounts/company-hiring): **1 credit** per job returned * [Company stack](/api-reference/endpoints/accounts/company-stack), [hiring intent](/api-reference/endpoints/signals/hiring) and [tech-stack search](/api-reference/endpoints/signals/tech_stack) (**3 credits** per imported company) * WhatsApp validation When the balance is too low the request is rejected up front with `402` and nothing is spent, enqueued, or imported. Top up and replay the same request. Credits belong to the workspace, so every member and every API key spends from the same pool. ## Plan limits Limits are quotas, not a balance. They come with your plan, reset on a fixed schedule, and cannot be bought one at a time. There are two of them: * **Profile scraping** (daily): how many people profiles you can extract per day. Drawn on by lead extraction, such as [search leads by filters](/api-reference/endpoints/leads/advanced_search), [extract leads from a Sales Navigator URL](/api-reference/endpoints/extract/leads), [leads in a company](/api-reference/endpoints/extract/leads_from_company), and [post engagers](/api-reference/endpoints/signals/post_engagers). * **Company import** (daily and monthly): how many companies you can import per day and per month. Drawn on by account extraction, such as [search accounts by filters](/api-reference/endpoints/accounts/search), [extract accounts from a Sales Navigator URL](/api-reference/endpoints/extract/accounts), [lookalike companies](/api-reference/endpoints/signals/company_lookalike), and [growth signals](/api-reference/endpoints/signals/growth). When a quota is used up the endpoint answers `422` with `"Can't proceed with the request. Plan limit reached."`. Wait for the reset or move to a plan with a higher allowance. Buying credits does nothing here. In `GET /credits` the remaining quotas live under the `credits` key, next to `credits.enrichment`, and the field descriptions call them "credits". Read them as **remaining quota for the current period**, not as a spendable balance. Only `credits.enrichment` is money you can top up. The `limits` object gives each quota's ceiling so you can compute how much of the period you have used. ```json theme={null} { "credits": { "enrichment": 3000, "daily_profile_scraping": 1500, "daily_company_import": 1000, "monthly_company_import": 10000 }, "limits": { "daily_profile_scraping": 2500, "daily_company_import": 1000, "monthly_company_import": 10000 } } ``` In this example the workspace has 3,000 enrichment credits to spend, and can still extract 1,500 of its 2,500 daily profiles. ## Two other "limits" that are not plan limits ### Workspace weekly credit limit A workspace admin can cap how many **enrichment credits** each member may spend per week. This is a spending ceiling on credits, not a quota on extraction. Hitting it returns `403 Forbidden` with `code: "workspace_limit_exceeded"` and no `top_up_url`: the balance may be fine, so buying credits does not help. An admin raises the member's weekly allowance, or the limit resets at the end of the week. ### Rate limits Requests per second or per minute, tracked per API key and per endpoint. Exceeding one returns `429 Too Many Requests`. Rate limits are about request pacing and have nothing to do with credits or quotas; back off and retry. ## Which one am I hitting? Branch on the status code and, for `403`, on the `code` field. | Response | What ran out | What unblocks it | | --------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | | `402` with `code: "insufficient_credits"` | Enrichment credit balance | Top up at `top_up_url`, or wait for plan renewal, then retry | | `403` with `code: "workspace_limit_exceeded"` | Weekly credit spending cap for this member | Workspace admin raises the allowance, or the week resets | | `403` with any other body | Nothing ran out: the API key lacks access to the endpoint | Use a key with the right permissions | | `422` with `"Plan limit reached."` | Daily profile scraping or daily/monthly company import quota | Wait for the reset, or upgrade the plan | | `429` | Request rate for this endpoint | Back off and retry | For the exact response bodies and the list of endpoints that return each code, see [Credit and limit errors](/api-reference/errors). **History.** Until August 2026, enrich account and enrich people drew on the company import and profile scraping quotas and failed with `422` when they ran out. They are now priced in credits and answer `402` and `403` instead. See the [changelog](/changelog). # Company hiring (job postings) Source: https://docs.pipecorn.com/api-reference/endpoints/accounts/company-hiring POST /accounts/company_hiring Retrieve the list of open job postings for a given company Get the list of open job postings indexed for a company using one company identifier (domain, company name, or LinkedIn URL). Results are sourced from TheirStack. ## Credits and rate limits * Credits: **1 credit per job returned**. You are only charged for the jobs actually returned, and never for more jobs than your available credits allow. A lookup that returns no jobs costs nothing. * Rate limit: **5 requests per second** per user If your balance cannot cover the lookup, the request is rejected with `402 Payment Required` and `code: "insufficient_credits"` before any job is fetched. A workspace weekly credit limit returns `403 Forbidden` with `code: "workspace_limit_exceeded"` instead. See [Credit and limit errors](/api-reference/errors). ## Required identification Provide at least one of: * `company_domain` * `company_name` * `company_linkedin_url` If none are provided, the API returns: ```json theme={null} { "error": 400, "message": "Provide at least one of: company_domain, company_name, company_linkedin_url" } ``` ## Optional parameters * `posted_within_days`: Only return jobs posted within the last N days. Must be one of the selectable look-back windows: `7`, `30`, `60`, `90`, or `180`. Defaults to `30` when omitted; any other value returns `422`. * `limit`: Maximum number of jobs to return, a positive integer capped at **100**. Because billing is per job, use this to bound how many credits a single lookup can spend. Only enough pages to satisfy the limit are fetched. * `full_description`: When `true`, return each job's full description. Defaults to `false`, in which case descriptions are truncated to a 300-character snippet. * `job_title_keywords`: Array of strings. Only return jobs whose title matches one of these keywords. * `excluded_job_title_keywords`: Array of strings. Exclude jobs whose title matches one of these keywords. * `job_description_keywords`: Array of strings. Only return jobs whose description contains one of these keywords. * `excluded_job_description_keywords`: Array of strings. Exclude jobs whose description contains one of these keywords. * `job_country_codes`: Array of 2-letter ISO 3166-1 alpha-2 country codes (e.g. `US`, `FR`). Only return jobs located in these countries. Codes are case-insensitive. * `excluded_job_country_codes`: Array of 2-letter ISO 3166-1 alpha-2 country codes. Exclude jobs located in these countries. Each keyword filter must be an array of strings, otherwise the API returns `422`. Invalid country codes also return `422`. ## Example request ```json theme={null} { "company_domain": "notion.so", "posted_within_days": 30, "limit": 10, "full_description": false, "job_title_keywords": ["engineer", "developer"], "excluded_job_title_keywords": ["intern"], "job_country_codes": ["US", "FR"] } ``` ## Example response The `truncated` flag is `true` when more jobs matched than were returned (because of the `limit`, the 100-job ceiling, or your available credits). ```json theme={null} { "total_jobs": 42, "truncated": true, "company": { "name": "Acme", "domain": "acme.com", "linkedin_url": "https://linkedin.com/company/acme" }, "jobs": [ { "job_title": "Senior Backend Engineer", "job_url": "https://example.com/jobs/1", "job_location": "Paris France", "employment_statuses": ["full_time"], "date_posted": "2026-05-30", "description": "Build cool stuff with Rails.", "hiring_team": [ { "name": "Alice Doe", "title": "Engineering Manager", "linkedin_url": "https://linkedin.com/in/alice" } ] } ] } ``` # Company stack (technographics) Source: https://docs.pipecorn.com/api-reference/endpoints/accounts/company-stack POST /accounts/company_stack Retrieve a company technology stack Get a company's technology stack using one company identifier (domain, company name, or LinkedIn URL). ## Credits and rate limits * Credits: **3 credits** per request * Rate limit: **20 requests per second** per user If your balance is below 3 credits, the request is rejected with `402 Payment Required` and `code: "insufficient_credits"` before the provider is called. A workspace weekly credit limit returns `403 Forbidden` with `code: "workspace_limit_exceeded"` instead. See [Credit and limit errors](/api-reference/errors). ## Required identification Provide at least one of: * `company_domain` * `company_name` * `company_linkedin_url` If none are provided, the API returns: ```json theme={null} { "error": 400, "message": "Provide at least one of: company_domain, company_name, company_linkedin_url" } ``` ## Example request ```json theme={null} { "company_name": "Notion", "company_domain": "notion.so", "company_linkedin": "https://www.linkedin.com/company/notionhq/" } ``` ## Example response ```json theme={null} { "technologies": ["Amazon Web Services", "React", "Segment"], "technologies_with_confidence": [ { "name": "Amazon Web Services", "confidence": 0.97 }, { "name": "React", "confidence": 0.93 }, { "name": "Segment", "confidence": 0.74 } ] } ``` # # people at company Source: https://docs.pipecorn.com/api-reference/endpoints/accounts/count-profiles POST /accounts/count_profiles Count matching profiles based on job titles and locations. **Rate limit:** 2 requests per minute # Count Profiles The Count Profiles endpoint allows you to count the number of employee profiles matching specific criteria for a company. You can filter by job titles and locations to get precise counts of potential prospects. ## Required Parameters You must provide one of the following to identify the target company: * `company_linkedin_id`: The LinkedIn company identifier * `company_linkedin_url`: The full URL of the company's LinkedIn profile (regular or Sales Navigator) ## Location IDs Reference Location IDs used in this endpoint can be retrieved using the [Location Ids endpoint](/api-reference/endpoints/miscellaneous/location-ids). Simply provide a location name (e.g., "San Francisco") and the API will return all matching locations with their IDs. ## Request Example ```json theme={null} { "company_linkedin_id": "1234567", // Required if company_linkedin_url is not provided "title_to_include": ["Software Engineer", "Developer"], "title_to_exclude": ["Junior"], "included_locations": ["105015875", "102221843"], "excluded_locations": ["103644278"] } ``` Alternative company identification: ```json theme={null} { "company_linkedin_url": "https://www.linkedin.com/company/microsoft", // Required if company_linkedin_id is not provided // ... other parameters ... } ``` ## Response Example ```json theme={null} { "total": 26, "title_to_include": ["Software Engineer", "Developer"], "title_to_exclude": ["Junior"], "included_locations": ["105015875", "102221843"], "excluded_locations": ["103644278"] } ``` ## Understanding the Response * `total`: The total number of profiles matching your criteria * `title_to_include`: List of job titles that were included in the search * `title_to_exclude`: List of job titles that were excluded from the search * `included_locations`: List of Location IDs that were included * `excluded_locations`: List of Location IDs that were excluded ## Tips * Use location IDs to target specific geographic areas * Combine title inclusions and exclusions to refine your search * Keep your title filters relevant to ensure accurate results # Department headcount Source: https://docs.pipecorn.com/api-reference/endpoints/accounts/headcount POST /accounts/headcount Retrieve headcount information for specified departments or all departments if none specified. By default the data comes live from LinkedIn (`live: true`) and includes 3/6/12-month evolution per department, as documented below. Set `live: false` to answer from Pipecorn's companies database (Elasticsearch) instead, with no integration required. The `live: false` response is a current snapshot only (no evolution) in a different shape: ```json { "total_headcount": 18769, "departments": { "Engineering": { "current_headcount": 8681 }, "Sales": { "current_headcount": 6258 } } } ``` **Rate limit:** 2 requests per minute # Search accounts by filters Source: https://docs.pipecorn.com/api-reference/endpoints/accounts/search POST /accounts/search Search and extract company accounts based on industry, location, size, and keyword filters Search and extract company accounts using powerful filters including industry, location, company size, and keywords. This endpoint processes results asynchronously and sends enriched account data to your webhook URL. ## Overview This endpoint allows you to search for companies based on various criteria without needing to provide a LinkedIn Sales Navigator URL. The process is asynchronous - you'll receive an immediate response with the import job details and a preview of matching accounts, and the complete enriched results will be sent to your webhook URL when processing is complete. ## Rate Limits * **1 request per second** per user/IP address ## Search Filters ### Industries Target or exclude specific industries using industry IDs. Multiple industry IDs are combined with OR logic. **Parameters:** * `included_industries`: Array of industry IDs to target * `excluded_industries`: Array of industry IDs to exclude from results For the complete list of industry IDs, see the [LinkedIn Industry List](https://docs.google.com/spreadsheets/d/1qTFPVfcSHnL5PU1AcQlzD8mCmfSICKJ4WuU-OBGhkdI/edit?gid=0#gid=0). Common industry IDs include: * `4` - Automotive * `6` - Technology, Information and Internet * `12` - Education * `43` - Financial Services * `96` - Software Development ### Locations Use the [Location IDs endpoint](/api-reference/endpoints/miscellaneous/location-ids) to find valid location IDs. You can include or exclude specific locations: * `included_locations`: Target specific countries, states, or cities * `excluded_locations`: Exclude specific locations from results ### Company Size Filter by employee count ranges: * `1-10` - Startup/Very Small * `11-50` - Small * `51-200` - Medium * `201-500` - Medium-Large * `501-1000` - Large * `1001-5000` - Very Large * `5001-10000` - Enterprise * `10001+` - Mega Corporation Multiple size ranges can be used ### Keyword Search for companies by keyword in their name or description. This is useful for targeting specific niches or technologies (e.g., "saas", "fintech", "healthcare"). ### Revenue Filter companies by their annual revenue range. Revenue values are specified in millions and can be combined with a currency code. **Parameters:** * `min_revenue`: Minimum annual revenue (in millions). Valid values: `0`, `0.5`, `1`, `2.5`, `5`, `10`, `20`, `50`, `100`, `500`, `1000` * `max_revenue`: Maximum annual revenue (in millions). Valid values: `0.5`, `1`, `2.5`, `5`, `10`, `20`, `50`, `100`, `500`, `1000`, `1001` (where `1001` represents \$1B+) * `revenue_currency`: Currency code for revenue values. Defaults to `USD` if not specified. **Supported currencies:** `USD`, `EUR`, `GBP`, `CAD`, `AUD`, `JPY`, `CNY`, `INR`, `BRL`, `SEK`, `NOK`, `DKK`, `SGD`, `HKD`, `NZD`, `THB`, `IDR`, `TRY`, `TWD`, `ILS`, `AED`, `RUB` **Example:** To find companies with revenue between $10M-$50M: ```json theme={null} { "min_revenue": 10, "max_revenue": 50, "revenue_currency": "USD" } ``` ## Limits By default, the endpoint will process up to 1,000 matching accounts. You can set a lower limit using the `limit` parameter. The minimum of your specified limit and 1,000 will be used. ## Streaming Mode When `streaming` is set to `true`, results will be sent to your webhook in batches as they are processed, rather than all at once when complete. This is useful for large searches where you want to start processing results immediately. ## Response The endpoint returns immediately with: * A unique import job ID for tracking * The total number of accounts that will be processed * A preview of the first 10 matching accounts The complete enriched results will be sent to your webhook URL when processing is complete. ## Example Use Cases ### Find SaaS companies in US tech hubs ```json theme={null} { "webhook_url": "https://your-webhook.com/accounts", "name": "US Tech SaaS Companies", "included_industries": ["6", "96"], "included_locations": ["103644278"], "company_size": ["51-200", "201-500"], "keyword": "saas" } ``` ### Target European fintech startups ```json theme={null} { "webhook_url": "https://your-webhook.com/accounts", "name": "European Fintech Startups", "included_industries": ["43"], "included_locations": ["100506914", "105015875", "101165590"], "company_size": ["11-50", "51-200"], "limit": 500 } ``` ### Find large automotive companies excluding specific regions ```json theme={null} { "webhook_url": "https://your-webhook.com/accounts", "name": "Global Automotive Giants", "included_industries": ["4"], "excluded_locations": ["102221843"], "company_size": ["5001-10000", "10001+"] } ``` ### Find high-revenue tech companies in Europe ```json theme={null} { "webhook_url": "https://your-webhook.com/accounts", "name": "High Revenue European Tech", "included_industries": ["6", "96"], "included_locations": ["100506914", "105015875"], "min_revenue": 100, "max_revenue": 1001, "revenue_currency": "EUR" } ``` # Preview Source: https://docs.pipecorn.com/api-reference/endpoints/accounts/search_preview POST /accounts/search/preview Synchronously preview the first 25 matches and the total estimated count for a set of account search filters, without creating an import or consuming credits. Run the same filters as [`POST /accounts/search`](/api-reference/endpoints/accounts/search) and get back a synchronous **preview**: the total estimated account count plus the first **25** matching companies. Use it to validate filters and size an audience before kicking off the real search. ## Overview Compared to `POST /accounts/search`, the preview: * Does **not** create an import job. * Does **not** call your webhook. * Does **not** consume credits. * Does **not** require `webhook_url`. The body accepts the exact same filter parameters as the regular account search — see [Search accounts by filters](/api-reference/endpoints/accounts/search) for the full reference (`included_industries`, `excluded_industries`, `included_locations`, `excluded_locations`, `company_size`, `keyword`, `min_revenue`, `max_revenue`, `revenue_currency`, …). `webhook_url`, `name`, `limit`, and `streaming` are accepted but ignored: the response always contains up to 25 accounts. ## Rate Limits * **1 request per second** per user/IP address. ## Response `200 OK` — returns immediately with: ```json theme={null} { "total_count": 4321, "preview": [ { "company_name": "Pipecorn", "industry": "Technology, Information and Internet", "linkedin_id": "104885158", "linkedin_url": "https://www.linkedin.com/company/104885158" } ] } ``` | Field | Type | Notes | | ------------- | ---------------- | --------------------------------------------------------------------------------------- | | `total_count` | integer | Total estimated number of accounts matching the filters (not capped to 25). | | `preview` | array of objects | Up to 25 matching accounts. Each entry contains the fields listed above when available. | ## Example ```json theme={null} { "included_industries": ["6", "96"], "included_locations": ["103644278"], "company_size": ["51-200", "201-500"], "keyword": "saas" } ``` # Enrich account Source: https://docs.pipecorn.com/api-reference/endpoints/accounts/single POST /accounts/single_enrich Enrich a single company account with firmographic data. **Credits:** 1 credit per enrichment. You are only charged when a company is actually resolved — a lookup that matches nothing costs nothing. Identify the company with any of `company_linkedin_url`, `domain` or `name`. The more you provide, the more precisely the account is matched. # Find Enrichment result Source: https://docs.pipecorn.com/api-reference/endpoints/contacts/single_enrich GET /contacts/{id} Retrieve enrichment results for a single contact # Synchronous Single Contact Enrichment Source: https://docs.pipecorn.com/api-reference/endpoints/contacts/sync_single_enrich sync-enrichments POST /contacts/single_enrich Enrich a single contact with email, phone, and/or personal email data and get results instantly Enrich a single contact with email, phone, and/or personal email data using our waterfall enrichment system. Unlike the async enrichment endpoint, this endpoint returns results **synchronously** in the response - no webhook polling required. ## Overview This endpoint performs real-time waterfall enrichment across multiple data providers to find the most accurate email, phone number, and/or personal email for a contact. Results are returned immediately in the API response, making it ideal for interactive applications, Chrome extensions, and real-time workflows. ## Rate Limits * **50 requests per second** per user This generous rate limit makes it suitable for high-volume interactive use cases while protecting our infrastructure. ## Enrichment Types You can specify which data points you want to enrich by passing the `enrichment_type` array parameter: * `["email"]` - Find and validate professional email addresses only * `["phone"]` - Find phone numbers only * `["personal_email"]` - Find personal email addresses only (requires user consent — see below) * Any combination, e.g. `["email", "phone"]`, `["email", "personal_email"]`, or `["email", "phone", "personal_email"]` Requesting `personal_email` requires the authenticated user to have consented to personal email enrichment in their account settings. If consent is missing, the API responds with `422 Unprocessable Entity` and the message `"You can't use the personal email enrichment feature without consenting with our terms of use"`. This consent gate is required for GDPR compliance. Requests including `phone` or `personal_email` must include `linkedin_url`. ### Waterfall Enrichment When you request multiple enrichment types, our system uses a sophisticated waterfall approach: 1. Attempts to find the professional email from the most reliable providers first 2. Searches for personal email through dedicated personal-email providers (Pipecorn, LeadMagic, Airscale) 3. Searches for phone numbers using provider prioritization 4. Returns results as soon as all requested data points are found or all providers are exhausted This approach maximizes data quality while minimizing enrichment time and cost. ## Response Format ### Success Response When enrichment succeeds, you'll receive a 200 response with the enriched data: **Email Only:** ```json theme={null} { "enrichment_id": "123e4567-e89b-12d3-a456-426614174000", "first_name": "Mathieu", "last_name": "Brun-Picard", "linkedin_profile_url": "https://www.linkedin.com/in/mathieu-brun-picard/", "status": "success", "email": "mathieu@prontohq.com", "email_status": "valid" } ``` **Phone Only:** ```json theme={null} { "enrichment_id": "123e4567-e89b-12d3-a456-426614174000", "first_name": "Mathieu", "last_name": "Brun-Picard", "linkedin_profile_url": "https://www.linkedin.com/in/mathieu-brun-picard/", "status": "success", "phones": [ "+33612345678" ], "phone_status": "valid" } ``` **Email and Phone:** ```json theme={null} { "enrichment_id": "123e4567-e89b-12d3-a456-426614174000", "first_name": "Mathieu", "last_name": "Brun-Picard", "linkedin_profile_url": "https://www.linkedin.com/in/mathieu-brun-picard/", "status": "success", "email": "mathieu@prontohq.com", "email_status": "valid", "phones": [ "+33612345678" ], "phone_status": "valid" } ``` **Personal Email Only:** ```json theme={null} { "enrichment_id": "123e4567-e89b-12d3-a456-426614174000", "first_name": "Mathieu", "last_name": "Brun-Picard", "linkedin_profile_url": "https://www.linkedin.com/in/mathieu-brun-picard/", "status": "success", "personal_email": "mathieu.bp@gmail.com", "personal_email_status": "valid" } ``` ### Error Response When no data is found, the response includes a message and empty data fields: ```json theme={null} { "enrichment_id": "123e4567-e89b-12d3-a456-426614174000", "first_name": "Mathieu", "last_name": "Brun-Picard", "linkedin_profile_url": "https://www.linkedin.com/in/mathieu-brun-picard/", "status": "error", "message": "No email or phone found for this profile", "email": null, "email_status": "N/A", "phones": [], "phone_status": "not_found" } ``` ## Required Fields `enrichment_type` is always required — an array containing any combination of `"email"`, `"phone"`, and/or `"personal_email"`. The other required fields depend on which types you request: | `enrichment_type` value | Additional required fields | | ----------------------- | ----------------------------------------------------------------------------------- | | `"email"` | `firstname`, `lastname`, **and** one of `linkedin_url`, `domain`, or `company_name` | | `"phone"` | `linkedin_url` | | `"personal_email"` | `linkedin_url` | `firstname`/`lastname` are only needed when you request `"email"`; phone and personal email run off the `linkedin_url` alone. When you request a combination, the requirements add up — but a single `linkedin_url` satisfies the identifier requirement for all three types. For example, `["email", "phone"]` needs `firstname`, `lastname`, and a `linkedin_url` (the `linkedin_url` covers both the email and phone steps). ## Recommended Fields Beyond the required fields, supplying more context improves accuracy: * `linkedin_url` - LinkedIn profile URL (highly recommended for accuracy; on its own it satisfies every enrichment type) * `domain` / `company_name` - Company context that improves professional email matching when you don't have a `linkedin_url`. The more context you provide, the higher the accuracy of the enrichment. ## Custom Fields You can include custom fields that will be returned in the response: ```json theme={null} { "firstname": "Mathieu", "lastname": "Brun-Picard", "linkedin_url": "https://www.linkedin.com/in/mathieu-brun-picard/", "enrichment_type": ["email"], "custom": { "crm_id": "12345", "campaign": "outbound_q1", "segment": "enterprise" } } ``` These custom fields are passed through unchanged and returned in the `custom` field of the response, making it easy to correlate results with your internal systems. ## Email Status Values The `email_status` field indicates the validation state of the email: * `deliverable` - Email is deliverable * `catch-all` - Email hasa catch-all status but was validated by our debouncing waterfall * `N/A` - Email enrichment was not requested or no email was found ## Personal Email Status Values The `personal_email_status` field indicates the validation state of the personal email: * `valid` - Personal email was found and validated * `invalid` - Personal email enrichment ran but the result is not deliverable * `N/A` - Personal email enrichment was not requested or no personal email was found ## Phone Status Values The `phone_status` field indicates whether valid phone numbers were found: * `valid` - At least one valid phone number found * `not_found` - No phone numbers found or phone enrichment not requested ## Pricing Each enrichment request consumes credits based on the enrichment type requested and the providers used. Check your account credits using the [Account Credits endpoint](/api-reference/endpoints/miscellaneous/account-credits). Credits are checked before the waterfall runs. If your balance cannot cover the enrichment the request is rejected with `402 Payment Required` and `code: "insufficient_credits"` (the response carries a `top_up_url`); if it would exceed your workspace weekly credit limit, with `403 Forbidden` and `code: "workspace_limit_exceeded"`. No provider is called and nothing is spent in either case. See [Credit and limit errors](/api-reference/errors). # Bulk Contact Enrichment Source: https://docs.pipecorn.com/api-reference/endpoints/enrichments/batch POST /contacts/bulk_enrich Enrich up to 100 contacts in a single asynchronous batch Enqueue up to **100 contacts** for waterfall enrichment in a single request. The endpoint returns immediately with an `enrichment_id` for the bulk job; each contact is enriched asynchronously and results are delivered to your `webhook_url` as each contact completes. ## Constraints * **Minimum:** 2 contacts per request. For a single contact, use the [single async endpoint](/api-reference/endpoints/enrichments/single). * **Maximum:** 100 contacts per request. * A single `enrichment_type` applies to every contact in the batch. ## Enrichment Types Pass `enrichment_type` as an array containing one of: * `["email"]` — Find and validate professional emails * `["phone"]` — Find phone numbers (requires `linkedin_url` on every contact) * `["personal_email"]` — Find personal emails (requires `linkedin_url` **and** account-level consent — see below) Requesting `personal_email` requires the authenticated user to have consented to personal email enrichment in their account settings. If consent is missing the entire batch is rejected with `422 Unprocessable Entity`. This consent gate is required for GDPR compliance. ## Required Fields per contact The required per-contact fields depend on the batch-wide `enrichment_type`: | `enrichment_type` | Required fields per contact | | -------------------- | ----------------------------------------------------------------------------------- | | `["email"]` | `firstname`, `lastname`, **and** one of `linkedin_url`, `domain`, or `company_name` | | `["phone"]` | `linkedin_url` | | `["personal_email"]` | `linkedin_url` | Phone and personal email batches run off each contact's `linkedin_url` alone, so `firstname`/`lastname` are not required for those types. ## Receiving results Provide `webhook_url` to receive results — we POST one payload per contact as each one finishes. The webhook payload echoes the `custom` fields you sent with that contact, so you can correlate results back to your records. ## Credits Credits are checked up-front for the entire batch. If your balance is insufficient the request is rejected with `402 Payment Required` and `code: "insufficient_credits"`, and no contacts are enqueued — the response carries a `top_up_url` you can send the user to. If the batch would exceed your workspace weekly credit limit, the request is rejected with `403 Forbidden` and `code: "workspace_limit_exceeded"` instead; buying credits does not lift that limit. See [Credit and limit errors](/api-reference/errors). # Asynchronous Single Contact Enrichment Source: https://docs.pipecorn.com/api-reference/endpoints/enrichments/single enrichments POST /contacts/single_enrich Enrich a single contact record with email, phone, and / or personal email data Enqueue a single contact for waterfall enrichment. The endpoint returns immediately with an `enrichment_id` and `status: "pending"`; the waterfall runs asynchronously in the background. ## When to use this endpoint Use the async endpoint when: * You can accept results via webhook, or you can poll for them later. * You're enriching at scale and don't want to hold an HTTP connection per contact. * You want to retain the enrichment result on the contact record for later retrieval via [`GET /contacts/{id}`](/api-reference/endpoints/contacts/single_enrich). If you need results inline (Chrome extension, interactive UI, real-time workflow), use the [synchronous endpoint](/api-reference/endpoints/contacts/sync_single_enrich) instead. ## Enrichment Types Pass `enrichment_type` as an array containing one of: * `["email"]` — Find and validate the professional email * `["phone"]` — Find phone numbers (requires `linkedin_url`) * `["personal_email"]` — Find a personal email (requires `linkedin_url` **and** account-level consent — see below) Requesting `personal_email` requires the authenticated user to have consented to personal email enrichment in their account settings. If consent is missing, the API responds with `422 Unprocessable Entity` and the message `"You can't use the personal email enrichment feature without consenting with our terms of use"`. This consent gate is required for GDPR compliance. ## Required Fields `enrichment_type` is always required. The other required fields depend on its value (the **Body** section below shows this per type): | `enrichment_type` | Additional required fields | | -------------------- | ----------------------------------------------------------------------------------- | | `["email"]` | `firstname`, `lastname`, **and** one of `linkedin_url`, `domain`, or `company_name` | | `["phone"]` | `linkedin_url` | | `["personal_email"]` | `linkedin_url` | Email enrichment needs the contact's name plus at least one identifier — a `linkedin_url` on its own is enough, or company context (`domain` or `company_name`). Phone and personal email enrichment run off the `linkedin_url` alone, so `firstname`/`lastname` are not required for them. ## Receiving results You have two options: 1. **Webhook** — pass `webhook_url` in the request. We POST the final result to that URL once the waterfall completes. 2. **Polling** — call [`GET /contacts/{id}`](/api-reference/endpoints/contacts/single_enrich) with the returned `enrichment_id`. While the waterfall is running the `status` is `pending`; once it has completed (with or without data) the `status` flips to `finished`. ## Custom Fields Pass `custom: { ... }` in the request to attach arbitrary correlation data (e.g. your CRM record ID). The same payload is echoed back on `GET /contacts/{id}` and on the webhook callback. ## Pricing Each enrichment consumes credits based on the requested `enrichment_type` and the providers used. Check your account credits via the [Account Credits endpoint](/api-reference/endpoints/miscellaneous/account-credits). Credits are checked before the contact is enqueued. If your balance cannot cover the enrichment the request is rejected with `402 Payment Required` and `code: "insufficient_credits"` (the response carries a `top_up_url`); if it would exceed your workspace weekly credit limit, with `403 Forbidden` and `code: "workspace_limit_exceeded"`. Nothing is enqueued in either case. See [Credit and limit errors](/api-reference/errors). # Account search Source: https://docs.pipecorn.com/api-reference/endpoints/extract/accounts POST /accounts/ Extract company accounts from a LinkedIn Sales Navigator search URL and process them asynchronously. **Rate limit:** 1 request per second This endpoint creates an import job that will process the search results in the background. Results will be sent to the specified webhook URL when processing is complete. Extract company accounts from LinkedIn Sales Navigator search results and process them asynchronously. This endpoint creates an import job that will process the search results in the background and send the results to your specified webhook URL when complete. ## Overview This endpoint allows you to extract company data from LinkedIn Sales Navigator search URLs. The process is asynchronous - you'll receive an immediate response with the import job details, and the actual results will be sent to your webhook URL when processing is complete. ## Rate Limits * **1 request per second** per user/IP address # People search Source: https://docs.pipecorn.com/api-reference/endpoints/extract/leads POST /leads Initiates a new lead search based on the provided parameters. **Rate limit:** 1 request per second ## Scale Parameter The `scale` parameter (boolean, optional) allows you to increase your volume of requests by omitting the following fields: * `connections_count` * `headline` * Vanity LinkedIn profile URL (like `https://www.linkedin.com/in/mathieu-brun-picard/`) When `scale` is set to `true`, you will still receive a LinkedIn profile URL, but it will use the user ID instead of the vanity URL format (like `https://linkedin.com/in/ACwAACaX8uYBfAh-5YxmfObz4mVOKYih3zxa-TM`). # Find people at company Source: https://docs.pipecorn.com/api-reference/endpoints/extract/leads_from_company POST /leads/search Searches for leads based on job titles and a company (LinkedIn company ID or URL). Optionally narrow results by location, LinkedIn **function** (department), and **seniority** level using the authorized ID lists below. By default the search runs live through LinkedIn (`live: true`) and requires a connected integration. Set `live: false` to resolve the company and matching people from Pipecorn's people database (Elasticsearch) instead, with no LinkedIn call and no integration required. # Find 2x people than with Clay * Input : Job titles + Company * Output : Live matching people data