Query leads
Search the leads of the workspace, a page at a time.
Returns the leads of your workspace, sorted by creation date, most recent first by default. It returns 25 leads per page by default: set limit (up to 100) to get more or fewer. Each item has the shape of Get a lead.
All filters are optional. An empty body returns the first page of every lead. A search that matches nothing answers 200 OK with an empty data list.
The list holds the leads your Sillage dashboard shows, not every lead of the workspace: prospects only. It leaves out your own and your clients' employees, influencers, people from competitor or partner lists, expired leads, leads without a profile, and leads rated outside your ideal customer profile or not yet rated. This is why a count can differ from the number of contacts in your CRM. Get a lead still returns any lead of the workspace by its ID.
Route
Access modes
Use a workspace API key. The workspace is inferred from the key.
Authorization: Bearer sk_live_...Body parameters
Send the filters as a JSON body, so lists of identifiers are not limited by the length of a URL. The four company filters add up: a lead matches when its company is any of the company_ids, domains, LinkedIn handles or LinkedIn URLs you send. A value that matches no company in your workspace matches nothing, so the answer is an empty list, never an error. Company filters combine with every other filter, and all of those have to match.
| Parameter | Type | Description |
|---|---|---|
| cursor | string | The meta.cursor.next of the previous response, to fetch the next page. Leave it out for the first page. It only works with the filters and sort it was issued for: reused with others, sent empty, or not issued to you by this search, it is refused with 422. |
| limit | integer | Number of leads per page, from 1 to 100. Defaults to 25. |
| sort | string | created_at:desc (default) or created_at:asc. |
| created_at_from | string | Only leads created at or after this moment, the moment itself included. ISO 8601 date and time with a UTC offset, for example 2026-09-01T00:00:00Z. A date without a time is refused with 422. |
| created_at_to | string | Only leads created at or before this moment, the moment itself included. ISO 8601 date and time with a UTC offset, for example 2026-09-30T23:59:59Z. A date without a time is refused with 422. |
| company_ids | array of integer | Only leads whose company is one of these companies. Up to 100 company IDs, as returned by the company endpoints and by a lead's company.id. |
| company_domains | array of string | Only leads whose company has one of these website domains, for example acme.com. Up to 100 values. |
| company_linkedin_handles | array of string | Only leads whose company has one of these LinkedIn handles (the last part of the LinkedIn page address). Up to 100 values. |
| company_linkedin_urls | array of string | Only leads whose company has one of these LinkedIn page URLs. Up to 100 values. |
| countries | array of string | Only leads located in one of these countries, for example ["France", "Germany"]. Up to 100 values. Combined with cities: a lead matches when it is in one of the countries or one of the cities. |
| cities | array of object | Only leads located in one of these cities. Each city is an object { "name", "country" }, so Paris, France and Paris, United States stay distinct. Up to 100 values. |
Paging
This search pages with a cursor: pass meta.cursor.next as cursor on the next request, until meta.cursor.has_more is false. See Pagination.
Example request
This call returns the leads created since 1 September 2026 whose company is acme.com and who are located in France.
curl -X POST "https://api.getsillage.com/api/v3/leads/query" \
-H "Authorization: Bearer $SILLAGE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"limit": 25,
"company_domains": [
"acme.com"
],
"created_at_from": "2026-09-01T00:00:00Z",
"countries": [
"France"
]
}'Success response
Status: 200 OK
{
"data": [
{
"id": 123,
"full_name": "Jane Doe",
"first_name": "Jane",
"last_name": "Doe",
"linkedin_url": "https://www.linkedin.com/in/janedoe",
"linkedin_handle": "janedoe",
"linkedin_headline": "VP Sales at Acme",
"avatar_url": "https://example.com/avatar.png",
"email": "jane.doe@acme.com",
"phone": "+33 1 23 45 67 89",
"position": "VP Sales",
"location": {
"city": "Paris",
"region": "Île-de-France",
"country": "France",
"country_code": "FR"
},
"company": {
"id": 789,
"name": "Acme",
"domain": "acme.com",
"linkedin_url": "https://www.linkedin.com/company/acme",
"linkedin_handle": "acme",
"logo_url": "https://example.com/acme-logo.png",
"activity_summary": "Acme builds enterprise sales software.",
"employee_range": "201-500",
"location": {
"city": "Paris",
"region": "Île-de-France",
"country": "France",
"country_code": "FR"
},
"in_key_account_list": true
},
"experiences": [
{
"position": "VP Sales",
"company_name": "Acme",
"company_linkedin_url": "https://www.linkedin.com/company/acme",
"location": "Paris, France",
"start_date": "2022-03-01",
"end_date": null,
"is_current": true
},
{
"position": "Sales Director",
"company_name": "Globex",
"company_linkedin_url": "https://www.linkedin.com/company/globex",
"location": "Lyon, France",
"start_date": "2018-06-01",
"end_date": "2022-02-01",
"is_current": false
}
],
"status": "meeting_booked",
"owner": {
"email": "sam@acme.com",
"first_name": "Sam",
"last_name": "Martin"
},
"crm_records": [
{
"provider": "salesforce",
"contact_id": "003xx000004TMMaBC",
"account_id": "001xx000008ABCdEF"
}
],
"created_at": "2026-09-14T09:12:44.000Z"
}
],
"meta": {
"cursor": {
"next": "eyJ2IjoxfQ.MTIz",
"has_more": true
},
"resolved_companies": [
{
"company": {
"id": 789,
"name": "Acme",
"domain": "acme.com",
"linkedin_url": "https://www.linkedin.com/company/acme",
"linkedin_handle": "acme",
"logo_url": "https://example.com/acme-logo.png"
},
"matched_by": "company_domains",
"identifier": "acme.com"
}
]
}
}Response fields
| Field | Type | Description |
|---|---|---|
| data | array | The leads of this page. |
| meta.cursor.next | string or null | Pass it as cursor to fetch the next page. null on the last page. |
| meta.cursor.has_more | boolean | Whether more leads exist after this page. |
| meta.resolved_companies | array | The companies your company filters matched, each with the filter value that matched it. Empty when you sent no company filter. |
| meta.resolved_companies[].company | object | The matched company, as a summary: id (its ID in your workspace), name, domain, linkedin_url, linkedin_handle and logo_url. |
| meta.resolved_companies[].matched_by | string | Which filter matched: company_ids, company_domains, company_linkedin_handles or company_linkedin_urls. |
| meta.resolved_companies[].identifier | string | The value you sent that matched. |
Each item of data has the fields below.
| Field | Type | Description |
|---|---|---|
| data[].id | integer | ID of the lead. |
| data[].full_name | string or null | Lead's full name. |
| data[].created_at | string or null | When the lead was added to the workspace, as an ISO 8601 timestamp. The list is sorted on it. |
| data[].first_name | string or null | Lead's first name. |
| data[].last_name | string or null | Lead's last name. |
| data[].linkedin_url | string or null | LinkedIn profile URL. |
| data[].linkedin_handle | string or null | LinkedIn profile handle. |
| data[].linkedin_headline | string or null | LinkedIn headline. |
| data[].avatar_url | string or null | Profile picture URL. |
| data[].email | string or null | Lead's email address, when known. |
| data[].phone | string or null | Lead's phone number, when known. |
| data[].position | string or null | Job title. |
| data[].location | object or null | Lead's location. null when no location could be resolved. See Location. |
| data[].company | object or null | The lead's current company, or null when the lead has no current company. |
| data[].company.id | integer | ID of the company in the workspace, usable with Get a company. |
| data[].company.name | string or null | Company name. |
| data[].company.domain | string or null | Primary domain. |
| data[].company.linkedin_url | string or null | LinkedIn company page URL. |
| data[].company.linkedin_handle | string or null | LinkedIn company handle. |
| data[].company.logo_url | string or null | Logo of the company. |
| data[].company.activity_summary | string or null | Short summary of what the company does. |
| data[].company.employee_range | string or null | Employee headcount range, one of the persona headcounts values: 1-10, 11-50, 51-200, 201-500, 501-1,000, 1,001-5,000, 5,001-10,000 or 10,001+. null when unknown. |
| data[].company.location | object or null | The company's headquarters. See Location. |
| data[].company.in_key_account_list | boolean | true when this company is on one of your customer or prospect lists. |
| data[].experiences | array | The lead's work history, in the order of their LinkedIn profile and including the current position. An empty array when no work history is known. |
| data[].experiences[].position | string or null | Job title held in that position. null when unknown, never an empty string. |
| data[].experiences[].company_name | string or null | Name of the employer. null when unknown, never an empty string. |
| data[].experiences[].company_linkedin_url | string or null | The employer's LinkedIn page, when known. |
| data[].experiences[].location | string or null | The job's location as written on LinkedIn (free text). null when unknown, never an empty string. |
| data[].experiences[].start_date | string or null | When the position started, as a date without a time (YYYY-MM-DD). The source may only carry a month or a year, so treat it as approximate. |
| data[].experiences[].end_date | string or null | When the position ended, as a date without a time (YYYY-MM-DD). null for the current position or when unknown. |
| data[].experiences[].is_current | boolean | true for the lead's current position. |
| data[].status | string or null | Where the lead stands in your pipeline: see Pipeline status. null when no status is set. |
| data[].owner | object or null | The workspace member assigned to the lead, or null when unassigned. |
| data[].owner.email | string | The member's email address. |
| data[].owner.first_name | string or null | The member's first name. |
| data[].owner.last_name | string or null | The member's last name. |
| data[].crm_records | array | The CRM records Sillage has matched the lead to, one item per CRM. Empty when the lead is not matched to a contact in any of your CRMs. |
| data[].crm_records[].provider | string | The CRM, salesforce or hubspot. More CRMs may be added, so ignore values you do not handle. |
| data[].crm_records[].contact_id | string or null | The lead's Contact ID in this CRM. |
| data[].crm_records[].account_id | string or null | The ID of the Account associated with the contact in this CRM. null when the contact has no associated account. |
Location
Every location in this API has the same shape: { "city", "region", "country", "country_code" }. Any part is null when it is not known, and the whole location is null when nothing could be resolved. country_code is the ISO country code, for example FR. This is a valid response, not an error.
Errors
| Status | Meaning |
|---|---|
| 401 | The API key is missing or invalid. |
| 422 | A filter is not known or not valid, a date has no time, or the cursor was not issued to you by this search, was issued for other filters or another sort, or is empty. A range that ends before it starts (created_at_from after created_at_to) is refused with the code invalid_date_range; errors.created_at_from says "must be on or before created_at_to". |
| 429 | Rate limit exceeded. |
| 500 | An unexpected server error occurred. |
Error responses use RFC 9457 problem documents with Content-Type: application/problem+json. type is always about:blank; code tells one problem from another, detail says what went wrong this time, and errors names the field at fault.