Skip to content
unzoi docs
Search and navigation
Start here
REST API
MCP
Limits and plans
Agent clients
SDKs
Guides

Tool reference

All 18 tools, generated from https://api.unzoi.com/mcp/tools.json — the schemas the server actually accepts, not a second copy of them.

Every tool maps onto a REST endpoint, and the arguments are that endpoint's query parameters (for create_watch, the fields of its request body). Two argument shapes are richer than their query-string form, because a model emits them more reliably: facets is an array of strings rather than a comma-separated list, and signals is an array of {name, min, max} objects rather than the packed name:min:max syntax. Every tool declares additionalProperties: false — an argument it does not list is refused — and an outputSchema, the shape of what it returns.

The tools cover searching, expanding, counting over time, resolving names, monitoring and relationships. The relationship tools, related_entities, connection_path, entity_network and shared_exposures, count co-mentions in the reporting and return the articles as evidence; Relationships explains what they measure and what they do not. Every tool result reports credits_charged, what the call was charged; every tool takes estimate to price a call without running it and max_credits to cap it.

search_news

Equivalent to /search over REST.

Search the news index. Returns ranked articles with image, topics, entities, locations, and versioned industry/business/risk language signals. Supports keyword, semantic, or hybrid ranking, exact metadata filters, numeric signal ranges, pagination, and facets. Omit `q` for a newest-first browse of whatever the filters match; pass `story_id` to list every article in one story. Never conclude that something does not exist when `partial` is true, `coverage` is not `complete`, or `from_clamped` is true: retry, narrow the time range, or check `account_status` for the plan's archive depth.

Credits: 1 for keyword ranking or a browse, 2 for semantic, 3 for hybrid; 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.

Argument Type Description
amount_max number Articles mentioning a numeric amount of at most this value. With amount_min, one amount must satisfy both; with amount_object, that amount must describe the object.
amount_min number Articles mentioning a numeric amount of at least this value. With amount_max, one amount must satisfy both; with amount_object, that amount must describe the object.
amount_object string An exact object described by a numeric amount.
author string An exact article author.
bbox string A box, `south,west,north,east` in decimal degrees: articles mentioning a city inside it. West greater than east crosses the antimeridian. Not with near.
city string An exact mentioned city.
country string A mentioned country's canonical two-character identifier.
cursor string Keyset paging for a newest-first browse (no `q`): pass `start` for the first page, then the `next_cursor` the response carried. Pages are deterministic and disjoint even across articles sharing one timestamp. The first page costs two index queries and each later page three. Not with `offset`, `q`, or a ranked `mode`.
entity_id string Up to five entity ids from resolve_entity, comma separated (over REST the parameter may also repeat). Each matches any spelling in its alias group in the requested window; several ids must all match. The spellings used are reported in `resolved`.
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
event_type `bankruptcy` · `earnings_report` · `ipo` · `cyber_attack` · `outage` · `industrial_accident` · `sanctions` · `trade_dispute` · `boycott` · `nationalization` · `privatization` · `money_laundering` · `executive_change` · `factory_closure` · `supply_shortage` · `labor_strike` · `antitrust_action` An event class derived from the article's GKG themes (events-v1). Precise rather than complete: an article can describe an event without carrying its class.
facet_limit integer Values per facet, 1-100 (default 10).
facets `source` · `source_type` · `publisher_country` · `language` · `story_id` · `topic` · `organization` · `person` · `country` · `author` · `location` · `location_id` · `city` · `region` · `name` · `mentioned_date` · `quote_verb` · `amount_object` · `event_type`[] Comma-separated fields to count over the full match set, up to 8.
from string Lower time bound, e.g. 2026-07-09 or 20260709120000. Clamped forward to what the caller's plan may reach; see `history_days` and `from_clamped` in the response.
language string Source language, ISO-639-3, e.g. eng, fra, ara, zho.
limit integer Results per page, 1-100 (default 10).
location string An exact mentioned location.
location_id string An exact canonical location identifier.
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.
mentioned_date string An exact date mentioned in the article text.
mode `keyword` · `semantic` · `hybrid` · `recent` Ranking mode. `hybrid` is usually right when a model wrote the query, because models paraphrase. `recent` orders newest-first and is implied when `q` is omitted.
name string An exact proper name.
near string A point, `latitude,longitude` in decimal degrees, e.g. 48.8566,2.3522. With radius_km: articles mentioning a city within that distance. On article results (/search, /top-headlines) each hit reports the cities that matched as matched_locations.
offset integer Zero-based result offset, up to 100000.
organization string An exact organization entity.
person string An exact person entity.
publisher_country string The publisher's canonical two-character country identifier.
q string Query text. Omit for a recency browse.
quote_verb string An exact verb introducing a quotation.
radius_km number With near: the distance in kilometres, 0.1-2000.
region string An exact mentioned region.
signal `economy` · `healthcare` · `agriculture` · `labor` · `environment` · `energy` · `transportation` · `real_estate` · `finance` · `defense` · `science_technology` · `trade` · `public_sector` · `financial_uncertainty` · `financial_negative` · `financial_positive` · `legal_litigation` · `financial_stability_stress` · `anxiety` · `conflict` · `supply_disruption` · `cyber_incident` · `climate` · `health_security` · `governance_risk` A normalized business signal to range-filter on, e.g. finance, energy, conflict. An unknown name is rejected.
signal_max number Inclusive upper bound for `signal`.
signal_min number Inclusive lower bound for `signal`.
signal_percentile_min number With `signal`: keep only articles at or above this percentile of the signal's intensity over the match set (50-99.9). The threshold used is reported as `signal_threshold`. Not with `signal_min`.
signals {max, min, name}[] Several signal ranges at once, ANDed: `name[:min[:max]]`, comma separated, e.g. `finance:1.5:,energy::2`.
source string Source domain, e.g. bbc.co.uk.
source_type `web` · `citation` · `academic_archive` · `defense_archive` · `journal_archive` · `non_textual` · `other` The kind of source: web | citation | academic_archive | defense_archive | journal_archive | non_textual | other.
story_id string A cluster id from /stories, to expand one story into its articles.
to string Upper time bound, same formats as `from`.
topic string An exact canonical topic identifier returned by the API.
view `full` · `compact` How much of each hit to return. `full` (default) is the whole Article; `compact` keeps id, title, url, source, published_at, language, story_id and score. Use compact when results feed a model.

