Create ICP
curl --request POST \
--url https://api.example.com/api/v1/entities/icps \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"description": {},
"leadProviderCriteria": [
{
"provider": "<string>",
"type": "<string>",
"filters": {}
}
],
"customFilterCriteria": [
{}
],
"crmFilters": {
"provider": "<string>",
"textSearch": {},
"query": {},
"filters": [
{
"path": "<string>",
"mode": "<string>",
"value": {},
"exclude": true
}
]
},
"userIds": [
{}
],
"leadsPerList": 123,
"activeUntil": {}
}
'import requests
url = "https://api.example.com/api/v1/entities/icps"
payload = {
"name": "<string>",
"description": {},
"leadProviderCriteria": [
{
"provider": "<string>",
"type": "<string>",
"filters": {}
}
],
"customFilterCriteria": [{}],
"crmFilters": {
"provider": "<string>",
"textSearch": {},
"query": {},
"filters": [
{
"path": "<string>",
"mode": "<string>",
"value": {},
"exclude": True
}
]
},
"userIds": [{}],
"leadsPerList": 123,
"activeUntil": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
description: {},
leadProviderCriteria: [{provider: '<string>', type: '<string>', filters: {}}],
customFilterCriteria: [{}],
crmFilters: {
provider: '<string>',
textSearch: {},
query: {},
filters: [{path: '<string>', mode: '<string>', value: {}, exclude: true}]
},
userIds: [{}],
leadsPerList: 123,
activeUntil: {}
})
};
fetch('https://api.example.com/api/v1/entities/icps', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/entities/icps",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'description' => [
],
'leadProviderCriteria' => [
[
'provider' => '<string>',
'type' => '<string>',
'filters' => [
]
]
],
'customFilterCriteria' => [
[
]
],
'crmFilters' => [
'provider' => '<string>',
'textSearch' => [
],
'query' => [
],
'filters' => [
[
'path' => '<string>',
'mode' => '<string>',
'value' => [
],
'exclude' => true
]
]
],
'userIds' => [
[
]
],
'leadsPerList' => 123,
'activeUntil' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/entities/icps"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"description\": {},\n \"leadProviderCriteria\": [\n {\n \"provider\": \"<string>\",\n \"type\": \"<string>\",\n \"filters\": {}\n }\n ],\n \"customFilterCriteria\": [\n {}\n ],\n \"crmFilters\": {\n \"provider\": \"<string>\",\n \"textSearch\": {},\n \"query\": {},\n \"filters\": [\n {\n \"path\": \"<string>\",\n \"mode\": \"<string>\",\n \"value\": {},\n \"exclude\": true\n }\n ]\n },\n \"userIds\": [\n {}\n ],\n \"leadsPerList\": 123,\n \"activeUntil\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/api/v1/entities/icps")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"description\": {},\n \"leadProviderCriteria\": [\n {\n \"provider\": \"<string>\",\n \"type\": \"<string>\",\n \"filters\": {}\n }\n ],\n \"customFilterCriteria\": [\n {}\n ],\n \"crmFilters\": {\n \"provider\": \"<string>\",\n \"textSearch\": {},\n \"query\": {},\n \"filters\": [\n {\n \"path\": \"<string>\",\n \"mode\": \"<string>\",\n \"value\": {},\n \"exclude\": true\n }\n ]\n },\n \"userIds\": [\n {}\n ],\n \"leadsPerList\": 123,\n \"activeUntil\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/entities/icps")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"description\": {},\n \"leadProviderCriteria\": [\n {\n \"provider\": \"<string>\",\n \"type\": \"<string>\",\n \"filters\": {}\n }\n ],\n \"customFilterCriteria\": [\n {}\n ],\n \"crmFilters\": {\n \"provider\": \"<string>\",\n \"textSearch\": {},\n \"query\": {},\n \"filters\": [\n {\n \"path\": \"<string>\",\n \"mode\": \"<string>\",\n \"value\": {},\n \"exclude\": true\n }\n ]\n },\n \"userIds\": [\n {}\n ],\n \"leadsPerList\": 123,\n \"activeUntil\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "DACH Tech Leaders",
"description": "Technology leaders in German-speaking regions",
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z",
"leadProviderCriteria": [
{
"provider": "baseProvider",
"type": "person",
"filters": {
"job_title": ["CTO", "VP Engineering", "Head of Technology"],
"location": {
"country": ["Germany", "Austria", "Switzerland"]
},
"company": {
"employee_size": {
"min": 100,
"max": 5000
}
}
}
}
],
"customFilterCriteria": [
{
"type": "maxPeoplePerCompany",
"value": 2
}
],
"crmFilters": null,
"userIds": ["user_abc123"],
"leadsPerList": 20,
"activeUntil": null
}
{
"error": {
"code": "BAD_REQUEST",
"message": "Invalid request body",
"details": [
{
"path": ["name"],
"message": "Required"
}
]
}
}
{
"error": {
"code": "UNAUTHORIZED",
"message": "User not authenticated"
}
}
ICPs
Create ICP
Creates a new Ideal Customer Profile (ICP) for lead targeting
POST
/
api
/
v1
/
entities
/
icps
Create ICP
curl --request POST \
--url https://api.example.com/api/v1/entities/icps \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"description": {},
"leadProviderCriteria": [
{
"provider": "<string>",
"type": "<string>",
"filters": {}
}
],
"customFilterCriteria": [
{}
],
"crmFilters": {
"provider": "<string>",
"textSearch": {},
"query": {},
"filters": [
{
"path": "<string>",
"mode": "<string>",
"value": {},
"exclude": true
}
]
},
"userIds": [
{}
],
"leadsPerList": 123,
"activeUntil": {}
}
'import requests
url = "https://api.example.com/api/v1/entities/icps"
payload = {
"name": "<string>",
"description": {},
"leadProviderCriteria": [
{
"provider": "<string>",
"type": "<string>",
"filters": {}
}
],
"customFilterCriteria": [{}],
"crmFilters": {
"provider": "<string>",
"textSearch": {},
"query": {},
"filters": [
{
"path": "<string>",
"mode": "<string>",
"value": {},
"exclude": True
}
]
},
"userIds": [{}],
"leadsPerList": 123,
"activeUntil": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
description: {},
leadProviderCriteria: [{provider: '<string>', type: '<string>', filters: {}}],
customFilterCriteria: [{}],
crmFilters: {
provider: '<string>',
textSearch: {},
query: {},
filters: [{path: '<string>', mode: '<string>', value: {}, exclude: true}]
},
userIds: [{}],
leadsPerList: 123,
activeUntil: {}
})
};
fetch('https://api.example.com/api/v1/entities/icps', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/entities/icps",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'description' => [
],
'leadProviderCriteria' => [
[
'provider' => '<string>',
'type' => '<string>',
'filters' => [
]
]
],
'customFilterCriteria' => [
[
]
],
'crmFilters' => [
'provider' => '<string>',
'textSearch' => [
],
'query' => [
],
'filters' => [
[
'path' => '<string>',
'mode' => '<string>',
'value' => [
],
'exclude' => true
]
]
],
'userIds' => [
[
]
],
'leadsPerList' => 123,
'activeUntil' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/entities/icps"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"description\": {},\n \"leadProviderCriteria\": [\n {\n \"provider\": \"<string>\",\n \"type\": \"<string>\",\n \"filters\": {}\n }\n ],\n \"customFilterCriteria\": [\n {}\n ],\n \"crmFilters\": {\n \"provider\": \"<string>\",\n \"textSearch\": {},\n \"query\": {},\n \"filters\": [\n {\n \"path\": \"<string>\",\n \"mode\": \"<string>\",\n \"value\": {},\n \"exclude\": true\n }\n ]\n },\n \"userIds\": [\n {}\n ],\n \"leadsPerList\": 123,\n \"activeUntil\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/api/v1/entities/icps")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"description\": {},\n \"leadProviderCriteria\": [\n {\n \"provider\": \"<string>\",\n \"type\": \"<string>\",\n \"filters\": {}\n }\n ],\n \"customFilterCriteria\": [\n {}\n ],\n \"crmFilters\": {\n \"provider\": \"<string>\",\n \"textSearch\": {},\n \"query\": {},\n \"filters\": [\n {\n \"path\": \"<string>\",\n \"mode\": \"<string>\",\n \"value\": {},\n \"exclude\": true\n }\n ]\n },\n \"userIds\": [\n {}\n ],\n \"leadsPerList\": 123,\n \"activeUntil\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/entities/icps")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"description\": {},\n \"leadProviderCriteria\": [\n {\n \"provider\": \"<string>\",\n \"type\": \"<string>\",\n \"filters\": {}\n }\n ],\n \"customFilterCriteria\": [\n {}\n ],\n \"crmFilters\": {\n \"provider\": \"<string>\",\n \"textSearch\": {},\n \"query\": {},\n \"filters\": [\n {\n \"path\": \"<string>\",\n \"mode\": \"<string>\",\n \"value\": {},\n \"exclude\": true\n }\n ]\n },\n \"userIds\": [\n {}\n ],\n \"leadsPerList\": 123,\n \"activeUntil\": {}\n}"
response = http.request(request)
puts response.read_body{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "DACH Tech Leaders",
"description": "Technology leaders in German-speaking regions",
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z",
"leadProviderCriteria": [
{
"provider": "baseProvider",
"type": "person",
"filters": {
"job_title": ["CTO", "VP Engineering", "Head of Technology"],
"location": {
"country": ["Germany", "Austria", "Switzerland"]
},
"company": {
"employee_size": {
"min": 100,
"max": 5000
}
}
}
}
],
"customFilterCriteria": [
{
"type": "maxPeoplePerCompany",
"value": 2
}
],
"crmFilters": null,
"userIds": ["user_abc123"],
"leadsPerList": 20,
"activeUntil": null
}
{
"error": {
"code": "BAD_REQUEST",
"message": "Invalid request body",
"details": [
{
"path": ["name"],
"message": "Required"
}
]
}
}
{
"error": {
"code": "UNAUTHORIZED",
"message": "User not authenticated"
}
}
Creates a new ICP (Ideal Customer Profile) with the specified targeting criteria. The authenticated user is automatically added to the ICP’s
userIds array, granting them access to the newly created ICP.
Authentication
This endpoint requires authentication. The user must be signed in to create an ICP.The creating user is automatically added to the
userIds array even if not
explicitly included in the request body.Request
string
required
The name of the ICP. Should be descriptive of the target audience.
string | null
An optional description providing more context about the ICP’s purpose and
target criteria.
array
required
Array of lead provider search criteria. At least one criteria should be provided to enable lead sourcing.
Show Lead provider criteria object
Show Lead provider criteria object
string
required
The lead provider to use. Currently supports
"baseProvider".string
The type of search to perform:
"person"- Search for individual contacts"company"- Search for companies
object
required
Provider-specific filter object. For our base provider, this includes parameters like:
job_title- Array of job titles to targetlocation- Location filters (country, state, city)company- Company filters (size, industry, keywords)skills- Required skillsseniority- Seniority levels
array
required
Array of custom filters to apply after lead provider search. Can be empty array
[] if no custom filters are needed.Show Custom filter types
Show Custom filter types
Website FilterWeb Scraping FilterAI FilterMax People Per CompanyMax Percent From CRMMin Days Until ReuseMatch Field With Regex
{
"type": "website",
"provider": "browserUse",
"prompt": "Check if company offers B2B SaaS products"
}
{
"type": "webscraping",
"provider": "firecrawl",
"extractionPrompt": "Extract pricing information",
"pageFindingPrompt": "Find the pricing page",
"includeSearchStrings": ["enterprise", "pricing"],
"excludeSearchStrings": ["free trial only"]
}
{
"type": "ai",
"entityType": "person",
"prompt": "Evaluate if this person has hiring authority"
}
{
"type": "maxPeoplePerCompany",
"value": 2
}
{
"type": "maxPercentFromCRM",
"value": 50
}
{
"type": "minDaysUntilReuse",
"value": 180
}
{
"type": "matchFieldWithRegex",
"field": "company.name",
"regex": "^(?!.*Test).*$"
}
object | null | undefined
Optional CRM integration filters for sourcing leads from connected CRM systems. This field is both optional and nullable.
Show CRM filters object
Show CRM filters object
string
required
CRM provider. Currently supports
"bullhorn".string | null | undefined
Free-text search for occupation/title field. Supports wildcards and boolean operators (e.g.,
"Head OR Leit* OR Direktor"). This field is both optional and nullable.string | null | undefined
Legacy query field. Optional and nullable. Retained for backward compatibility.
array
Array of structured filter conditions.
Show Filter condition object
Show Filter condition object
array
required
Array of Clerk user IDs that should have access to this ICP. The creating user
is automatically included.
number
default:10
Number of leads to include per generated lead list.
string | null
ISO 8601 timestamp indicating when the ICP should expire. Set to
null for no
expiration.Response
Returns the created ICP object.string
required
The generated UUID for the new ICP.
string
required
The name of the ICP.
string | null
required
The description of the ICP.
string
required
ISO 8601 timestamp of when the ICP was created.
string
required
ISO 8601 timestamp of when the ICP was last updated (same as createdAt for new
ICPs).
array
required
The lead provider search criteria as provided in the request.
array
required
The custom filter criteria as provided in the request.
object | null | undefined
The CRM filters as provided in the request. This field is both optional and nullable.
array
required
Array of user IDs with access, including the creating user.
number
required
Number of leads per list.
string | null
required
Expiration timestamp or
null.Request Examples
{
"name": "DACH Tech Leaders",
"description": "Technology leaders in German-speaking regions",
"leadProviderCriteria": [
{
"provider": "baseProvider",
"type": "person",
"filters": {
"job_title": ["CTO", "VP Engineering", "Head of Technology"],
"location": {
"country": ["Germany", "Austria", "Switzerland"]
},
"company": {
"employee_size": {
"min": 100,
"max": 5000
}
}
}
}
],
"customFilterCriteria": [
{
"type": "maxPeoplePerCompany",
"value": 2
}
],
"crmFilters": null,
"userIds": [],
"leadsPerList": 20,
"activeUntil": null
}
{
"name": "Existing Contacts - Refresh",
"description": "Re-engage existing CRM contacts in specific regions",
"leadProviderCriteria": [],
"customFilterCriteria": [
{
"type": "minDaysUntilReuse",
"value": 90
}
],
"crmFilters": {
"provider": "bullhorn",
"textSearch": "Director OR Manager",
"filters": [
{
"path": "address.countryName",
"mode": "in",
"value": ["Germany", "Austria"],
"exclude": false
},
{
"path": "status",
"mode": "equals",
"value": "Active",
"exclude": false
}
]
},
"userIds": ["user_teammate123"],
"leadsPerList": 50,
"activeUntil": "2024-12-31T23:59:59.000Z"
}
{
"name": "AI-Qualified SaaS Buyers",
"description": "Leads qualified by AI for SaaS purchasing intent",
"leadProviderCriteria": [
{
"provider": "baseProvider",
"type": "person",
"filters": {
"job_title": [
"IT Manager",
"Procurement Manager",
"Operations Director"
],
"company": {
"industry": ["Technology", "Finance", "Healthcare"]
}
}
}
],
"customFilterCriteria": [
{
"type": "ai",
"entityType": "company",
"prompt": "Determine if this company is likely to purchase B2B SaaS solutions based on their industry, size, and technology stack"
},
{
"type": "website",
"provider": "browserUse",
"prompt": "Check if the company website mentions digital transformation or cloud adoption initiatives"
},
{
"type": "maxPeoplePerCompany",
"value": 3
}
],
"crmFilters": null,
"userIds": [],
"leadsPerList": 15,
"activeUntil": null
}
Response Examples
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "DACH Tech Leaders",
"description": "Technology leaders in German-speaking regions",
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-15T10:30:00.000Z",
"leadProviderCriteria": [
{
"provider": "baseProvider",
"type": "person",
"filters": {
"job_title": ["CTO", "VP Engineering", "Head of Technology"],
"location": {
"country": ["Germany", "Austria", "Switzerland"]
},
"company": {
"employee_size": {
"min": 100,
"max": 5000
}
}
}
}
],
"customFilterCriteria": [
{
"type": "maxPeoplePerCompany",
"value": 2
}
],
"crmFilters": null,
"userIds": ["user_abc123"],
"leadsPerList": 20,
"activeUntil": null
}
{
"error": {
"code": "BAD_REQUEST",
"message": "Invalid request body",
"details": [
{
"path": ["name"],
"message": "Required"
}
]
}
}
{
"error": {
"code": "UNAUTHORIZED",
"message": "User not authenticated"
}
}
Error Codes
| Status Code | Error Code | Description |
|---|---|---|
| 400 | BAD_REQUEST | Invalid request body. Check the details field for specific validation errors. |
| 401 | UNAUTHORIZED | User is not authenticated. Ensure a valid session exists. |
| 500 | INTERNAL_ERROR | An unexpected server error occurred. |