Create Event Trend

Aggregate semantic event matches into a compact, dense time series on the server.

POST/api/v2.0/event-trends

Authorizations

Bearer
Authorizationstringheader

Required Bearer API key for programmatic World access.

Example: Bearer nos_sk_...

Body

application/json
querystringrequiredbody

The topic to measure, in any language, up to 8 KB. Events are compared with it by the cosine similarity of their text-embedding-3-large embeddings.

Example: openai lawsuits

fromdaterequiredbody

Inclusive UTC start date, on or after the archive's first day (2010-01-01). A date that is not a calendar date (such as 2026-02-30) is a 422.

Example: 2026-09-21

todaterequiredbody

Exclusive UTC end date, at most tomorrow (UTC). A trend has at most 12,000 buckets.

Example: 2026-10-11

intervalenumbody

Bucket size: day (the default), week (Monday to Sunday), month or quarter (calendar quarters).

Example: week

min_similaritynumberbody

Similarity floor from -1 to 1, inclusive; defaults to 0.35. Every event of the window at or above it is counted.

Example: 0.35

filtersobjectbody

Only events that match it are counted. The World Search filter syntax, set out in Filter syntax below, and type-checked in the same way: an unknown field, an operator the field's type does not take, a value of the wrong type or an empty and, or or not is a 422.

Example: {}

group_byenumbody

Split every bucket by one field: sentiment, materiality or time_horizon (the event's signals); country or region (the event's own place, its first location); language (its original language); iptc_topic (its most probable IPTC Media Topic, level 1); gics_sector (its most probable GICS sector); or nosible_category (its most probable NOSIBLE category). Events without a value are grouped as unknown.

Example: sentiment

How to use this endpoint

guidance

Use Event Trend for a semantic signal over time without downloading the matching events. Every event of the window whose similarity to the query is at least min_similarity is counted, so a bucket's count matches a search of its days at the same floor, buckets compare across days, weeks and quarters, and a group's count equals the count of the same trend filtered to that group's value. Days without data are listed in missing_dates (for example the archive gap of 2026-09-27 to 2026-10-07, or today before its first events): read a bucket with missing true as no data, not as zero events, and use days and missing_days to compare buckets that do not cover the same number of days. A partial bucket covers only part of its interval: the first can start before from, the last can run past to, and the bucket holding today is still being filled. truncated is true only for a topic that matches a large share of the window, where the search stopped at its ceiling of 250,000 events checked: that bucket's counts are then lower bounds. The trend's id is valid until expires_at, 15 minutes after the trend was last created; creating the same trend again returns the same id and serves it for another 15 minutes.

Filter syntax

filters

filters keeps only the events that match it: the search, its total and its facets all count those events and no others. It is a JSON object, and an event must satisfy every key of it. A key is a field name, one of and, or and not, or one of the geographic shapes bbox and geo_radius. Search Schema (GET /api/v2.0/search/schema) lists every field with its type (string, number, boolean, date or string_set), its aliases (countries for country, orgs for entity_org, tickers for ticker) and the operators each type takes; fetch it rather than copying a list from here.

A field's condition takes one of three forms. A bare value is equality: {"sentiment": "negative"}. An array means any of its values: {"sentiment": ["positive", "neutral"]}. An object applies operators, and every operator in it must hold: {"total_coverage": {"gte": 50, "lt": 500}}. A condition is never null (to find events without a value, send {"missing": true}), and an operator object is never empty.

