Search contacts
Search contacts (customers and leads) with a structured filter AST, sorting, and cursor pagination.
Structured query AST
Each clause has the shape { field, operator, value }. You can pass a single clause or wrap up to 15 in a top-level AND group:
{
"query": {
"operator": "AND",
"value": [
{ "field": "type", "operator": "=", "value": "customer" },
{ "field": "lastActivity", "operator": ">", "value": 1735689600 }
]
},
"sort": "lastActivity:desc",
"limit": 20
}
Top-level OR groups and nested groups are not supported in this version.
Supported fields and operators
Field names are camelCase, matching the rest of the v2 public API. Snake_case names that this endpoint originally shipped with (external_id, company_ids, posts_created, comments_created, last_activity, created_at) are still accepted for back-compat but are deprecated — please migrate to camelCase in new code.
| Field | Type | Operators |
|---|---|---|
externalId | string (caller-provided user id) | =, !=, IN, NIN |
email | string | =, !=, IN, NIN |
name | string | =, !=, IN, NIN, ~ |
type | enum (customer, lead) | =, !=, IN, NIN |
companyIds | id (Featurebase company id) | =, !=, IN, NIN |
postsCreated | number | =, !=, >, < |
commentsCreated | number | =, !=, >, < |
lastActivity | unix seconds | =, !=, >, < |
createdAt | unix seconds | =, !=, >, < |
The name ~ "..." operator runs a word-aware substring search via the underlying text index. Other string operators (!~, ^, $) are reserved for future use and currently return 400.
A query consisting only of != or NIN clauses on unbounded fields is rejected with query_too_broad to prevent full-org scans. Combine the negation with at least one positive clause (=, IN, >, <) instead. The closed-enum field type is exempt from this guard.
Contacts that have been merged into another contact (lead-to-customer rollup) are always excluded from results.
Sort
Allowed values:
lastActivity:desc(default),lastActivity:asccreatedAt:desc,createdAt:ascpostsCreated:desc,postsCreated:asccommentsCreated:desc,commentsCreated:asc
Snake_case sort axes (last_activity:desc, created_at:asc, etc.) are accepted for back-compat — the cursor encodes the canonical camelCase identity, so a caller can switch naming conventions mid-pagination without restarting.
The chosen sort axis is encoded in the cursor; switching sort mid-pagination returns 400 invalid_cursor. Restart pagination without a cursor when changing sort.
Pagination
Cursor-based, limit between 1 and 100 (default 10). totalCount is approximate and capped at 5000; totalCountCapped is true when the real count may be higher.
Response
Returns a standard list envelope with contact rows identical to GET /v2/contacts/{id}.
Version Availability
This endpoint is only available in API version 2026-01-01.nova and newer.
Search contacts
import Featurebase from 'featurebase-node';
const client = new Featurebase({
apiKey: process.env['FEATUREBASE_API_KEY'], // This is the default and can be omitted
});
const response = await client.users.contacts.search();
console.log(response.data);{
"data": [
{
"id": "676f0f6765bdaa7d7d760f88",
"name": "John Steezy",
"object": "contact",
"type": "customer",
"commentsCreated": 0,
"companies": [
{
"id": "507f1f77bcf86cd799439011",
"companyId": "comp_12345",
"companySize": 250,
"createdAt": "2025-01-01T12:00:00.000Z",
"industry": "Technology",
"lastActivity": "2025-01-15T00:00:00.000Z",
"linkedUsers": 15,
"monthlySpend": 5000,
"name": "Acme Inc",
"object": "company",
"plan": "enterprise",
"updatedAt": "2025-01-10T15:30:00.000Z",
"website": "https://acme.com",
"customFields": {
"location": "bar",
"priority": "bar"
}
}
],
"customFields": {
"foo": "bar"
},
"description": "",
"email": "john@example.com",
"lastActivity": "2025-01-03T21:42:30.181Z",
"locale": "en",
"manuallyOptedOutFromChangelog": false,
"organizationId": "5febde12dc56d60012d47db6",
"postsCreated": 0,
"profilePicture": "https://fb-usercontent.fra1.cdn.digitaloceanspaces.com/anon_23.png",
"roles": [
"string"
],
"subscribedToChangelog": true,
"userId": "676f0f673dbb299c8a4f3057",
"verified": true
}
],
"nextCursor": "eyJpZCI6IjUwN2YxZjc3YmNmODZjZDc5OTQzOTAxMSJ9",
"object": "list",
"totalCount": 42,
"totalCountCapped": false
}Returns Examples
{
"data": [
{
"id": "676f0f6765bdaa7d7d760f88",
"name": "John Steezy",
"object": "contact",
"type": "customer",
"commentsCreated": 0,
"companies": [
{
"id": "507f1f77bcf86cd799439011",
"companyId": "comp_12345",
"companySize": 250,
"createdAt": "2025-01-01T12:00:00.000Z",
"industry": "Technology",
"lastActivity": "2025-01-15T00:00:00.000Z",
"linkedUsers": 15,
"monthlySpend": 5000,
"name": "Acme Inc",
"object": "company",
"plan": "enterprise",
"updatedAt": "2025-01-10T15:30:00.000Z",
"website": "https://acme.com",
"customFields": {
"location": "bar",
"priority": "bar"
}
}
],
"customFields": {
"foo": "bar"
},
"description": "",
"email": "john@example.com",
"lastActivity": "2025-01-03T21:42:30.181Z",
"locale": "en",
"manuallyOptedOutFromChangelog": false,
"organizationId": "5febde12dc56d60012d47db6",
"postsCreated": 0,
"profilePicture": "https://fb-usercontent.fra1.cdn.digitaloceanspaces.com/anon_23.png",
"roles": [
"string"
],
"subscribedToChangelog": true,
"userId": "676f0f673dbb299c8a4f3057",
"verified": true
}
],
"nextCursor": "eyJpZCI6IjUwN2YxZjc3YmNmODZjZDc5OTQzOTAxMSJ9",
"object": "list",
"totalCount": 42,
"totalCountCapped": false
}