Contacts
Filter contacts
List contacts with filters sent in the request body. Accepts a Prisma-shaped `where` clause, an optional geographic `near` radius, and pagination. Returns the same shape as `GET /v2/contacts/` with an
POST /v2/contacts/filter
Building a
where filter? See the Filtering contacts guide for every key, its value shapes, and end-to-end examples.Request body
Content-Type: application/json
take
integer
skip
integer
cursor
string (uuid)
where
object
where.in
string (uuid)
where.not_in
string (uuid)
where.ignore_merge
boolean
Filter by the
ignore_merge flag (excluded from merge suggestions).where.is_starred
boolean
Match starred (true) or non-starred (false) contacts.
where.is_archived
boolean
Match archived (true) or active (false) contacts. Defaults to false when omitted.
where.has_priority_tier
integer
where.has_linkedin
string
where.has_instagram
string
where.has_twitter
string
where.has_source
string
where.has_name
string
where.has_groups
object
where.has_groups.not
string
where.has_user_created_groups
boolean
Non-system group membership: true for at least one user-created group; false for no user-created groups, including contacts with zero memberships or only Dex system-group memberships.
where.has_grouping_signal
boolean enum
Internal organize prefilter: title, company, location, or LinkedIn summary is non-null and non-empty. Whitespace-only values are removed by the organize serializer.Possible values:
truewhere.has_groups_all
array<array>
Array of group-id rows: AND across rows, OR within each row (contact must be in at least one group from every row).
where.has_frequency
string
where.has_location
string
where.has_location_exact
string
Location: exact string match (not fuzzy).
where.has_job_title
string
where.has_never_keep_in_touch
boolean
Filter by the
never_keep_in_touch flag.where.has_created_at
object
Creation-date range:
{ gte?, lte? } ISO 8601 datetimes (at least one bound required).where.has_created_at.gte
string (date-time)
where.has_created_at.lte
string (date-time)
where.has_updated_at
object
Last-updated-date range:
{ gte?, lte? } ISO 8601 datetimes (at least one bound required).where.has_updated_at.gte
string (date-time)
where.has_updated_at.lte
string (date-time)
where.has_birthday
string (date-time)
where.has_tag
string (uuid)
Match contacts carrying this single tag id.
where.has_tags
array<string (uuid)>
where.has_tags_all
array<array>
Array of tag-id rows: AND across rows, OR within each row (contact must carry at least one tag from every row).
where.has_company
string
where.has_education
string
where.has_description
string
where.has_linkedin_companies
string
where.has_linkedin_education
string
where.has_email
boolean
Match contacts that have (true) or lack (false) at least one email.
where.has_phone_number
boolean
Match contacts that have (true) or lack (false) at least one phone number.
where.not_has_name
string
where.not_has_company
string
where.not_has_job_title
string
where.not_has_education
string
where.not_has_description
string
where.not_has_linkedin_companies
string
where.not_has_linkedin_education
string
where.has_linkedin_last_message_at
boolean
where.has_last_seen_at
boolean
where.has_distance
object
Geo radius filter: contacts within
meters of { lat, lon } (PostGIS ST_DWithin on geocoded coordinates). label is an optional display name for the point.where.has_distance.lat
number
where.has_distance.lon
number
where.has_distance.meters
number
where.has_distance.label
string
where.has_interaction
boolean
where.has_next_reminder
boolean
where.custom_fields
array<object>
User-defined custom-field filters. Each clause is
{ field_id, operator, value? }; multiple clauses AND together. Operators: contains, eq, in, not_in, present, absent, gte, lte.where.custom_fields[].field_id
string (uuid)
where.custom_fields[].operator
string enum
Possible values:
"contains", "eq", "in", "not_in", "present", "absent", "gte", "lte"where.custom_fields[].value
string
where._or
array<object>
Compound-OR escape hatch: an array of filter branches combined with OR, each ANDed with the top-level keys. One level deep — branches cannot themselves contain
_or.where._or[].in
string (uuid)
where._or[].not_in
string (uuid)
where._or[].ignore_merge
boolean
Filter by the
ignore_merge flag (excluded from merge suggestions).where._or[].is_starred
boolean
Match starred (true) or non-starred (false) contacts.
where._or[].is_archived
boolean
Match archived (true) or active (false) contacts. Defaults to false when omitted.
where._or[].has_priority_tier
integer
where._or[].has_linkedin
string
where._or[].has_instagram
string
where._or[].has_twitter
string
where._or[].has_source
string
where._or[].has_name
string
where._or[].has_groups
object
where._or[].has_groups.not
string
where._or[].has_user_created_groups
boolean
Non-system group membership: true for at least one user-created group; false for no user-created groups, including contacts with zero memberships or only Dex system-group memberships.
where._or[].has_grouping_signal
boolean enum
Internal organize prefilter: title, company, location, or LinkedIn summary is non-null and non-empty. Whitespace-only values are removed by the organize serializer.Possible values:
truewhere._or[].has_groups_all
array<array>
Array of group-id rows: AND across rows, OR within each row (contact must be in at least one group from every row).
where._or[].has_frequency
string
where._or[].has_location
string
where._or[].has_location_exact
string
Location: exact string match (not fuzzy).
where._or[].has_job_title
string
where._or[].has_never_keep_in_touch
boolean
Filter by the
never_keep_in_touch flag.where._or[].has_created_at
object
Creation-date range:
{ gte?, lte? } ISO 8601 datetimes (at least one bound required).where._or[].has_created_at.gte
string (date-time)
where._or[].has_created_at.lte
string (date-time)
where._or[].has_updated_at
object
Last-updated-date range:
{ gte?, lte? } ISO 8601 datetimes (at least one bound required).where._or[].has_updated_at.gte
string (date-time)
where._or[].has_updated_at.lte
string (date-time)
where._or[].has_birthday
string (date-time)
where._or[].has_tag
string (uuid)
Match contacts carrying this single tag id.
where._or[].has_tags
array<string (uuid)>
where._or[].has_tags_all
array<array>
Array of tag-id rows: AND across rows, OR within each row (contact must carry at least one tag from every row).
where._or[].has_company
string
where._or[].has_education
string
where._or[].has_description
string
where._or[].has_linkedin_companies
string
where._or[].has_linkedin_education
string
where._or[].has_email
boolean
Match contacts that have (true) or lack (false) at least one email.
where._or[].has_phone_number
boolean
Match contacts that have (true) or lack (false) at least one phone number.
where._or[].not_has_name
string
where._or[].not_has_company
string
where._or[].not_has_job_title
string
where._or[].not_has_education
string
where._or[].not_has_description
string
where._or[].not_has_linkedin_companies
string
where._or[].not_has_linkedin_education
string
where._or[].has_linkedin_last_message_at
boolean
where._or[].has_last_seen_at
boolean
where._or[].has_distance
object
Geo radius filter: contacts within
meters of { lat, lon } (PostGIS ST_DWithin on geocoded coordinates). label is an optional display name for the point.where._or[].has_distance.lat
number
where._or[].has_distance.lon
number
where._or[].has_distance.meters
number
where._or[].has_distance.label
string
where._or[].has_interaction
boolean
where._or[].has_next_reminder
boolean
where._or[].custom_fields
array<object>
User-defined custom-field filters. Each clause is
{ field_id, operator, value? }; multiple clauses AND together. Operators: contains, eq, in, not_in, present, absent, gte, lte.where._or[].custom_fields[].field_id
string (uuid)
where._or[].custom_fields[].operator
string enum
Possible values:
"contains", "eq", "in", "not_in", "present", "absent", "gte", "lte"where._or[].custom_fields[].value
string
orderBy
any
include
object
include.linkedin_data
boolean
include.groups_count
boolean
include.coordinates
boolean
select
object
select.linkedin_data
boolean
select.groups_count
boolean
select.coordinates
boolean
near
string
radiusKm
number
Example
{
"take": 0,
"skip": 0
}
Responses
200 — Successful response
Content-Type: application/json
data
object required
data.contacts
array<object> required
data.contacts[].id
string (uuid) required
data.contacts[].user_id
string
data.contacts[].first_name
string | null
data.contacts[].last_name
string | null
data.contacts[].full_name
string | null
data.contacts[].description
string | null
data.contacts[].job_title
string | null
data.contacts[].company
string | null
data.contacts[].education
string | null
data.contacts[].legacy_location
string | null
data.contacts[].image_url
string | null
data.contacts[].business_card_url
string | null
data.contacts[].website
string | null
data.contacts[].image_source
string | null
data.contacts[].birthday
string (date-time)
data.contacts[].birthday_year
integer | null
data.contacts[].linkedin
string | null
data.contacts[].twitter
string | null
data.contacts[].facebook
string | null
data.contacts[].instagram
string | null
data.contacts[].telegram
string | null
data.contacts[].tiktok
string | null
data.contacts[].youtube
string | null
data.contacts[].starred
boolean
data.contacts[].is_archived
boolean
data.contacts[].ignore_merge
boolean
data.contacts[].never_keep_in_touch
boolean
data.contacts[].source
string
data.contacts[].priority_tier
integer | null
data.contacts[].frequency
string | null
data.contacts[].frequency_text
string | null
data.contacts[].last_seen_at
string (date-time)
data.contacts[].last_reminder_at
string (date-time)
data.contacts[].next_reminder_at
string (date-time)
data.contacts[].first_met_at
string (date-time)
data.contacts[].first_interaction_at
string (date-time)
data.contacts[].linkedin_companies
string | null
data.contacts[].linkedin_education
string | null
data.contacts[].linkedin_enhance_date
string (date-time)
data.contacts[].linkedin_last_message_at
string (date-time)
data.contacts[].linkedin_last_message_snippet
string | null
data.contacts[].linkedin_message_link
string | null
data.contacts[].whatsapp_message_link
string | null
data.contacts[].whatsapp_message_snippet
string | null
data.contacts[].whatsapp_last_message_at
string (date-time)
data.contacts[].imessage_message_link
string | null
data.contacts[].imessage_message_snippet
string | null
data.contacts[].imessage_last_message_at
string (date-time)
data.contacts[].instagram_message_link
string | null
data.contacts[].instagram_message_snippet
string | null
data.contacts[].instagram_last_message_at
string (date-time)
data.contacts[].gmail_last_interaction_at
string (date-time)
data.contacts[].gmail_last_interaction_provider
string enum
Possible values:
"GOOGLE", "OFFICE365"data.contacts[].gmail_last_interaction_provider_id
string | null
data.contacts[].gmail_last_interaction_subject
string | null
data.contacts[].gcal_last_interaction_at
string (date-time)
data.contacts[].gcal_last_interaction_provider
string enum
Possible values:
"GOOGLE", "OFFICE365"data.contacts[].gcal_last_interaction_provider_id
string | null
data.contacts[].gcal_last_interaction_title
string | null
data.contacts[].phone_call_interaction_snippet
string | null
data.contacts[].phone_call_last_interaction_at
string (date-time)
data.contacts[].web_search_summary
any | null
data.contacts[].created_at
string (date-time)
data.contacts[].updated_at
string (date-time)
data.contacts[].geocode_attempts
integer
data.contacts[].geocode_failed_at
string (date-time)
data.contacts[]._count
object
data.contacts[]._count.groups_contacts
integer
data.contacts[].frequency_interval
any
data.contacts[].linkedin_data
object | null
data.contacts[].latitude
number | null
data.contacts[].longitude
number | null
data.contacts[].contact_emails
array<object>
data.contacts[].contact_phone_numbers
array<object>
data.contacts[].contact_birthdays
object | null
data.contacts[].contact_locations
array<object>
data.contacts[].contacts_custom_fields
array<object>
data.contacts[].legacy_contact_addresses
array<object>
data.contacts[].groups_contacts
array<object>
data.contacts[].tags_contacts
array<object>
data.contacts[].timeline_items_contacts
array<object>
data.contacts[].reminders_contacts
array<object>
data.contacts[].contact_relations_contact_relations_sourceTocontacts
array<object>
data.contacts[].contact_relations_contact_relations_destinationTocontacts
array<object>
data.contacts[].feed_items
array<object>
data.contacts[].keep_in_touch_reminders
object | null
data.pagination
object
data.pagination.nextCursor
string | null
data.pagination.count
integer
data.filterHash
string required
Example
{
"data": {
"contacts": [
{
"id": "00000000-0000-0000-0000-000000000000"
}
],
"filterHash": "string"
}
}
400
No response body.
401
No response body.
403
No response body.
404
No response body.
409
No response body.
429
No response body.
500
No response body.
Code samples
curl https://api.prod.getdex.com/v2/contacts/filter \
--request POST \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"take": 0,
"skip": 0
}'
fetch('https://api.prod.getdex.com/v2/contacts/filter', {
method: 'POST',
headers: {
Authorization: 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
take: 0,
skip: 0
})
})
requests.post(
"https://api.prod.getdex.com/v2/contacts/filter",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
},
json={
"take": 0,
"skip": 0
}
)
Count contacts
Return the count of contacts matching the optional `where` filter. Returns `{ data: { count } }`.
Search contacts by name
Name-only typeahead. Matches the contact's full name accent-insensitively (`f_unaccent`) and returns full contact rows in the list envelope `{ data: { contacts: [...] } }`. `query` is required — send

