Skip to main content
Retrieve posts collected by your watchlists. The endpoint serves both LinkedIn watchlists (keyword, people, company) and Reddit watchlists from the same URL: the source is auto-detected from the watchlist’s type, so you do not pass anything to switch between them. The field names are shared, but the contents are not interchangeable: a Reddit row leaves the LinkedIn-only fields empty or null, carries a source: "reddit" marker, and adds Reddit-only fields. See the Reddit watchlists section for the exact differences.

Query Parameters

string
required
Watchlist ID to retrieve posts from. This parameter is required and must be a single watchlist ID.
number
default:"1"
Page number for pagination. Combine with page_size to control how many posts you get per page (defaults to 20).
number
default:"20"
Number of posts returned per page. Used together with page (or on its own) for offset-free pagination, e.g. page=2&page_size=50 returns posts 51 to 100. Use page_size and page (or range_from/range_to); unrecognized aliases such as limit, offset, per_page, or pageSize are rejected with a 400 (with a did-you-mean hint naming the correct parameter where the alias is close enough, and the full allowed-parameter list in every case).

Filtering Parameters

string | array
Filter to posts classified into these intent labels (the watchlist’s label key strings). Pass multiple as comma-separated (labels=buying-intent,competitor-mention) or repeated params.Two special values:
  • default resolves to this watchlist’s default labels, the view the app opens on. This is the recommended way to read a feed. It can be mixed with explicit keys (labels=default,industry-news), and it is safe to send on any watchlist: on one with no default labels it simply applies no filter. Because the server resolves it, default is a reserved key, so a label of your own cannot be named default.
  • no labels fetches the unclassified bucket (stored tag "na").
Omitting labels returns every post, including the low-intent ones. That is the full firehose, not the app’s view. Read default_labels and applied_labels on the response to see which you got. See Intent labels & defaults.
string | array
Filter by specific people (profile slugs). LinkedIn watchlists only; ignored on Reddit.
string | array
Filter by specific companies (company slugs). LinkedIn watchlists only; ignored on Reddit.
string
Search within post content. LinkedIn watchlists only; ignored on Reddit.
boolean
Filter for bookmarked/saved posts only. Works on both LinkedIn and Reddit.
string | boolean
Restrict results to English posts only. Accepts "en", "english", "true", or true. Any other value is ignored.Non-English language filtering is not currently supported, posts in other languages can be retrieved by omitting this parameter.LinkedIn watchlists only; ignored on Reddit (Reddit posts do not carry a language field).
string
Filter posts from this date onwards (ISO 8601 format: YYYY-MM-DD). Works on both LinkedIn and Reddit.
string
Filter posts up to this date (ISO 8601 format: YYYY-MM-DD). Works on both LinkedIn and Reddit.
string
Filter by post type. Supports multiple comma-separated values. LinkedIn watchlists only; ignored on Reddit. See post_type under Response Fields for the values that exist, and note that a value outside that list is not an error, it simply matches nothing.The common use is post_type=job_update on a people watchlist, which is how job changes are read.
Filter for trending posts with high engagement. LinkedIn watchlists only; ignored on Reddit.
boolean
Filter for posts you’ve already liked or commented on. LinkedIn watchlists only; ignored on Reddit.
string | array
Filter by author’s seniority level. Supports multiple comma-separated values (e.g. "VP,Director"). Values must match exactly one of: "Entry Level", "Manager", "Senior", "Director", "VP", "CXO/Founder". An unrecognized value is rejected with a 400. LinkedIn watchlists only; ignored on Reddit (Reddit does not have author profile data).
string
Retrieve a specific post by its LinkedIn slug. LinkedIn watchlists only; ignored on Reddit.
string | array
Filter by post relevance bucket. Supports multiple comma-separated values (e.g. "high,medium"). Allowed values: "high" (relevance score 8 to 10), "medium" (4 to 7), "low" (1 to 3); any other value is rejected with a 400. Works on both LinkedIn and Reddit watchlists. Note: the bucketed relevance_level response field is currently only returned on Reddit rows; on LinkedIn, use the numeric relevance_score field on each post.

