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.
find_related
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.
related_entities
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 insignalorsignalsthat 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: aviewthat is not one offull/compact, afacetsfield the index cannot count,signal_minwithoutsignal, alimitabove 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.