Returns {attribution, coverage, credits_charged, facets, from_clamped, has_more, history_days, limit, mode, next_cursor, offset, partial, resolved, results, signal_threshold, total, total_relation} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

list_stories

Equivalent to /stories over REST.

Search and collapse results into deduplicated stories (one real event across many outlets). Returns story_id, article count, outlet count, and a representative headline. Prefer this over search_news whenever the results go into a context window. Never conclude that something does not exist when `partial` is true, `coverage` is not `complete`, or `from_clamped` is true: retry, narrow the time range, or check `account_status` for the plan's archive depth.

Credits: 1, or 2 semantic and 3 hybrid unless sort=recency; +1 with near, bbox, event_type or amount bounds; +1-2 per entity_id; +1 when signal_percentile_min resolves a threshold; +1 per full 100 rows of offset, which stops at 1000. Pass estimate=true to get the exact range without running the call, or max_credits to refuse anything costlier.

Argument Type Description
amount_max number Articles mentioning a numeric amount of at most this value. With amount_min, one amount must satisfy both; with amount_object, that amount must describe the object.
amount_min number Articles mentioning a numeric amount of at least this value. With amount_max, one amount must satisfy both; with amount_object, that amount must describe the object.
amount_object string An exact object described by a numeric amount.
author string An exact article author.
bbox string A box, `south,west,north,east` in decimal degrees: articles mentioning a city inside it. West greater than east crosses the antimeridian. Not with near.
city string An exact mentioned city.
country string A mentioned country's canonical two-character identifier.
entity_id string Up to five entity ids from resolve_entity, comma separated (over REST the parameter may also repeat). Each matches any spelling in its alias group in the requested window; several ids must all match. The spellings used are reported in `resolved`.
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
event_type `bankruptcy` · `earnings_report` · `ipo` · `cyber_attack` · `outage` · `industrial_accident` · `sanctions` · `trade_dispute` · `boycott` · `nationalization` · `privatization` · `money_laundering` · `executive_change` · `factory_closure` · `supply_shortage` · `labor_strike` · `antitrust_action` An event class derived from the article's GKG themes (events-v1). Precise rather than complete: an article can describe an event without carrying its class.
from string Lower time bound, e.g. 2026-07-09 or 20260709120000. Clamped forward to what the caller's plan may reach; see `history_days` and `from_clamped` in the response.
language string Source language, ISO-639-3, e.g. eng, fra, ara, zho.
limit integer Results per page, 1-100 (default 10).
location string An exact mentioned location.
location_id string An exact canonical location identifier.
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.
mentioned_date string An exact date mentioned in the article text.
mode `keyword` · `semantic` · `hybrid` · `recent` Ranking mode. `hybrid` is usually right when a model wrote the query, because models paraphrase. `recent` orders newest-first and is implied when `q` is omitted.
name string An exact proper name.
near string A point, `latitude,longitude` in decimal degrees, e.g. 48.8566,2.3522. With radius_km: articles mentioning a city within that distance. On article results (/search, /top-headlines) each hit reports the cities that matched as matched_locations.
offset integer Zero-based result offset, up to 100000.
organization string An exact organization entity.
person string An exact person entity.
publisher_country string The publisher's canonical two-character country identifier.
q string Query text. Omit for a recency browse.
quote_verb string An exact verb introducing a quotation.
radius_km number With near: the distance in kilometres, 0.1-2000.
region string An exact mentioned region.
signal `economy` · `healthcare` · `agriculture` · `labor` · `environment` · `energy` · `transportation` · `real_estate` · `finance` · `defense` · `science_technology` · `trade` · `public_sector` · `financial_uncertainty` · `financial_negative` · `financial_positive` · `legal_litigation` · `financial_stability_stress` · `anxiety` · `conflict` · `supply_disruption` · `cyber_incident` · `climate` · `health_security` · `governance_risk` A normalized business signal to range-filter on, e.g. finance, energy, conflict. An unknown name is rejected.
signal_max number Inclusive upper bound for `signal`.
signal_min number Inclusive lower bound for `signal`.
signal_percentile_min number With `signal`: keep only articles at or above this percentile of the signal's intensity over the match set (50-99.9). The threshold used is reported as `signal_threshold`. Not with `signal_min`.
signals {max, min, name}[] Several signal ranges at once, ANDed: `name[:min[:max]]`, comma separated, e.g. `finance:1.5:,energy::2`.
sort `count` · `outlets` · `recency` Story order: `count` (articles, default), `outlets` (distinct publishers), or `recency` (newest representative article first, ranked newest-first before collapsing).
source string Source domain, e.g. bbc.co.uk.
source_type `web` · `citation` · `academic_archive` · `defense_archive` · `journal_archive` · `non_textual` · `other` The kind of source: web | citation | academic_archive | defense_archive | journal_archive | non_textual | other.
story_id string A cluster id from /stories, to expand one story into its articles.
to string Upper time bound, same formats as `from`.
topic string An exact canonical topic identifier returned by the API.

