For the complete documentation index, see llms.txt. This page is also available as Markdown.

Lists

Manage lists of contacts, companies, or deals. Lists come in two types:

  • Regular lists (filterBased: false) — records are explicitly added or removed by patching the listIds array on the contact/company/deal record.

  • Dynamic lists (filterBased: true) — records are not stored. The UI dynamically shows all workspace records that match the filters defined on the list's views. Dynamic list membership cannot be queried directly via the API — use a regular GET /api/contacts (or companies/deals) query with the same filter criteria instead.

List + View pairing (required)

A list without a view is not usable in the UI. Always create at least one view immediately after creating a list using POST /api/views. The first view should have settings.isDefault: true (or set it via a follow-up PATCH on the view). The UI sets isDefault automatically when the list is first opened.

Icons

Every list must have an icon set. A list without an icon will not display correctly in the UI. See the available icon names in the icon field description on ListCreate.

Filter placement

For dynamic lists, filters belong on the views (via filters on the View object), not on the list itself. The list-level filters field should always be left empty ({}). Setting filters on the list object has no effect on what records are shown.

Each list can have multiple views, each with its own independent filter. The UI shows records matching each view's own filter when that view is active.

List lists

get

Returns lists in a workspace. Filter by workspace using {"workspaceId": "<WORKSPACE_UUID>"}.

Use filterBased to distinguish between regular and dynamic lists:

  • {"workspaceId": "<WS>", "filterBased": false} — regular lists only

  • {"workspaceId": "<WS>", "filterBased": true} — dynamic lists only

Authorizations
AuthorizationstringRequired

All API requests require a Bearer token in the Authorization header. Create an API key from Workspace Settings → API keys

Query parameters
fieldsstringOptional

Comma-separated list of fields to return. Defaults to all fields.

Example: id,name,domain
wherestringOptional

JSON-encoded filter object. All top-level conditions are combined with AND logic. Use $or for OR logic.

The available operators depend on the data type of the field you are filtering on.


String fields

Fields like name, domain, description, linkedin, source, externalId, location.

OperatorDescriptionExample
(exact)Exact match{"name": "Linear"}
$eqExplicit exact match{"name": {"$eq": "Linear"}}
$notNot equal{"source": {"$not": "import"}}
$inMatches any value in array{"domain": {"$in": ["linear.app", "granola.so"]}}
$notInMatches none of the values{"source": {"$notIn": ["import", "api"]}}
$containsCase-insensitive word-boundary substring match{"name": {"$contains": "YC"}}
$notContainsDoes not contain{"name": {"$notContains": "Test"}}
$containsAnyContains any of the given strings{"name": {"$containsAny": ["YC", "Techstars"]}}
$startsWithStarts with prefix{"domain": {"$startsWith": "app."}}
$endsWithEnds with suffix{"email": {"$endsWith": "@zero.inc"}}
$existsField is present and truthy{"linkedin": {"$exists": true}}
$notExistsField is absent, null, or empty{"linkedin": {"$notExists": true}}

Number fields

Fields like value, confidence.

OperatorDescriptionExample
(exact)Exact match{"value": 5000}
$eqExplicit exact match{"value": {"$eq": 5000}}
$notNot equal{"value": {"$not": 0}}
$gtGreater than{"value": {"$gt": 10000}}
$gteGreater than or equal{"value": {"$gte": 5000}}
$ltLess than{"value": {"$lt": 10000}}
$lteLess than or equal{"value": {"$lte": 50000}}
$inMatches any value in array{"confidence": {"$in": [0.25, 0.5, 0.75]}}
$notInMatches none of the values{"confidence": {"$notIn": [0, 1]}}
$existsField is present and truthy{"value": {"$exists": true}}
$notExistsField is absent, null, or zero{"value": {"$notExists": true}}

Multiple operators can be combined on one field:

{"value": {"$gte": 5000, "$lt": 10000}}

Date fields

Fields like closeDate, startDate, endDate, createdAt, updatedAt.

Values can be ISO 8601 strings ("2026-01-01", "2026-01-01T00:00:00Z") or relative time macros.

Relative time macros: +Nd / -Nd (days), +Nw / -Nw (weeks), +Nm / -Nm (months), +Ny / -Ny (years), +Nh / -Nh (hours), +Ns / -Ns (seconds), now().

