GET /top-headlines
The most recent articles.
Recency rather than relevance, optionally narrowed by any filter. Equivalent to the `top_headlines` MCP tool. Credits: 1; 1-4 with near, bbox, amount_min or amount_max, whose candidates are checked in batches of 500; a cursor page costs 1-2 to start and 1-3 after; +1-2 per entity_id; +1 when signal_percentile_min resolves a threshold; +1 per full 1000 rows of offset. Pass estimate=true to get the exact range without running the call, or max_credits to refuse anything costlier.
Recency rather than relevance. There is no q: this endpoint answers "what is happening", and every
filter still applies, so "what is happening in Japanese-language energy coverage" is one request.
Parameters
Every filter, signal, time and paging parameter /search takes, minus
q and mode: there is nothing to rank, so there is nothing to choose a ranking for. Each
group is described in full on the page linked beside it.
- Filters
-
sourcesource_typepublisher_countrylanguagestory_idtopicorganizationpersoncountryauthorlocationlocation_idcityregionnamementioned_datequote_verbamount_objectestimatemax_credits - Entity ids
-
entity_id - Place
-
nearradius_kmbbox - Event classes
-
event_type - Amounts
-
amount_minamount_max - Signals
-
signalsignal_minsignal_maxsignalssignal_percentile_min - Time range
-
fromto - Paging, shape and facets
-
offsetlimitcursorfacetsfacet_limitview
Response
Identical to /search, with mode reported as
recent. Results are ordered by published_at, newest first. view=compact
trims each hit to the fields a model needs to choose what to read, which suits a feed that is polled often.
Under view=full each hit carries event_types, and, when near or
bbox filtered the feed, matched_locations. Geographic search has
an area's rules, and what checking one costs.
Because the order is fixed, this endpoint pages by cursor as well as by
offset: cursor=start, then each next_cursor. Pages stay disjoint while new
articles arrive, which an offset cannot promise on a feed that is still growing.
Example
# The last few hours of energy coverage from European publishers.
curl -s -G "https://api.unzoi.com/top-headlines" \
-H "x-api-key: $UNZOI_KEY" \
--data-urlencode "topic=ENV_OIL" \
--data-urlencode "language=eng" \
--data-urlencode "from=2026-08-26" \
--data-urlencode "limit=20" Counting a recency window
facets and facet_limit apply here, and they are the only thing this endpoint takes that
/stories does not. They count over the whole match set rather than over the
page you were handed, so faceting a recency window turns "what is happening" into "who is publishing it" in a
single request.
# The newest Japanese coverage, plus a count of which outlets and topics it came from.
curl -s -G "https://api.unzoi.com/top-headlines" \
-H "x-api-key: $UNZOI_KEY" \
--data-urlencode "publisher_country=JP" \
--data-urlencode "from=2026-08-26" \
--data-urlencode "facets=source,topic" \
--data-urlencode "limit=5" Pagination and facets covers how far to trust those counts, and when they are approximate rather than exact.
Polling for new articles
To follow a topic without polling, create a watch: the index runs a story query on an
interval and records new and growing stories as events, in a feed or as signed webhooks. To poll this endpoint
yourself instead, set from to your last poll and
deduplicate on id — or on story_id, if you would rather be told about events than about
articles, and /stories/{id} when one of them grows. Advance the
watermark only when the poll came back coverage: complete.
Monitoring a topic has a working loop, including how to pick an interval
that fits your credit budget.