Returns {attribution, coverage, credits_charged, from_clamped, has_more, history_days, limit, offset, partial, resolved, signal_threshold, stories, total, total_relation} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

top_headlines

Equivalent to /top-headlines over REST.

Most-recent articles, optionally filtered by indexed article metadata and time range. The same as search_news with no `q`. Never conclude that something does not exist when `partial` is true, `coverage` is not `complete`, or `from_clamped` is true: retry, narrow the time range, or check `account_status` for the plan's archive depth.

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.

Argument Type Description
amount_max number Articles mentioning a numeric amount of at most this value. With amount_min, one amount must satisfy both; with amount_object, that amount must describe the object.
amount_min number Articles mentioning a numeric amount of at least this value. With amount_max, one amount must satisfy both; with amount_object, that amount must describe the object.
amount_object string An exact object described by a numeric amount.
author string An exact article author.
bbox string A box, `south,west,north,east` in decimal degrees: articles mentioning a city inside it. West greater than east crosses the antimeridian. Not with near.
city string An exact mentioned city.
country string A mentioned country's canonical two-character identifier.
cursor string Keyset paging for a newest-first browse (no `q`): pass `start` for the first page, then the `next_cursor` the response carried. Pages are deterministic and disjoint even across articles sharing one timestamp. The first page costs two index queries and each later page three. Not with `offset`, `q`, or a ranked `mode`.
entity_id string Up to five entity ids from resolve_entity, comma separated (over REST the parameter may also repeat). Each matches any spelling in its alias group in the requested window; several ids must all match. The spellings used are reported in `resolved`.
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
event_type `bankruptcy` · `earnings_report` · `ipo` · `cyber_attack` · `outage` · `industrial_accident` · `sanctions` · `trade_dispute` · `boycott` · `nationalization` · `privatization` · `money_laundering` · `executive_change` · `factory_closure` · `supply_shortage` · `labor_strike` · `antitrust_action` An event class derived from the article's GKG themes (events-v1). Precise rather than complete: an article can describe an event without carrying its class.
facet_limit integer Values per facet, 1-100 (default 10).
facets `source` · `source_type` · `publisher_country` · `language` · `story_id` · `topic` · `organization` · `person` · `country` · `author` · `location` · `location_id` · `city` · `region` · `name` · `mentioned_date` · `quote_verb` · `amount_object` · `event_type`[] Comma-separated fields to count over the full match set, up to 8.
from string Lower time bound, e.g. 2026-07-09 or 20260709120000. Clamped forward to what the caller's plan may reach; see `history_days` and `from_clamped` in the response.
language string Source language, ISO-639-3, e.g. eng, fra, ara, zho.
limit integer Results per page, 1-100 (default 10).
location string An exact mentioned location.
location_id string An exact canonical location identifier.
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.
mentioned_date string An exact date mentioned in the article text.
name string An exact proper name.
near string A point, `latitude,longitude` in decimal degrees, e.g. 48.8566,2.3522. With radius_km: articles mentioning a city within that distance. On article results (/search, /top-headlines) each hit reports the cities that matched as matched_locations.
offset integer Zero-based result offset, up to 100000.
organization string An exact organization entity.
person string An exact person entity.
publisher_country string The publisher's canonical two-character country identifier.
quote_verb string An exact verb introducing a quotation.
radius_km number With near: the distance in kilometres, 0.1-2000.
region string An exact mentioned region.
signal `economy` · `healthcare` · `agriculture` · `labor` · `environment` · `energy` · `transportation` · `real_estate` · `finance` · `defense` · `science_technology` · `trade` · `public_sector` · `financial_uncertainty` · `financial_negative` · `financial_positive` · `legal_litigation` · `financial_stability_stress` · `anxiety` · `conflict` · `supply_disruption` · `cyber_incident` · `climate` · `health_security` · `governance_risk` A normalized business signal to range-filter on, e.g. finance, energy, conflict. An unknown name is rejected.
signal_max number Inclusive upper bound for `signal`.
signal_min number Inclusive lower bound for `signal`.
signal_percentile_min number With `signal`: keep only articles at or above this percentile of the signal's intensity over the match set (50-99.9). The threshold used is reported as `signal_threshold`. Not with `signal_min`.
signals {max, min, name}[] Several signal ranges at once, ANDed: `name[:min[:max]]`, comma separated, e.g. `finance:1.5:,energy::2`.
source string Source domain, e.g. bbc.co.uk.
source_type `web` · `citation` · `academic_archive` · `defense_archive` · `journal_archive` · `non_textual` · `other` The kind of source: web | citation | academic_archive | defense_archive | journal_archive | non_textual | other.
story_id string A cluster id from /stories, to expand one story into its articles.
to string Upper time bound, same formats as `from`.
topic string An exact canonical topic identifier returned by the API.
view `full` · `compact` How much of each hit to return. `full` (default) is the whole Article; `compact` keeps id, title, url, source, published_at, language, story_id and score. Use compact when results feed a model.

Returns {attribution, coverage, credits_charged, facets, from_clamped, has_more, history_days, limit, mode, next_cursor, offset, partial, resolved, results, signal_threshold, total, total_relation} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