Sorting Parameters

string
default:"recent"
Sort order for posts. The allowed set depends on the watchlist’s type, because Reddit rows have no like count to rank by:
  • On a keyword, people or company watchlist: recent, popular_first, engagement.
  • On a reddit watchlist: recent, relevance_first, popular_first, engagement.
What each one does:
  • recent: most recent posts first (default, every type)
  • popular_first: highest engagement (likes plus comments) first. On Reddit it aliases to relevance_first.
  • engagement: alias for popular_first.
  • relevance_first: relevance score first, then post date. Reddit only.
Anything outside the allowed set for that watchlist is rejected with a 400 naming what is allowed, for example Invalid value(s) for sort_by: relevance_first. Allowed values for a keyword watchlist: recent, popular_first, engagement. It is never silently downgraded to recent. To rank a LinkedIn feed by relevance, read relevance_score on each post and sort client-side.
number
default:"0"
Pagination start offset (0-indexed). Use with range_to for custom page sizes.
number
default:"19"
Pagination end offset (inclusive). Default returns 20 posts (0-19).

Response Fields

array
Array of post objects
number
Total number of posts matching the filters
array
The label keys this watchlist opens on in the app, and what labels=default resolves to. Present on every response.An empty array is common and worth handling. It means the watchlist has no defaults, so labels=default filtered nothing. Treat it as the cue to pick labels explicitly: read the watchlist’s label set with GET /api-keyword-watchlist?id=..., choose the keys that match what you want, and pass those. Always empty on people and company watchlists, which have no intent labels at all.
array
The label keys that actually filtered this response, after default was resolved. Empty means no label filter ran and you are looking at every post. Present on every response.Compare the two to tell a narrowed feed from the full one without a second call: applied_labels equal to default_labels means you got the app’s view.

Post Object Fields

string
Unique post identifier
string
Direct URL to the LinkedIn post. null on Reddit watchlists; see reddit_url instead.
string
ID of the watchlist this post belongs to
string
Post text content
string
Name of the post author
string
LinkedIn profile slug of the author
string
Headline/bio of the post author
string
Profile image URL of the author
string
ISO 8601 timestamp when the post was added to OutX
string
ISO 8601 timestamp when the post was published on LinkedIn
number
Number of likes on the post
number
Number of comments on the post
number
Number of shares/reposts
boolean
Whether the post has been bookmarked/saved
string
What kind of row this is. The full set of values:
  • person: a LinkedIn post authored by a person
  • company: a LinkedIn post authored by a company page
  • school: a LinkedIn post authored by a school page
  • job_update: a tracked person changed job, with the job-change text in content (people watchlists)
  • birthday_update: a tracked person’s birthday (people watchlists)
  • reddit_post: a Reddit post (Reddit watchlists only)
  • reddit_comment: a Reddit comment (Reddit watchlists only)
Older rows can have post_type as null.job_update and birthday_update rows carry no intent label. They are never classified, so their tags stay empty and labels= filters exclude them. Read them by filtering on post_type instead.This field is about the author or the event, not the media in the post. There is no image, video, article or poll value: filtering on those matches nothing.
string
Detected language of the post. Empty string on Reddit watchlists.
array
The intent label(s) the post was classified into, matching the labels set on the watchlist (a tag equals a label key). A post with no confident match has ["na"], and tags is empty until the post has been enriched. See Intent labels & defaults.
There is no sentiment field. OutX returns intent labels (tags), not sentiment, and relevance_score measures relevance to the watchlist, not tone. tags are written asynchronously during enrichment, so a freshly collected post can return empty tags for a while, treat that as “not classified yet,” not “no match.”
array
Array of image URLs attached to the post
array
Array of video data attached to the post
string
Seniority level of the post author. One of "Entry Level", "Manager", "Senior", "Director", "VP", "CXO/Founder". Empty string on Reddit watchlists.
number
Relevance score of the post (1-10). High: 8-10, Medium: 4-7, Low: 1-3. Returned for both LinkedIn and Reddit posts.
array
Array of countries associated with the post author’s location. When the location could not be determined, this is the single-element array ["NA"] rather than an empty array. null on Reddit watchlists.
array
Array of objects with tag and description for each tag.