Strings are compared exactly on a string field, so write a value as the event carries it: {"gics_sector": "Energy"} matches and "energy" does not (the Ontology directory and a search's facets list the values). contains and prefix ignore case. A string_set field (entity_gpe, entity_loc, entity_org, entity_person, entity_product, ticker, isin, figi, lei, wiki_qid and the *_top3 classification fields) holds several values per event, and every operator on it ignores case and extra spaces. entity_any, also entities, is every entity_* field at once. V1.2's city, required_ontology_below_floor, entity_event, entity_fac, entity_language, entity_law, entity_norp and entity_work_of_art are not fields of V2.0: filtering on one is a 422.

A date is a string in YYYY-MM-DD form, such as "2026-09-30": in a condition on the date field (the event's archive date) and in the request's own date window ({"from", "to", "include_live"}). The window chooses which archive days are searched; filters then apply to those days, so a request can carry both. A timestamp, a date without its leading zeros ("2026-9-1") and any other form is a 422 validation_error.

World Search and date-grouped search answer a filter they cannot read with a 422 validation_error whose message names the path of the problem: an unknown field (with the closest known name), an operator the field's type does not take, a value of the wrong type, a null, an empty and, or or not, a between or bbox written backwards. Event Trend reads and checks the same syntax.

A complete filter

and, or, not and a range togetherobject

Negative events of the United States or the United Kingdom, without a listed company, reported by at least 50 documents. Keys beside each other are an and, and and, or and not nest to any depth.

Example: {"and": [{"sentiment": "negative"}, {"or": [{"country_iso": "US"}, {"country_iso": "GB"}]}, {"not": {"has_tickers": true}}, {"total_coverage": {"gte": 50}}]}

Operators

eqall types

Equal to the value. On a string_set field, the event has the value.

Example: {"country_iso": {"eq": "US"}}

neqstring, number, boolean, date

Not equal to the value. Events with no value match.

Example: {"gics_sector": {"neq": "Energy"}}

inall types

Equal to any of the values. On a string_set field, the event has at least one of them.

Example: {"language": {"in": ["en", "fr"]}}

not_inall types

Equal to none of the values. Events with no value match.

Example: {"entity_org": {"not_in": ["nvidia"]}}

allstring_set

The event has every one of the values.

Example: {"entity_org": {"all": ["nvidia", "openai"]}}

existsstring, number, boolean

true: the event has a value. false: it has none.

Example: {"gics_sector": {"exists": true}}

missingstring, number, boolean

true: the event has no value. false: it has one.

Example: {"gics_sector": {"missing": true}}

gt, gte, lt, ltenumber, date

Greater than, at least, less than, at most. The value is a number, or a date for a date field.

Example: {"total_coverage": {"gte": 50}}

betweennumber, date

[low, high], both ends included. The low end may not be above the high end.

Example: {"date": {"between": ["2026-09-01", "2026-09-30"]}}

containsstring, string_set

A value contains the text, ignoring case. The argument is a string or an array of strings, any of which may match. The entity fields hold millions of distinct names, and a field with more than 1,000,000 of them (entity_org, entity_person and others) refuses contains and prefix: use eq or in with a name that Find entities returns.

Example: {"title": {"contains": "oil"}}

prefixstring, string_set

A value starts with the text, ignoring case. Refused on the same entity fields as contains.

Example: {"title": {"prefix": "oil"}}

Combining conditions

andfilter[]

An array of filter objects, all of which must match.

Example: {"and": [{"sentiment": "negative"}, {"has_tickers": true}]}

orfilter[]

An array of filter objects, at least one of which must match.

Example: {"or": [{"country_iso": "US"}, {"country_iso": "GB"}]}

notfilter

One filter object, which must not match. Events that lack the field match too.

Example: {"not": {"has_tickers": true}}

Geography

bboxnumber[4]

[west_lng, south_lat, east_lng, north_lat]: events whose own place (the lat and lng fields) is inside the box, its edges included. Longitudes run from -180 to 180 and latitudes from -90 to 90; west may not be east of east, or south above north, so a box across the 180th meridian is two boxes joined with or. Events with no place never match a bbox, so not {bbox} includes them. geo_bbox is accepted as the same key.

Example: {"bbox": [-10, 35, 30, 60]}

geo_radiusobject

{lat, lng, km}: events whose own place is within km kilometres of the point, measured along the earth's surface. lat is from -90 to 90, lng from -180 to 180 and km above 0. radius is accepted as the same key and lon as lng. Events with no place never match.

Example: {"geo_radius": {"lat": 51.5, "lng": -0.1, "km": 50}}

Response body

application/json

These are the fields you can build against. Nested names use dot notation; optional sections are called out in their descriptions.

idstring

Handle for Get Events in Trend, valid until expires_at.

expires_atdate-time

When the handle expires (UTC): 15 minutes after the trend was last created. Creating the same trend again returns the same id and moves this 15 minutes on. A trend that includes a day still being filled gets a new id once that day's data changes.

approximateboolean

Always true: the search stops once the least similar candidates it checks no longer reach min_similarity, so an event ranked below all of them would be missed. Checked against an exact search of single days, the counts matched event for event.

missing_datesdate[]

Dates of the window without data, in order. Their buckets count nothing because there is nothing to count.

bucketsobject[]

The time series, one bucket per interval in date order, empty buckets included.

buckets[].startdate

First day of the bucket's interval (a Monday for week buckets); the first bucket can start before from.

buckets[].event_countinteger

Events of the bucket at or above min_similarity.

buckets[].coverage_suminteger

Sum of the events' coverage.total_netlocs: the distinct source sites that reported them, as in V1.2.

buckets[].similarity_sumnumber

Sum of the events' similarity to the query; divide by event_count for their mean similarity.

buckets[].truncatedboolean

True only when the search stopped at its ceiling (250,000 events checked) before reaching min_similarity for this bucket: its counts are then lower bounds.

buckets[].partialboolean

True when the bucket covers only part of its interval: it starts before from, runs past to, or holds today (UTC), which is still being filled.

buckets[].daysinteger

Days of the bucket inside the window [from, to).

buckets[].missing_daysinteger

Of those days, the ones without data (listed in missing_dates).

buckets[].missingboolean

True when none of the bucket's days has data: its zeros mean no data, not no events.

buckets[].groupsobject

With group_by only: event_count, coverage_sum and similarity_sum per group value.

Responses and errors

HTTP
200Request succeeded. The response body is shown in the panel on the right.
400invalid_json — The request body is not JSON. Every error body, 401 included, is {error, message, status}.
401api_key_required — No API key was sent. Send it as Authorization: Bearer <key> or the api-key header.
401invalid_api_key — The API key is invalid or has been revoked.
403access_denied — The requested archive date is outside the caller's World tier.
422validation_error — The request is well formed but the API cannot decode or validate it: an unknown body field or query parameter, a missing required parameter, a value of the wrong type, an empty and, or or not, a date that is not a calendar date (in the path, the query or the body), an unknown enum value or a reversed range. The message names the parameter and what is wrong.
404not_found — The requested date, entity, ticker, or event does not exist in the accessible index.
410cursor_expired — The cursor was minted against a replaced index build. Restart pagination from the first page.
429rate_limited — The request exceeded the endpoint or account rate limit. Respect Retry-After when supplied.
501backend_not_configured — The World backend is not configured for this deployment.
503api_key_auth_unavailable — API key authentication is temporarily unavailable; retry shortly.
503api_key_metering_unavailable — API key usage metering is temporarily unavailable, so the request was not served; wait for the Retry-After header (30 seconds) and retry.
502backend_error — The World backend could not be reached or did not return a valid response; retry shortly.
504backend_timeout — The World backend did not answer within 300 seconds; narrow the request (for example with a date window) or retry.