get_article

Equivalent to /doc/{id} over REST.

Fetch a single article's rich metadata by id, including names, structured locations and dates, quotations, amounts, related media, links, and alternate URLs. The body is never returned; link the url.

Credits: 1. Pass estimate=true to get the exact range without running the call, or max_credits to refuse anything costlier.

Argument Type Description
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
id required string The article id, from any search result.
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.

Returns {activity_density, amounts, amp_url, authors, cities, collected_at, countries, credits_charged, date_mentions, event_types, id, image, language, links, location_details, locations, matched_locations, mentioned_dates, mobile_url, names, negative_score, organizations, persons, polarity, positive_score, published_at, publisher_country, quotes, regions, related_images, score, self_reference_density, signals, social_images, social_videos, source, source_type, story_id, title, tone, topics, url, word_count} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

Equivalent to /similar/{id} over REST.

Find articles semantically similar to a given article id (More-Like-This). Returns distinct related stories (deduplicated across outlets), excluding the seed article. Cheaper and usually better than reformulating a query. Never conclude that something does not exist when `partial` is true, `coverage` is not `complete`, or `from_clamped` is true: retry, narrow the time range, or check `account_status` for the plan's archive depth.

Credits: 2, for the vector search behind it. Pass estimate=true to get the exact range without running the call, or max_credits to refuse anything costlier.

Argument Type Description
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
id required string Seed article id to find related stories for.
limit integer Results per page, 1-100 (default 10).
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.
view `full` · `compact` How much of each hit to return. `full` (default) is the whole Article; `compact` keeps id, title, url, source, published_at, language, story_id and score. Use compact when results feed a model.

Returns {attribution, coverage, credits_charged, facets, from_clamped, has_more, history_days, limit, mode, next_cursor, offset, partial, resolved, results, signal_threshold, total, total_relation} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

get_story

Equivalent to /stories/{id} over REST.

Expand one story by its story_id (from list_stories or any article): the article and outlet counts, every outlet, when it was first and last seen, the entities and topics it is about, and its newest articles as compact hits. One call, no re-search. `articles_truncated` true means more members exist: page them with search_news and story_id. Never conclude that something does not exist when `partial` is true, `coverage` is not `complete`, or `from_clamped` is true: retry, narrow the time range, or check `account_status` for the plan's archive depth.

Credits: 2 for the whole story, however many articles it lists. Pass estimate=true to get the exact range without running the call, or max_credits to refuse anything costlier.

Argument Type Description
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
from string Lower time bound, e.g. 2026-07-09 or 20260709120000. Clamped forward to what the caller's plan may reach; see `history_days` and `from_clamped` in the response.
id required string The story id, from list_stories or an article's story_id.
limit integer Articles to list, 1-100 (default 20). `articles_truncated` says whether more exist; page them with /search?story_id=.
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.
to string Upper time bound, same formats as `from`.

Returns {articles, articles_returned, articles_truncated, attribution, count, coverage, credits_charged, first_reported, first_seen, from_clamped, history_days, languages, last_seen, outlets, partial, publisher_countries, representative_article_id, sources, sources_by_first_seen, story_id, title, title_variants, top_organizations, top_persons, top_topics, url} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

resolve_entity

Equivalent to /entities over REST.

Find the spellings the index holds for an organization, person, place, topic, author or source, before filtering on it. Filters are exact matches on the index's own values, so `organization=ASML Holding NV` matches nothing while `asml` matches thousands. Returns groups of aliases with a stable entity_id, a canonical spelling, per-alias article counts and a confidence (1.0 exact, 0.8 prefix, 0.6 acronym). Pass a returned `value` verbatim as the matching filter. Ids are deterministic for the resolution version, not a registry. Pass a time range: the values are counted over it. An empty list means the index holds no such spelling in the window, not that the entity is absent from the news. Never conclude that something does not exist when `partial` is true, `coverage` is not `complete`, or `from_clamped` is true: retry, narrow the time range, or check `account_status` for the plan's archive depth.

Credits: 1-2; the second pass runs only when the name's own words match nothing. Pass estimate=true to get the exact range without running the call, or max_credits to refuse anything costlier.

Argument Type Description
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
from string Lower time bound, e.g. 2026-07-09 or 20260709120000. Clamped forward to what the caller's plan may reach; see `history_days` and `from_clamped` in the response.
limit integer Results per page, 1-100 (default 10).
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.
q required string The name to resolve, as the user gave it (any spelling or case). Matched against the index's own values after normalisation.
to string Upper time bound, same formats as `from`.
type required `organization` · `person` · `location` · `city` · `region` · `name` · `topic` · `author` · `source` Which entity field to resolve against; the returned `value`s are filters on it.

Returns {approximate, attribution, coverage, credits_charged, entities, from_clamped, history_days, limit, partial, q, type} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

aggregate_news

Equivalent to /aggregate over REST.

A time series over the match set: per calendar bucket (hour, day, week, month, or `all` for one bucket), the article count and optionally the distinct story count, the distinct outlet count and a signal's mean and percentiles. One call replaces one search per day. Pass `from`: the plan's archive window fills it in when omitted, and a session without a plan is refused without one. At most 366 buckets. Distinct counts are approximate across indexes and say so. Never conclude that something does not exist when `partial` is true, `coverage` is not `complete`, or `from_clamped` is true: retry, narrow the time range, or check `account_status` for the plan's archive depth.