Reddit watchlists

The /api-posts endpoint also serves Reddit watchlists. The URL, authentication, and pagination are identical to the LinkedIn flow; pass the Reddit watchlist’s id as watchlist_id and the server detects the source from tracking_lists.type. A Reddit row in data represents either a Reddit post or a top-level comment that matched one of the watchlist keywords. The shared response fields above are filled best-effort, with these source-specific differences:
  • A discriminator field, source: "reddit", is present on every Reddit row. LinkedIn rows do not include this field.
  • linkedin_post_url, videos, and location_countries are always null.
  • language, author_url, author_headline, and seniority_level are empty strings (Reddit posts do not carry these data).
  • shares_count and comments_count are always 0. Use comment_* and post_vote_count mappings instead.
  • likes_count is the Reddit post upvote net score (mapped from post_vote_count).
  • tags is a single-element array derived from the row’s label column.
  • post_type is "reddit_post" for posts and "reddit_comment" for comments.
Reddit rows include these additional fields:
string
Always "reddit" on Reddit rows. Absent on LinkedIn rows.
string
Direct URL to the Reddit post or comment.
string
Reddit post title. May be null for rows that represent a comment under a post that was not separately ingested.
string
Body of the Reddit post.
string
Subreddit name (e.g. r/dataengineering). Mapped from the underlying post_group_name column.
string
Reddit username of the comment author. null when the row is a post.
string
Comment body. null when the row is a post.
string
ISO 8601 timestamp of the comment. null when the row is a post.
number
Reddit comment upvote net score. 0 when the row is a post.
string
Bucketed relevance: "high", "medium", or "low". Derived from relevance_score. null if the post has not been scored.
array
Array containing the watchlist keyword that matched this row. Empty if the row is no longer linked to a keyword (for example after a watchlist update).

Reddit response example

Response (Reddit watchlist)
default_labels and applied_labels come back on Reddit watchlists exactly as they do on LinkedIn ones, and mean the same thing (see Response Fields above). applied_labels is empty here because the request passed no labels, so every collected post was returned.

Reddit examples

Get posts from a Reddit watchlist
High-relevance Reddit posts only

Pagination

Posts are returned in batches of 20 by default. You can use either page + page_size (simpler) or range_from + range_to (offset-based) to paginate.
The count field in the response shows the total number of posts matching your filters, so you know how many pages to fetch.

Error Responses

Frequently Asked Questions

No. The api-posts endpoint now requires a single watchlist_id and returns posts for that watchlist only. To build a unified feed across multiple watchlists, make separate requests per watchlist and merge the results on your side.
The default page size is 20 posts. To change it, pass page_size (for example page_size=50 returns 50 posts per page), or use range_from and range_to for offset-based pagination (e.g. range_from=0&range_to=49 returns the first 50). The count field in the response tells you the total number of matching posts so you know how many pages to fetch.
Pass labels=default. The server resolves it to the watchlist’s default: true label keys and reports both default_labels and applied_labels on the response. The API never applies defaults on its own, so omitting labels gives you everything collected.
Filter the people watchlist’s own feed with post_type=job_update. There is no separate endpoint. Those rows carry the job-change text in content and no intent label, so do not combine them with a labels filter.
Pass comma-separated values to the seniority_level parameter. For example: seniority_level=VP,Director. This returns posts authored by people at any of those seniority levels. Values must match exactly one of: Entry Level, Manager, Senior, Director, VP, CXO/Founder. An unrecognized value is rejected with a 400.