curl --request GET \
--url https://api.lemlist.com/api/contacts \
--header 'Authorization: Basic <encoded-value>'import requests
url = "https://api.lemlist.com/api/contacts"
headers = {"Authorization": "Basic <encoded-value>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Basic <encoded-value>'}};
fetch('https://api.lemlist.com/api/contacts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));require 'uri'
require 'net/http'
url = URI("https://api.lemlist.com/api/contacts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Basic <encoded-value>'
response = http.request(request)
puts response.read_body<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.lemlist.com/api/contacts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Basic <encoded-value>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}Get Many Contacts
Retrieves contacts from your CRM. Use idsOrEmails to fetch specific contacts by ID or email in a single request (max 100), crmIds to find them from their record id in your connected CRM, or omit them to search/list contacts by name, email, contact list, or campaign membership.
curl --request GET \
--url https://api.lemlist.com/api/contacts \
--header 'Authorization: Basic <encoded-value>'import requests
url = "https://api.lemlist.com/api/contacts"
headers = {"Authorization": "Basic <encoded-value>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Basic <encoded-value>'}};
fetch('https://api.lemlist.com/api/contacts', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));require 'uri'
require 'net/http'
url = URI("https://api.lemlist.com/api/contacts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Basic <encoded-value>'
response = http.request(request)
puts response.read_body<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.lemlist.com/api/contacts",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Basic <encoded-value>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}Query modes
This endpoint supports the following query modes:| Mode | Parameters | Response format |
|---|---|---|
| By IDs/emails | idsOrEmails | Array of Contact |
| By CRM record ids | crmIds | Array of Contact, the ones found |
| Search/filter | search, email, listId, and/or notInAnyCampaign | Paginated object with data, total, limit, offset, where data holds ContactListItem objects |
idsOrEmails takes precedence over crmIds. A lookup ignores the search filters and the pagination.
Response shapes
- A lookup (
idsOrEmails,crmIds) returns fullContactobjects: fields underfields, campaigns with their lead id, andcrmSyncwhen the contact has a record in the connected CRM. - The list returns
ContactListItemobjects.
idsOrEmails answers 404 and crmIds answers 200 with an empty array.
Finding a contact from your CRM
UsecrmIds (up to 100, comma-separated) with the record ids of your connected CRM, for example GET /contacts?crmIds=123456789 with a HubSpot contact id; for Salesforce, pass the 18-character Contact or Lead id. Each contact found carries the matched id under crmSync.crmRecordId; ids that match nothing are skipped.
Filtering by contact list
Use thelistId parameter to retrieve contacts belonging to a specific list. Get valid list IDs from GET /contacts/lists.
You can combine listId with search or email to further narrow results within a list.
Filtering contacts not in any campaign
UsenotInAnyCampaign=true to find contacts that are not part of any campaign (orphan contacts). This can be used alone or combined with other filters like search, email, or listId.Authorizations
Basic authentication header of the form Basic <encoded-value>, where <encoded-value> is the base64-encoded string username:password.
Query Parameters
A comma separated string of either valid contact IDs (MongoDB ObjectId) or valid email addresses. Optional — when omitted, returns the paginated list of all contacts of the team. Maximum 100 values.
Comma-separated record ids of contacts in the CRM connected to the team (HubSpot, Salesforce, or Pipedrive); for Salesforce, the 18-character Contact or Lead id. Returns an array of the contacts found, each with the matched id under crmSync.crmRecordId; ids that match nothing are skipped, and the array is empty when no CRM is connected. Duplicates are removed; an empty value is ignored. Maximum 100 values (TOO_MANY_CRM_IDS); a value over 25 characters answers INVALID_CRM_ID. Ignored when idsOrEmails is provided.
Search contacts by name or other text fields. Must be at least 2 characters.
Search contacts by exact email address.
Filter contacts by contact list ID (clt_xxx format). Can be combined with search or email, or used alone to list all contacts in a list. Get valid IDs from GET /contacts/lists.
^clt_[a-zA-Z0-9]+$When set to true, only returns contacts that are not part of any campaign (orphan contacts). Can be used alone or combined with other filters such as search, email, or listId.
Filter contacts by attached company ID (cpn_xxx format). Use this when you already know the lemlist company id (for example after fetching GET /companies?crmSyncStatus=unique_index_error_company). Mutually exclusive with companyDomain, companyLinkedinUrl, and companySalesnavUrl.
^cpn_[a-zA-Z0-9]+$Filter contacts by their company's website domain. Resolved to a companyId against the Companies collection. If no company matches, the endpoint returns an empty list (total: 0). Mutually exclusive with the other company* filters.
Filter contacts by their company's LinkedIn URL. Resolved to a companyId against the Companies collection. If no company matches, the endpoint returns an empty list (total: 0). Mutually exclusive with the other company* filters.
Filter contacts by their company's LinkedIn Sales Navigator URL. Resolved to a companyId against the Companies collection. If no company matches, the endpoint returns an empty list (total: 0). Mutually exclusive with the other company* filters.
When set to true, only returns contacts linked to a company; when set to false, only returns contacts without a company. Omit for no filter. Mutually exclusive with the company* filters (companyId, companyDomain, companyLinkedinUrl, companySalesnavUrl).
Filter contacts to those carrying a field rejection with this reason — a value lemlist refused to write, prefixed by its origin (enrichment_* while enriching, crm_sync_* during CRM sync). Returns an empty list (total: 0) when no contact matches. Each returned contact exposes the full detail under fieldRejections[] (which field, why, and conflictingRecordId for duplicates). Only applies to the paginated list — ignored when idsOrEmails is provided (that path returns the exact contacts requested, unfiltered).
enrichment_duplicate_linkedin_url, enrichment_duplicate_linkedin_url_sales_nav, enrichment_duplicate_email, crm_sync_duplicate_linkedin_url, crm_sync_duplicate_linkedin_url_sales_nav, crm_sync_invalid_linkedin_url, crm_sync_invalid_url, crm_sync_invalid_email, crm_sync_invalid_phone, crm_sync_linkedin_url_not_contact, crm_sync_duplicate_contact_blocked, crm_sync_duplicate_company_blocked, crm_sync_company_data_rejected, crm_sync_unsub_state_protected, crm_sync_value_oscillating, crm_sync_owner_sync_loop, crm_sync_unmapped_user, crm_sync_value_incompatible, crm_sync_unknown_error Maximum number of contacts to return (1–500). Defaults to 100.
1 <= x <= 500Number of contacts to skip for pagination. Defaults to 0.
x >= 0Response
Success. When using idsOrEmails or crmIds, returns an array of contacts (empty when no crmIds value matches). Otherwise, returns a paginated object with data (ContactListItem items), total, limit, and offset.
- Lookup by idsOrEmails or crmIds · object[]
- List · object
A contact record in your CRM, as the lookups (GET /contacts?idsOrEmails=, GET /contacts?crmIds=, GET /contacts/{idOrEmail}) return it. Not to be confused with a lead which is a contact specifically added to a campaign.
Unique contact identifier
Team identifier the contact belongs to
Contact's calculated full name
Contact's primary email address
Contact fields, standard (firstName, lastName, phone, jobTitle...) and custom
List of campaigns the contact is associated with
Show child attributes
Show child attributes
Contact's LinkedIn profile URL
Contact's LinkedIn Sales Navigator URL
ID of the user who owns this contact
Contact creation timestamp
ID of the user who created the contact
Whether the contact is globally unsubscribed. When true, no outreach will be sent to this contact.
Verification status of each verified phone number.
Show child attributes
Show child attributes
CRM sync status for the contact, resolved against the team's active CRM provider (Hubspot, Salesforce, or Pipedrive). Only present when a CRM is connected and the contact has a record in it. crmRecordId maps a crmIds lookup back to the ids sent.
Show child attributes
Show child attributes
Values lemlist refused to write on this contact, each with its reason. Empty when none. Filter the list endpoint to only flagged contacts via GET /contacts?fieldRejectionReason=....
Show child attributes
Show child attributes
Was this page helpful?