Credits: 1, whatever the number of buckets; +1 with event_type; +1-2 per entity_id. Pass estimate=true to get the exact range without running the call, or max_credits to refuse anything costlier.

Argument Type Description
amount_object string An exact object described by a numeric amount.
author string An exact article author.
city string An exact mentioned city.
country string A mentioned country's canonical two-character identifier.
entity_id string Up to five entity ids from resolve_entity, comma separated (over REST the parameter may also repeat). Each matches any spelling in its alias group in the requested window; several ids must all match. The spellings used are reported in `resolved`.
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
event_type `bankruptcy` · `earnings_report` · `ipo` · `cyber_attack` · `outage` · `industrial_accident` · `sanctions` · `trade_dispute` · `boycott` · `nationalization` · `privatization` · `money_laundering` · `executive_change` · `factory_closure` · `supply_shortage` · `labor_strike` · `antitrust_action` An event class derived from the article's GKG themes (events-v1). Precise rather than complete: an article can describe an event without carrying its class.
from string Lower time bound, e.g. 2026-07-09 or 20260709120000. Clamped forward to what the caller's plan may reach; see `history_days` and `from_clamped` in the response.
interval required `hour` · `day` · `week` · `month` · `all` Bucket width, aligned to the calendar in UTC: hour, day, week (Monday), month, or `all` for one bucket over the whole range. At most 366 buckets.
language string Source language, ISO-639-3, e.g. eng, fra, ara, zho.
location string An exact mentioned location.
location_id string An exact canonical location identifier.
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.
mentioned_date string An exact date mentioned in the article text.
metrics string Comma-separated: `articles` (always reported), `stories` (distinct story ids), `outlets` (distinct publisher domains), `signal:<name>` (mean and percentiles of one signal). Default `articles`.
name string An exact proper name.
organization string An exact organization entity.
percentile number An extra percentile to report for every `signal:` metric, 1-99.9; the 50th and 95th are always reported.
person string An exact person entity.
publisher_country string The publisher's canonical two-character country identifier.
q string Query text. Omit for a recency browse.
quote_verb string An exact verb introducing a quotation.
region string An exact mentioned region.
signal `economy` · `healthcare` · `agriculture` · `labor` · `environment` · `energy` · `transportation` · `real_estate` · `finance` · `defense` · `science_technology` · `trade` · `public_sector` · `financial_uncertainty` · `financial_negative` · `financial_positive` · `legal_litigation` · `financial_stability_stress` · `anxiety` · `conflict` · `supply_disruption` · `cyber_incident` · `climate` · `health_security` · `governance_risk` A normalized business signal to range-filter on, e.g. finance, energy, conflict. An unknown name is rejected.
signal_max number Inclusive upper bound for `signal`.
signal_min number Inclusive lower bound for `signal`.
signals {max, min, name}[] Several signal ranges at once, ANDed: `name[:min[:max]]`, comma separated, e.g. `finance:1.5:,energy::2`.
source string Source domain, e.g. bbc.co.uk.
source_type `web` · `citation` · `academic_archive` · `defense_archive` · `journal_archive` · `non_textual` · `other` The kind of source: web | citation | academic_archive | defense_archive | journal_archive | non_textual | other.
story_id string A cluster id from /stories, to expand one story into its articles.
to string Upper time bound, same formats as `from`.
topic string An exact canonical topic identifier returned by the API.

Returns {attribution, buckets, coverage, credits_charged, from, from_clamped, history_days, interval, metrics, partial, resolved, to} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

Equivalent to /graph/related over REST.

The entities most often mentioned alongside one entity (organizations, people, places, topics), strongest first, each with its co-mention count and share and, for the strongest, the newest articles mentioning both plus distinct sources, stories and first and last seen. Start from an id resolve_entity returned. Co-mention in reporting is association, not ownership, partnership or causation: read the evidence before stating a relationship, and present it as a reporting pattern. Costs the index queries it issues, reported as credits_charged (at most 16). Never conclude that something does not exist when `partial` is true, `coverage` is not `complete`, or `from_clamped` is true: retry, narrow the time range, or check `account_status` for the plan's archive depth.

Credits: 2 up to 4 + 2 per edge that gets evidence, at most 16; evidence=0 keeps it to 4 or less. Pass estimate=true to get the exact range without running the call, or max_credits to refuse anything costlier.

Argument Type Description
country string A mentioned country's canonical two-character identifier.
entity_id required string The entity to start from: one id from resolve_entity, e.g. organization:asml.
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
evidence integer How many of the strongest connections get evidence, and how many articles each carries (default 3; 0 for counts only). Evidence costs index queries, reported as credits_charged.
from string Lower time bound, e.g. 2026-07-09 or 20260709120000. Clamped forward to what the caller's plan may reach; see `history_days` and `from_clamped` in the response.
language string Source language, ISO-639-3, e.g. eng, fra, ara, zho.
limit integer Neighbours to return, 1-50 (default 20).
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.
publisher_country string The publisher's canonical two-character country identifier.
source_type `web` · `citation` · `academic_archive` · `defense_archive` · `journal_archive` · `non_textual` · `other` The kind of source: web | citation | academic_archive | defense_archive | journal_archive | non_textual | other.
to string Upper time bound, same formats as `from`.
types string Neighbour types to return, comma separated: organization, person, location, city, region, topic, name (default organization,person,location,topic).

Returns {attribution, coverage, credits_charged, entity_resolution_version, from_clamped, history_days, indexed_through, note, partial, related, seed} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

