Skip to content

Search contacts

Request

You can search for multiple contacts by the value of their attributes in order to fetch exactly who you want.

To search for contacts, you need to send a POST request to https://api.intercom.io/contacts/search.

This will accept a query object in the body which will define your filters in order to search for contacts.

Optimizing search queries

Search queries can be complex, so optimizing them can help the performance of your search. Use the AND and OR operators to combine multiple filters to get the exact results you need and utilize pagination to limit the number of results returned. The default is 50 results per page. See the pagination section for more details on how to use the starting_after param.

Merged Contacts

Contacts that have been merged (via POST /contacts/merge) are excluded from search results. If a contact was recently merged into another, it will no longer appear in queries filtered by updated_at or any other field. Only the target contact from the merge remains searchable.

Contact Creation Delay

If a contact has recently been created, there is a possibility that it will not yet be available when searching. This means that it may not appear in the response. This delay can take a few minutes. If you need to be instantly notified it is recommended to use webhooks and iterate to see if they match your search filters.

Nesting & Limitations

You can nest these filters in order to get even more granular insights that pinpoint exactly what you need. Example: (1 OR 2) AND (3 OR 4). There are some limitations to the amount of multiple's there can be:

  • There's a limit of max 2 nested filters
  • There's a limit of max 15 filters for each AND or OR group

Searching for Timestamp Fields

Standard timestamp fields and Date custom attributes behave differently.

Standard timestamp fields (created_at, updated_at, last_seen_at etc.) are filtered on the exact second, in UTC. = matches only Contacts whose value is that exact second, and >, <, >= and <= compare against the exact instant you pass - the value is not rounded or truncated. These fields report a type of datetime on the Data Attributes endpoint. Note that != also matches Contacts with no value set for the field.

Date custom attributes are matched by calendar day, and the day boundary is always UTC regardless of your workspace's timezone. = matches the whole UTC day, > matches from the start of the next UTC day, and < matches everything before the start of that day. The !=, >=, <=, IN and NIN operators are not supported on these fields and return an error.

Example. Searching for created_at greater than 1577869200 (January 1st, 2020 9:00 AM UTC) returns Contacts created after that exact instant. Passing the same value for a Date custom attribute truncates it to 1577836800 (January 1st, 2020 12:00 AM UTC), so those results begin from January 2nd, 2020 12:00 AM UTC.

Only search queries behave this way. Responses always carry the full UNIX timestamp, and sorting uses the full value.

Accepted Fields

Most key listed as part of the Contacts Model are searchable, whether writeable or not. The value you search for has to match the accepted type, otherwise the query will fail (ie. as created_at accepts a date, the value cannot be a string such as "foorbar").

FieldType
idString
roleString
Accepts user or lead
nameString
avatarString
owner_idInteger
emailString
email_domainString
phoneString
formatted_phoneString
external_idString
created_atDatetime (Unix timestamp in seconds)
signed_up_atDatetime (Unix timestamp in seconds)
updated_atDatetime (Unix timestamp in seconds)
last_seen_atDatetime (Unix timestamp in seconds)
last_contacted_atDatetime (Unix timestamp in seconds)
last_replied_atDatetime (Unix timestamp in seconds)
last_email_opened_atDatetime (Unix timestamp in seconds)
last_email_clicked_atDatetime (Unix timestamp in seconds)
language_overrideString
browserString
browser_languageString
osString
location.countryString
location.regionString
location.cityString
unsubscribed_from_emailsBoolean
marked_email_as_spamBoolean
has_hard_bouncedBoolean
ios_last_seen_atDatetime (Unix timestamp in seconds)
ios_app_versionString
ios_deviceString
ios_app_deviceString
ios_os_versionString
ios_app_nameString
ios_sdk_versionString
android_last_seen_atDatetime (Unix timestamp in seconds)
android_app_versionString
android_deviceString
android_app_nameString
andoid_sdk_versionString
segment_idString
tag_idString
custom_attributes.{attribute_name}Matches the attribute's own type
(String, Integer, Float, Boolean or Date)

Accepted Operators

Operators not supported on Date custom attributes

Date custom attributes do not support the !=, >=, or <= operators. Using them returns an error. Standard timestamp fields (created_at, updated_at etc.) do support these operators, and are filtered on the exact second.

The table below shows the operators you can use to define how you want to search for the value. The operator should be put in as a string ("="). Which operators are valid depends on the field's type - see the "Valid Types" column below. Searching by tag_id supports only the = and != operators.

OperatorValid TypesDescription
=AllEquals
!=All except DateDoesn't Equal
Also matches Contacts with no value set
INAll except Date, Datetime and tag_idIn
Shortcut for OR queries
Values must be in Array
NINAll except Date, Datetime and tag_idNot In
Shortcut for OR ! queries
Values must be in Array
>Integer
Datetime
Date
Greater than
On Date custom attributes, matches from the start of the next day
<Integer
Datetime
Date
Lower than
On Date custom attributes, matches before the start of the day
>=Integer
Datetime
Greater than or equal to
Not supported on Date custom attributes
<=Integer
Datetime
Lower than or equal to
Not supported on Date custom attributes
~StringContains
!~StringDoesn't Contain
^StringStarts With
$StringEnds With
Security
bearerAuth
Query
include_merge_historyboolean

Pass true to include a merge_history array on each contact in the response. Only returned for contacts with a user role.

Default:false
Headers
Intercom-Versionstring(intercom_version)

Intercom API version.
By default, it's equal to the version set in the app package.

Default:"Preview"
Enum:"1.0""1.1""1.2""1.3""1.4""2.0""2.1""2.2""2.3""2.4"
Example:Preview
Bodyapplication/json
querySingle filter search request (object) or multiple filter search request (object)required
One of:

Search using Intercoms Search APIs with a single filter.

paginationobject or null(Pagination: Starting After)
sortobject

An optional object to sort the results by.

curl -i -X POST \
  'https://api.intercom.io/contacts/search?include_merge_history=false' \
  -H 'Authorization: Bearer <YOUR_TOKEN_HERE>' \
  -H 'Content-Type: application/json' \
  -H 'Intercom-Version: Preview' \
  -d '{
    "query": {
      "operator": "AND",
      "value": [
        {
          "field": "created_at",
          "operator": ">",
          "value": "1306054154"
        }
      ]
    },
    "sort": {
      "field": "created_at",
      "order": "ascending"
    },
    "pagination": {
      "per_page": 5
    }
  }'

Responses

successful

Bodyapplication/json
typestring

Always list

Value:"list"
Example:"list"
dataArray of objects(Contact)

The list of contact objects

total_countinteger

A count of the total number of objects.

Example:100
pagesobject or null(Cursor based pages)

Cursor-based pagination is a technique used in the Intercom API to navigate through large amounts of data. A "cursor" or pointer is used to keep track of the current position in the result set, allowing the API to return the data in small chunks or "pages" as needed.

Response
{ "type": "list", "data": [], "total_count": 0, "pages": { "type": "pages", "page": 1, "per_page": 5, "total_pages": 0 } }