Skip to content
Go to Micro
Using the API

Querying

How to filter, sort, select, and paginate with the Micro API

All data in Micro is queried through a single endpoint:

POST /v2/prism/{teamId}/{objectType}/query

The request body contains a query object that describes what to fetch.

select is required. Pass an array of property slugs to return.

{
"query": {
"select": ["full_name", "email", "title"]
}
}

Use dot notation to traverse relationships:

{
"query": {
"select": ["full_name", "company.name", "company.primary_domain"]
}
}

filter is an array of conditions. Each condition is { slug: { operator: value } }.

{
"query": {
"select": ["full_name", "email"],
"filter": [
{ "labels": { "in": ["investor"] } },
{ "last_interaction_date": { ">=": "2024-01-01" } }
]
}
}
OperatorTypesDescription
=allExact match
!=allNot equal
< > <= >=number, dateComparison
instring, selectValue is in the array
not_instring, selectValue is not in the array
begins_withstringStarts with value
ends_withstringEnds with value
containsstringContains value
not_containsstringDoes not contain value
betweennumber, dateWithin a two-element [min, max] array, inclusive on both ends
existsanyField has a value
not_existsanyField has no value
is_nullanyAlias for not_exists — takes any truthy value
is_not_nullanyAlias for exists — takes any truthy value

Each filter object takes exactly one property with exactly one operator.

By default filters are combined with AND. Use combinator to switch to OR:

{
"query": {
"select": ["full_name"],
"filter": [
{ "labels": { "in": ["investor"] } },
{ "labels": { "in": ["founder"] } }
],
"combinator": "OR"
}
}

sort is an array of { slug: direction } objects. Earlier items in the array take priority.

{
"query": {
"select": ["full_name", "last_interaction_date"],
"sort": [
{ "last_interaction_date": "desc" },
{ "full_name": "asc" }
]
}
}

Use limit to set page size. It must be between 1 and 50 — requests above the cap are rejected rather than clamped.

{
"query": {
"select": ["full_name"],
"limit": 50
}
}

The response wraps rows in a data array alongside pagination metadata:

{
"data": [
{
"id": "c1a2b3c4-...",
"properties": {
"full_name": "Sarah Chen",
"email": "sarah@example.com"
}
}
],
"has_more": true,
"next_cursor": "eyJrIjoi..."
}

To fetch the next page, pass next_cursor back unchanged as cursor. When cursor is set, page and limit are derived from the cursor and any explicit values are ignored. has_more is false on the last page, at which point next_cursor is null.

{
"query": {
"select": ["full_name"],
"cursor": "eyJrIjoi..."
}
}

Set include_total: true (a sibling of query, not inside it) to add an unpaginated total to the response. It costs an extra pass over the result set, so prefer GET /v2/prism/{teamId}/{objectType}/count for unfiltered totals.

:::caution page still works but is deprecated — page-number pagination drifts under concurrent writes. Use cursor for anything other than a one-shot export. :::

Pass list_id — a UUID — to scope results to a specific list (e.g. your fundraising pipeline vs. your investor network):

{
"query": {
"select": ["full_name", "stage"],
"list_id": "3f9a1c42-5b7e-4d18-9a2f-8c1e6b0d7f35"
}
}

query rejects unknown properties, so a misspelled or renamed key returns 400 rather than being silently ignored.