connection_path

Equivalent to /graph/path over REST.

How two entities connect in the reporting: the articles mentioning both, and up to five paths through one shared neighbour, each hop with its co-mentions and evidence. Bounded to two hops by design. Co-mention is association, not a real-world relationship. Costs the index queries it issues, reported as credits_charged (at most 16). Never conclude that something does not exist when `partial` is true, `coverage` is not `complete`, or `from_clamped` is true: retry, narrow the time range, or check `account_status` for the plan's archive depth.

Credits: 3-8 with max_hops=1, 3-9 with evidence=0, up to 16 otherwise. Pass estimate=true to get the exact range without running the call, or max_credits to refuse anything costlier.

Argument Type Description
country string A mentioned country's canonical two-character identifier.
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
evidence integer How many of the strongest connections get evidence, and how many articles each carries (default 3; 0 for counts only). Evidence costs index queries, reported as credits_charged.
from string Lower time bound, e.g. 2026-07-09 or 20260709120000. Clamped forward to what the caller's plan may reach; see `history_days` and `from_clamped` in the response.
from_entity required string Where the path starts: an id from resolve_entity.
language string Source language, ISO-639-3, e.g. eng, fra, ara, zho.
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.
max_hops integer 1 for the direct connection only; 2 (default) also looks through one shared neighbour. Paths are bounded to two hops by design.
publisher_country string The publisher's canonical two-character country identifier.
source_type `web` · `citation` · `academic_archive` · `defense_archive` · `journal_archive` · `non_textual` · `other` The kind of source: web | citation | academic_archive | defense_archive | journal_archive | non_textual | other.
to string Upper time bound, same formats as `from`.
to_entity required string Where the path ends: an id from resolve_entity.

Returns {attribution, coverage, credits_charged, direct, entity_resolution_version, from, from_clamped, history_days, indexed_through, note, partial, paths, to} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

entity_network

Equivalent to /graph/network over REST.

One entity's neighbours grouped by type for a window. With compare_from or compare_to, what changed against a second window: new and gone neighbours, and ties whose share grew by half or fell by a third. Costs the index queries it issues, reported as credits_charged. Never conclude that something does not exist when `partial` is true, `coverage` is not `complete`, or `from_clamped` is true: retry, narrow the time range, or check `account_status` for the plan's archive depth.

Credits: 2 up to 4 + 2 per edge that gets evidence, at most 16, plus 3 for a comparison window. Pass estimate=true to get the exact range without running the call, or max_credits to refuse anything costlier.

Argument Type Description
compare_from string Start of a second window to compare the network against, in the same formats as `from`. With compare_from or compare_to the response carries `changes`.
compare_to string End of the comparison window, in the same formats as `to`.
country string A mentioned country's canonical two-character identifier.
entity_id required string The entity to start from: one id from resolve_entity, e.g. organization:asml.
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
evidence integer How many of the strongest connections get evidence, and how many articles each carries (default 3; 0 for counts only). Evidence costs index queries, reported as credits_charged.
from string Lower time bound, e.g. 2026-07-09 or 20260709120000. Clamped forward to what the caller's plan may reach; see `history_days` and `from_clamped` in the response.
language string Source language, ISO-639-3, e.g. eng, fra, ara, zho.
limit integer Neighbours per type, 1-20 (default 10).
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.
publisher_country string The publisher's canonical two-character country identifier.
source_type `web` · `citation` · `academic_archive` · `defense_archive` · `journal_archive` · `non_textual` · `other` The kind of source: web | citation | academic_archive | defense_archive | journal_archive | non_textual | other.
to string Upper time bound, same formats as `from`.
types string Neighbour types to return, comma separated: organization, person, location, city, region, topic, name (default organization,person,location,topic).

Returns {attribution, changes, coverage, credits_charged, entity_resolution_version, from_clamped, groups, history_days, indexed_through, note, partial, seed} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

shared_exposures

Equivalent to /graph/exposures over REST.

What up to five entities have in common: the articles mentioning all of them, their distinct stories and sources, the facets you ask for (topics, countries, sources and so on), mean and percentile intensities of the signals you name, and the newest shared articles as evidence. Costs the index queries it issues, reported as credits_charged. Never conclude that something does not exist when `partial` is true, `coverage` is not `complete`, or `from_clamped` is true: retry, narrow the time range, or check `account_status` for the plan's archive depth.

Credits: 3, plus 1-2 per entity id, plus 1 with signal_stats. Pass estimate=true to get the exact range without running the call, or max_credits to refuse anything costlier.

Argument Type Description
country string A mentioned country's canonical two-character identifier.
entity_id required string Up to five entity ids from resolve_entity, comma separated (over REST the parameter may also repeat). Each matches any spelling in its alias group in the requested window; several ids must all match. The spellings used are reported in `resolved`.
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
evidence integer How many of the strongest connections get evidence, and how many articles each carries (default 3; 0 for counts only). Evidence costs index queries, reported as credits_charged.
facet_limit integer Values per facet, 1-100 (default 10).
facets `source` · `source_type` · `publisher_country` · `language` · `story_id` · `topic` · `organization` · `person` · `country` · `author` · `location` · `location_id` · `city` · `region` · `name` · `mentioned_date` · `quote_verb` · `amount_object` · `event_type`[] Comma-separated fields to count over the full match set, up to 8.
from string Lower time bound, e.g. 2026-07-09 or 20260709120000. Clamped forward to what the caller's plan may reach; see `history_days` and `from_clamped` in the response.
language string Source language, ISO-639-3, e.g. eng, fra, ara, zho.
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.
publisher_country string The publisher's canonical two-character country identifier.
signal_stats string Signal names to summarise over the shared articles, comma separated, e.g. finance,supply_disruption.
source_type `web` · `citation` · `academic_archive` · `defense_archive` · `journal_archive` · `non_textual` · `other` The kind of source: web | citation | academic_archive | defense_archive | journal_archive | non_textual | other.
to string Upper time bound, same formats as `from`.