OperatorDescriptionExample
$gteOn or after{"closeDate": {"$gte": "2026-01-01"}}
$lteOn or before{"closeDate": {"$lte": "2026-03-31"}}
$gtAfter{"createdAt": {"$gt": "2026-01-01T00:00:00Z"}}
$ltBefore{"createdAt": {"$lt": "now()"}}
$dateExact date match (compares date portion only){"closeDate": {"$date": "2026-01-15"}}
$existsField is present and truthy{"closeDate": {"$exists": true}}
$notExistsField is absent or null{"closeDate": {"$notExists": true}}

Date range example:

{"closeDate": {"$gte": "2026-01-01", "$lte": "2026-03-31"}}

Relative date example (closing in next 30 days):

{"closeDate": {"$gte": "now()", "$lte": "+30d"}}

Array fields

Fields like listIds, ownerIds, contactIds.

OperatorDescriptionExample
$includesArray contains the given value (use this — bare exact match is not supported){"listIds": {"$includes": "<LIST_UUID>"}}
$notIncludesArray does not contain the given value{"ownerIds": {"$notIncludes": "<USER_UUID>"}}
$overlapsArray contains at least one of the given values{"ownerIds": {"$overlaps": ["<UUID_1>", "<UUID_2>"]}}
$notOverlapsArray contains none of the given values{"listIds": {"$notOverlaps": ["<UUID_1>", "<UUID_2>"]}}
$allArray contains all of the given values{"listIds": {"$all": ["<UUID_1>", "<UUID_2>"]}}
$lengthFilter by array length (supports nested operators){"contactIds": {"$length": {"$gte": 2}}}
$existsField is present and non-empty{"ownerIds": {"$exists": true}}
$notExistsField is absent or empty{"ownerIds": {"$notExists": true}}

UUID / ID fields

Fields like id, workspaceId, companyId, stage.

OperatorDescriptionExample
(exact)Exact match{"stage": "<PIPELINE_STAGE_UUID>"}
$inMatches any value in array{"stage": {"$in": ["<UUID_1>", "<UUID_2>"]}}
$notInMatches none of the values{"stage": {"$notIn": ["<UUID_1>"]}}
$notNot equal{"stage": {"$not": "<UUID>"}}

Boolean fields

Fields like archived.

OperatorDescriptionExample
(exact)Exact match{"archived": false}
$notNot equal{"archived": {"$not": true}}

Logical operators

These work across all data types.

$or — matches if any sub-condition is true:

{
  "workspaceId": "<WORKSPACE_UUID>",
  "$or": [
    {"ownerIds": {"$overlaps": ["<USER_UUID_1>", "<USER_UUID_2>"]}},
    {"closeDate": {"$gte": "2026-01-01"}}
  ]
}

$and — matches if all sub-conditions are true (useful when you need multiple conditions on the same field):

{
  "$and": [
    {"name": {"$contains": "Enterprise"}},
    {"name": {"$notContains": "Test"}}
  ]
}

Dot-notation (relation filtering)

Use dot-syntax to filter records based on properties of related objects:

{"company.name": "Linear"}
{"company.domain": {"$in": ["linear.app", "granola.so"]}}
{"company.location.city": "San Francisco"}
{"companyProfile.categories": {"$overlaps": ["Sales", "Marketing"]}}

All operators available for the target field's data type can be used with dot-notation.


Custom property filtering

Custom properties are stored in the custom object on records, keyed by UUID. Use GET /api/columns to discover the available custom property IDs, types, and options for a workspace.

Filter on custom properties using custom.<COLUMN_ID> with operators appropriate for the column's type.

