API summary
Filter grammar
Every filter describes which individual posts to keep. The API checks each post against your filter independently. There are two building blocks:Single condition
AND / OR group
Array fields
hashtags, mentions.person_id, mentions.company_id,
mentions.person_url, and mentions.company_url hold several values per
post. A condition on one of them is satisfied when any value matches, so
hashtags = "hiring" keeps every post that carries that tag among others.
Filter operators
Use the table below to pick the righttype for each condition. Every
operator works on filterable fields only; see
Filterable fields.
Geographic radius filters (geo_distance / geo_exclude)
The value is an object describing a center point and a radius:
Posts by authors within 25 km of Bengaluru:
Nested-array matching: all_of and has_all
reactors and comments are arrays of nested objects. Each reactor
entry has its own reaction_type, title, company, and so on, and each
comment has its own text, created_at, and commenter attributes. When you
put several conditions on one of these arrays, there are two things you
might mean:
- Same element: one reactor satisfies every condition (a founder whose
reaction was
PRAISE). - Cross element: different reactors each satisfy a condition (a founder reacted and a recruiter reacted, not necessarily the same person).
and group over one nested array means same element. To express
cross element, use an all_of group or the has_all operator.
all_of: each condition matched by some element
Each condition inside all_of must be satisfied by at least one array
element, evaluated independently. A condition can be a single filter or an
and/or group; a group is matched within one element.
Posts where some founder reacted and some recruiter reacted:
total_count: 59960. Wrap a condition in an and group to pin it
to one element: a founder whose reaction was PRAISE, plus any recruiter.
total_count: 13723. all_of groups nest freely inside and and
or groups, so you can combine cross-element requirements with post-level
filters such as date_posted.
has_all: every value matched by some element
has_all is shorthand for the common cross-element case: a value list where
each value is matched by some element of the array. The same query as the
first all_of example:
total_count: 5505. The count is lower than the all_of form
because has_all matches each value as a whole term rather than with the
typo-tolerant (.) operator.
Filterable fields
Only the fields below can appear infilters. Any other path returns 400
with Unsupported columns in conditions: [...].
Post
Author (actor.*)
Reposter (reposter.*)
Present on repost_quote and repost_without_thoughts rows.
Engagement (engagement.*)
Reactors (reactors.*, nested)
Filter paths are flat even though the response nests the person under
reactors[].reactor.
Comments (comments.*, nested)
Filter paths are flat even though the response nests the person under
comments[].commenter.
Mentions and attachments
Filter-only fields
These fields accept filters but are not returned and cannot be listed infields.
Sortable fields
The sort allowlist is narrower than the filter allowlist. Sorting on any other field, includingtext, returns 400 with
Unsupported columns in conditions: ['text'].
date_posted(the default, descending)post_typeactor.actor_typeengagement.total_reactionsengagement.total_commentsengagement.num_sharesengagement.reactions_by_type.LIKE,.PRAISE,.EMPATHY,.INTEREST,.APPRECIATION,.ENTERTAINMENTis_editedhas_videopoll.closedpoll.multi_selectdocument.page_count
Response field reference
Every post carries every group below unless you narrow it withfields.
Fields the source record lacks are omitted from actor and reposter
rather than returned as null, so treat each actor field as optional.
Post
actor and reposter
actor is the author. reposter is present on reposts and has the same
shape.
engagement
reactors[]
Every reaction on the post. The array is returned in full, not just the
elements that matched your filter.
comments[]
Every comment on the post, returned in full.
mentions and hyperlinks
Attachments and metadata
Attachment objects are always present. A post without a document, article,
or poll returns the object with empty strings,
0, false, and [] rather
than null. Use content_types or the content_type filter to test for an
attachment.
Current platform behavior
These are observed behaviors of the current index build, not part of the contract. They resolve at the next full index refresh.has_videoistrueon every post, and thecontent_typefilter valuesvideoandimagematch every post. Filter ondocument,article, orpoll, and treathas_videoand thevideoandimageentries incontent_typesas unreliable until then.is_not_nullovermatches on attachment text fields. Because empty attachments are stored as empty strings,poll.question is_not_nullmatches every post. Test attachments withcontent_typeinstead.
Errors
Every
400, 403, and 500 uses the nested envelope
{ "error": { "type", "message", "metadata" } }, and none of them charges
credits. Branch on error.type rather than string-matching message.
available_fields list in the unknown-field 400 is cut short here; the
API returns every selectable path.
Pagination and sorting
Sorting
sorts is an ordered array. Each item has a field and an order (asc
or desc). Sorts apply in array order: the first is the primary key and the
second breaks ties. Omitting sorts orders by date_posted descending.
order returns 400 with
Missing required field: 'sorts.0.order'.
Pagination
Pagination is cursor-based. Each response returns anext_cursor, or null
at the end of the result set. To fetch the next page, resend the original
body with cursor set to the previous next_cursor.
1
Fetch the first page
Omit
cursor and set limit to your page size (max 1000).2
Walk forward
Take
next_cursor from the response and pass it back as cursor.
Keep filters, sorts, and fields identical. A cursor issued for
a different body is rejected with Invalid cursor.3
Stop when next_cursor is null
A
null cursor means you have reached the end of the result set.total_count is computed once for the query and stays stable across pages.
Dataset freshness
The index is rebuilt periodically from the full post dataset, so every post in a build shares onematerialized_at value. The newest posts in the index
can be several days old at the time you query. For the latest posts by one
person or company, use
Enrich Social Posts.
Field selection
Usefields to return only the dot-paths you need. You can request a whole
group such as "actor" or "engagement", a sub-object such as
"actor.location" or "engagement.reactions_by_type", or a single field
such as "actor.name".
actor.locationis selected whole. Filters acceptactor.location.city, butfieldsdoes not; requestactor.location.- Filter-only fields cannot be selected.
content_typeandmaterialized_atinfieldsreturn400withInvalid fields: .... - Leave
reactorsandcommentsout unless you need them. They are returned in full and a popular post carries thousands of entries.
What’s next
- Examples on the introduction page.
- Pricing and Rate limits.
- Permissions to check which fields your key holds on
/social_post/search.