Returns {approximate, articles, attribution, coverage, credits_charged, entities, entity_resolution_version, evidence, facets, from_clamped, history_days, indexed_through, note, partial, signals, sources, stories} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

create_watch

Equivalent to POST /watches over REST.

Save a /stories query the index runs for you every interval_minutes, instead of polling. It records an event when a story first reaches minimum_outlets (new_story) or keeps growing (story_growth: crossing 5, 15, 40 or 100 outlets, or 10 more since the last event). Read events with watch_events; with webhook_url each is also POSTed, signed with the webhook_secret returned only here. Each run is charged the credits its query takes, and each webhook delivery attempt 1 credit, to this key; pass estimate=true to see the per-run price before creating it. A run whose answer is partial is asked again rather than skipped. The plan caps how many watches and how short an interval.

Credits: 1 to create. Every run is then charged the credits its query takes, and every webhook delivery attempt costs 1, retries included. Pass estimate=true to get the exact range without running the call, or max_credits to refuse anything costlier.

Argument Type Description
amount_max number Articles mentioning a numeric amount of at most this value. With amount_min, one amount must satisfy both; with amount_object, that amount must describe the object.
amount_min number Articles mentioning a numeric amount of at least this value. With amount_max, one amount must satisfy both; with amount_object, that amount must describe the object.
amount_object string An exact object described by a numeric amount.
author string An exact article author.
bbox string A box, `south,west,north,east` in decimal degrees: articles mentioning a city inside it. West greater than east crosses the antimeridian. Not with near.
city string An exact mentioned city.
country string A mentioned country's canonical two-character identifier.
entity_id string Up to five entity ids from resolve_entity, comma separated (over REST the parameter may also repeat). Each matches any spelling in its alias group in the requested window; several ids must all match. The spellings used are reported in `resolved`.
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
event_type `bankruptcy` · `earnings_report` · `ipo` · `cyber_attack` · `outage` · `industrial_accident` · `sanctions` · `trade_dispute` · `boycott` · `nationalization` · `privatization` · `money_laundering` · `executive_change` · `factory_closure` · `supply_shortage` · `labor_strike` · `antitrust_action` An event class derived from the article's GKG themes (events-v1). Precise rather than complete: an article can describe an event without carrying its class.
interval_minutes required integer How often the query runs, in minutes. The plan sets the floor (free 60, build 15, scale 5, archive 1); each run is one request.
label string A label for the watch, for your own lists. Not a filter: `name` is the proper-name filter, as on list_stories.
language string Source language, ISO-639-3, e.g. eng, fra, ara, zho.
location string An exact mentioned location.
location_id string An exact canonical location identifier.
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.
mentioned_date string An exact date mentioned in the article text.
minimum_outlets integer Report a story once it has reached this many distinct outlets (default 2).
mode `keyword` · `semantic` · `hybrid` · `recent` Ranking mode. `hybrid` is usually right when a model wrote the query, because models paraphrase. `recent` orders newest-first and is implied when `q` is omitted.
name string An exact proper name.
near string A point, `latitude,longitude` in decimal degrees, e.g. 48.8566,2.3522. With radius_km: articles mentioning a city within that distance. On article results (/search, /top-headlines) each hit reports the cities that matched as matched_locations.
notify_on `new_story` · `story_growth`[] Which events to record: `new_story` (a story first reaches minimum_outlets) and `story_growth` (it crosses 5, 15, 40 or 100 outlets, or grows by 10 since the last event). Default both.
organization string An exact organization entity.
person string An exact person entity.
publisher_country string The publisher's canonical two-character country identifier.
q string Query text. Omit for a recency browse.
quote_verb string An exact verb introducing a quotation.
radius_km number With near: the distance in kilometres, 0.1-2000.
region string An exact mentioned region.
signal `economy` · `healthcare` · `agriculture` · `labor` · `environment` · `energy` · `transportation` · `real_estate` · `finance` · `defense` · `science_technology` · `trade` · `public_sector` · `financial_uncertainty` · `financial_negative` · `financial_positive` · `legal_litigation` · `financial_stability_stress` · `anxiety` · `conflict` · `supply_disruption` · `cyber_incident` · `climate` · `health_security` · `governance_risk` A normalized business signal to range-filter on, e.g. finance, energy, conflict. An unknown name is rejected.
signal_max number Inclusive upper bound for `signal`.
signal_min number Inclusive lower bound for `signal`.
signals {max, min, name}[] Several signal ranges at once, ANDed: `name[:min[:max]]`, comma separated, e.g. `finance:1.5:,energy::2`.
source string Source domain, e.g. bbc.co.uk.
source_type `web` · `citation` · `academic_archive` · `defense_archive` · `journal_archive` · `non_textual` · `other` The kind of source: web | citation | academic_archive | defense_archive | journal_archive | non_textual | other.
story_id string A cluster id from /stories, to expand one story into its articles.
topic string An exact canonical topic identifier returned by the API.
webhook_url string Optional https URL on a public host. Each event is POSTed as JSON, signed with the webhook_secret returned when the watch is created (header x-unzoi-signature: sha256=<HMAC-SHA256 of the body>), and retried after 1, 5 and 25 minutes.