Note: For select and multiselect columns, option values are UUIDs (the key field from the column's options array). Use the UUID, not the human-readable name.

// Text custom property
{"custom.54e1ca7d-69c3-4b77-8266-8085b5834116": {"$contains": "enterprise"}}

// Select custom property (use the option key UUID)
{"custom.a1b2c3d4-e5f6-7890-abcd-ef1234567890": "3e839b5c-b311-4887-b2da-727d2d75cdd6"}

// Multi-select custom property (use option key UUIDs)
{"custom.b2c3d4e5-f6a7-8901-bcde-f12345678901": {"$overlaps": ["a1b1c1d1-e1f1-1111-aaaa-111111111111", "b2b2c2d2-e2f2-2222-bbbb-222222222222"]}}

// Currency/number custom property
{"custom.c3d4e5f6-a7b8-9012-cdef-123456789012": {"$gte": 100000}}

// Date custom property
{"custom.d4e5f6a7-b8c9-0123-defa-234567890123": {"$gte": "2026-01-01"}}

// Boolean custom property
{"custom.e5f6a7b8-c9d0-1234-efab-345678901234": true}

// Check if custom property has a value
{"custom.f6a7b8c9-d0e1-2345-fabc-456789012345": {"$exists": true}}

Complex example

All top-level keys are ANDed together:

{
  "name": {"$contains": "Zero"},
  "location.city": "Helsinki",
  "location.country": {"$in": ["United Kingdom", "Germany", "Sweden"]},
  "value": {"$gte": 10000},
  "closeDate": {"$gte": "2026-01-01", "$lte": "2026-03-31"},
  "ownerIds": {"$includes": "<USER_UUID>"},
  "stage": {"$in": ["<UUID_1>", "<UUID_2>"]},
  "lastActivity": {"$exists": true},
  "companyProfile.categories": {"$overlaps": ["Sales", "Marketing"]},
  "custom.54e1ca7d-69c3-4b77-8266-8085b5834116": {"$contains": "enterprise"}
}
Example: {"stage":"<PIPELINE_STAGE_UUID>"}
limitintegerOptional

Maximum number of records to return

Default: 100
offsetintegerOptional

Pagination offset

Default: 0
orderBystringOptional

JSON string for sort order

Example: {"name":"asc"}
Responses
200

Successful response

application/json
totalintegerOptional
get/api/lists

Create a list

post

Create a new list. Set filterBased: true to create a dynamic list, or filterBased: false (default) for a regular list.

Always set an icon — lists without an icon do not display correctly in the UI.

After creating a list, immediately create at least one view with POST /api/views to make the list usable. A list without a view cannot be opened in the UI.

Authorizations
AuthorizationstringRequired

All API requests require a Bearer token in the Authorization header. Create an API key from Workspace Settings → API keys

Body
workspaceIdstring · uuidRequired
namestringRequired
entitystring · enumRequiredPossible values:
filterBasedbooleanOptional

true for dynamic list, false for regular list

Default: false
colorstringOptional

Hex color code (e.g. "#8B5CF6")

iconstring · enumRequired

Required. Icon name from the Zero icon set.

Possible values:
orderintegerOptional
listFolderIdstring · uuid · nullableOptional
Responses
200

List created successfully

application/json
post/api/lists

Get a list

get

Retrieve a single list by ID.

Authorizations
AuthorizationstringRequired

All API requests require a Bearer token in the Authorization header. Create an API key from Workspace Settings → API keys

Path parameters
listIdstring · uuidRequired
Responses
200

Successful response

application/json
get/api/lists/{listId}

Delete a list

delete

Delete a list. By default performs a hard delete (data: 1). Pass ?archive=true for a soft delete.

Note: Deleting a list does not delete the records within it. For regular lists, the records simply lose their association with the list.

Authorizations
AuthorizationstringRequired

All API requests require a Bearer token in the Authorization header. Create an API key from Workspace Settings → API keys

Path parameters
listIdstring · uuidRequired
Query parameters
archivebooleanOptional

If true, soft-deletes (archives) the list instead of permanently deleting it

Default: false
Responses
200

Deletion result

application/json
dataone ofOptional
integerOptional

1 on hard delete success, 0 if not found

or
arrayOptional

Archived list object(s) on soft delete

delete/api/lists/{listId}

Update a list

patch

Update a list's metadata (name, color, icon, etc.). Returns only the changed fields. entity is immutable and cannot be changed after creation.

Authorizations
AuthorizationstringRequired

All API requests require a Bearer token in the Authorization header. Create an API key from Workspace Settings → API keys

Path parameters
listIdstring · uuidRequired
Body

All fields are optional. Multiple fields can be updated in a single PATCH request.

namestringOptional
colorstringOptional
iconstringOptional
filterBasedbooleanOptional

Convert between regular and dynamic list. When switching to true, set filters on each view rather than on the list itself.

filtersobjectOptional

The API accepts and stores values here, but the UI uses view-level filters to determine which records are shown. Recommended to leave as {} and set filters on views instead.

orderintegerOptional
listFolderIdstring · uuid · nullableOptional
Responses
200

List updated. Only changed fields are returned in data.

application/json
dataobjectOptional
patch/api/lists/{listId}

Last updated