Returns {consecutive_failures, consecutive_incomplete, created_at, credits_charged, id, interval_minutes, label, last_run_at, minimum_outlets, next_run_at, notify_on, query, status, watermark, webhook_secret, webhook_url} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

list_watches

Equivalent to /watches over REST.

List this account's watches with their status (active, paused_key, paused_credits, failing), last and next run, and the plan's cap.

Credits: 1. Pass estimate=true to get the exact range without running the call, or max_credits to refuse anything costlier.

Argument Type Description
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.

Returns {count, credits_charged, limit, watches} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

get_watch

Equivalent to /watches/{id} over REST.

Read one watch: the /stories query it runs, its interval and minimum_outlets, which events it records, its webhook_url, and its status (active, paused_key, paused_credits, failing) with the last and next run and the watermark. Check it to learn why a watch is quiet before creating another.

Credits: 1. Pass estimate=true to get the exact range without running the call, or max_credits to refuse anything costlier.

Argument Type Description
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
id required string The watch id, from create_watch or list_watches.
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.

Returns {consecutive_failures, consecutive_incomplete, created_at, credits_charged, id, interval_minutes, label, last_run_at, minimum_outlets, next_run_at, notify_on, query, status, watermark, webhook_url} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

delete_watch

Equivalent to DELETE /watches/{id} over REST.

Delete a watch with its state and its events. Nothing more is recorded or delivered for it, the deleted events cannot be read back, and the plan's watch count drops at once.

Credits: 1. Pass estimate=true to get the exact range without running the call, or max_credits to refuse anything costlier.

Argument Type Description
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
id required string The watch id, from create_watch or list_watches.
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.

Returns {credits_charged, deleted, id} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

watch_events

Equivalent to /watches/{id}/events over REST.

Read a watch's events, newest first: new_story and story_growth, each with the story's counts and, when a webhook is set, its delivery status. Page with after set to the previous response's next_after. Events are kept seven days.

Credits: 1. Pass estimate=true to get the exact range without running the call, or max_credits to refuse anything costlier.

Argument Type Description
after string Return events older than this event id: pass the previous page's `next_after`.
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
id required string The watch id, from create_watch or list_watches.
limit integer Events per page, 1-100 (default 20).
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.

Returns {credits_charged, events, next_after, watch_id} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

account_status

Equivalent to /account over REST.

Report this session's account: plan, credits a minute, the monthly credit allocation and how much of it is used, whether the key stops at its allocation or bills overage, how far back the plan may query (history_days; null = the full archive), calls and credits this session, and whether metered billing is active.

Check it before a large job: it is how to plan credits and a time range instead of discovering the limits by being refused or by getting fewer results than you expected.

Free: 0 credits.

Argument Type Description
estimate boolean Return this call's price instead of running it: the credit range, a breakdown, your remaining credits and whether the call would run. A preview costs 0 credits.
max_credits integer Refuse the call, at no cost, when its worst case would cost more than this many credits. The refusal carries the estimate.

Returns {attribution, calls_this_session, credits_limit, credits_per_minute, credits_remaining, credits_reset_secs, credits_this_session, credits_used, hard_cap, history_days, metered_billing, plan, tenant} or {mode, note} as structuredContent, typed by the tool's outputSchema. An argument not listed above is refused.

Calling one directly

Nothing about this is special — it is JSON-RPC over one POST:

curl -s -X POST https://api.unzoi.com/mcp \
  -H "x-api-key: $UNZOI_KEY" \
  -H "content-type: application/json" \
  -H "accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "list_stories",
      "arguments": { "q": "semiconductor export controls", "limit": 5 }
    }
  }'

The result carries the payload twice: as structuredContent, the typed JSON object whose shape is the tool's outputSchema — the OpenAPI response schema, inlined — and as one text content block holding the same JSON for clients that predate structuredContent. Either one is the body GET /stories returns. Read structuredContent if your client exposes it; otherwise parse the text block once. Never both. A host that validates results against outputSchema can: partial and coverage are required on every search-shaped tool. See Transport for the handshake, and Errors for what a refusal looks like.

Arguments are checked

An argument a tool does not declare is refused, as JSON-RPC -32602 with the name you probably meant. It is not dropped. Until September 2026 an unknown argument was silently ignored, which searched everything: a typo in a filter name widened the query instead of failing it.

{
  "jsonrpc": "2.0", "id": 2,
  "error": {
    "code": -32602,
    "message": "Unknown parameter 'langauge'. Did you mean 'language'?",
    "data": { "code": "unknown_parameter" }
  }
}

Three refusals share that shape, told apart by error.data.code:

  • unknown_parameter — an argument the tool does not declare.
  • unknown_signal — a name in signal or signals that is not one of the published signals. It used to match nothing, which looked like no coverage.
  • invalid_parameter — a value outside its enum or range: a view that is not one of full/compact, a facets field the index cannot count, signal_min without signal, a limit above 100.

All three are protocol errors, not tool errors: the call never ran, it cost nothing, and the session is fine. MCP errors has the mapping.

Asking for less

search_news, top_headlines and find_related take view: full (the default) returns the whole Article; compact keeps id, language, published_at, score, source, story_id, title, url — enough for a model to decide what to read next, at a fraction of the tokens. get_story lists its articles that way already; get_article always returns the full record.