Trends API / Docs

Trends API documentation

Everything you need to call the TrendIntel API: how to authenticate, the limits, how to filter and page, the errors, and every resource and field it returns. Base URL: https://trendintel.io/api/v1

Quick start

  1. API access is part of the Pro plan.
  2. Create a key in the API keys section of your account page. It is shown once, so copy it then.
  3. Call the API with the key in the Authorization header:
curl -H "Authorization: Bearer $TRENDINTEL_KEY" \
  "https://trendintel.io/api/v1/topics?filter[trajectory]=rising&sort=-momentum_score&per_page=5"

That returns the five rising trends with the most momentum. Add &include=opportunity to get each one's AI brief in the same response.

Authentication

Every request except the discovery document needs a key, sent as a bearer token:

Authorization: Bearer tiapi_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • Keys in the URL (?api_key=) are refused: URLs end up in logs and browser history.
  • You can hold up to 20 active keys, each with its own label and an optional expiry. Revoke a key on your account page and it stops working at once.
  • Keep keys on your server. Never put one in a web page, a mobile app or a public repository.
  • If your account leaves Pro, its keys are kept but refused with 403 plan_required, and they work again when you return to Pro.

Rate limits

Each account can make 60 requests a minute, shared by all of its keys. Every response carries X-RateLimit-Limit and X-RateLimit-Remaining. Past the limit you get 429 rate_limited with a Retry-After header giving the seconds to wait.

To read a lot of data, ask for more rows per request (up to each resource's maximum, usually 200) rather than making more requests, and use ?fields= to leave out columns you don't need.

Filters, sorting and fields

Each resource has three endpoints:

GET /{resource}A page of rows.
GET /{resource}/{id}One row.
GET /{resource}/{id}/{relation}The related row, or a page of related rows (a trend's history, a filing's holdings).

Query parameters, which can be combined:

filter[col]=valueRows where the column equals the value. Comma-separate values for any of them: filter[trajectory]=rising,returning. Only the filterable columns listed for each resource.
min_col=N, max_col=NA range on a sortable column, numbers or dates: min_velocity=1, max_filed_at=2026-09-30.
q=textCase-insensitive keyword search across the resource's searchable columns.
sort=col, sort=-colAscending, or descending with a minus. Only the sortable columns. Each resource has a default order.
fields=a,b,cReturn only these columns (id is always included).
include=relationEmbed a related record in each row. Only relations marked includable (those that return one record); lists come from the relation endpoint.
per_page=N, page=NRows per page (default 50, maximum per resource) and which page.

A filter or sort on a column that isn't listed for the resource is ignored, so check the reference below when results look unfiltered.

Paging

Lists come back as a page:

{
  "data": [ ... ],
  "current_page": 1,
  "per_page": 50,
  "total": 942,
  "last_page": 19,
  "next_page_url": "https://trendintel.io/api/v1/topics?page=2",
  ...
}
  • Page numbers stop at 10,000 rows deep. Past that, narrow the list with filters or ranges.
  • The largest resources (marked large below) answer without total and last_page; follow next_page_url until it is null.
  • On those, ?after_id=N reads every row past the page limit: it returns rows with an id below N, newest first, and a next_after_id for the next call. Start with a very large N.

Errors

Every error has the same JSON shape, with a code you can test for and a message saying what to do:

{"error": "rate_limited", "message": "Rate limit reached: ..."}
StatuserrorMeaning
401 unauthorized No key, or a key that is invalid, revoked or expired.
403 plan_required The key's account is no longer on Pro. The key works again after an upgrade.
404 not_found No such resource, relation or id.
422 invalid_request A page deeper than the limit, or an include that isn't available. The message says what to use instead.
429 rate_limited Over 60 requests a minute. Wait for Retry-After seconds.
503 query_timeout The query took too long. Narrow it with filters or ranges, or ask for fewer rows.

Code examples

Read every page of rising trends with their briefs, waiting when the rate limit says so.

Python

import os, time, requests

BASE = "https://trendintel.io/api/v1"
session = requests.Session()
session.headers["Authorization"] = "Bearer " + os.environ["TRENDINTEL_KEY"]

def get(path, **params):
    while True:
        r = session.get(BASE + path, params=params, timeout=30)
        if r.status_code == 429:
            time.sleep(int(r.headers.get("Retry-After", "5")))
            continue
        r.raise_for_status()
        return r.json()

page = 1
while True:
    body = get("/topics", **{"filter[trajectory]": "rising", "include": "opportunity",
                             "sort": "-momentum_score", "per_page": 100, "page": page})
    for topic in body["data"]:
        brief = topic.get("opportunity") or {}
        print(topic["label"], topic["velocity"], brief.get("ai_summary"))
    if page >= body["last_page"]:
        break
    page += 1

JavaScript (Node 18+, saved as an .mjs file)

const BASE = "https://trendintel.io/api/v1";
const headers = { Authorization: "Bearer " + process.env.TRENDINTEL_KEY };

async function get(path, params = {}) {
  const url = BASE + path + "?" + new URLSearchParams(params);
  for (;;) {
    const res = await fetch(url, { headers });
    if (res.status === 429) {
      const wait = Number(res.headers.get("Retry-After") || 5);
      await new Promise((r) => setTimeout(r, wait * 1000));
      continue;
    }
    if (!res.ok) throw new Error((await res.json()).message);
    return res.json();
  }
}

const body = await get("/entity-trends", { sort: "-velocity", per_page: 20 });
for (const e of body.data) console.log(e.normalized_entity, e.entity_label, e.velocity);

More requests

/topics?q=batteryFind a trend by name.
/topics/{id}/trajectories?sort=started_atEvery label a trend has had, oldest first.
/topics/{id}/history?sort=dateA trend's daily readings.
/narratives?filter[is_active]=1&sort=-strengthThe largest active narratives.
/micro-clusters?filter[status]=active&sort=-density_velocityMicro-trends forming fastest.
/entity-history?filter[normalized_entity]=nvidia&sort=-week_startAn entity's weekly mentions.
/convergence-scores?sort=-convergence_score&per_page=20The trends with the most cross-source backing.
/insider-transactions?filter[transaction_code]=P&sort=-transaction_dateThe latest open-market insider purchases.
/institutional-documents/{id}/holdings?sort=-value_usdThe largest positions in one 13F filing.

Discovery document

https://trendintel.io/api/v1/discovery describes everything on this page in machine-readable form: every resource, column and meaning, filter, sort and relation. It needs no key. Point code generators and AI agents at it.

What is not included

The API serves TrendIntel's own analysis and public government filings. It does not serve the original posts, articles and other items behind a trend (each trend says which sources it comes from and in what share), the text of filings, or stock market prices and the Stock Sectors data built from them. See the API section of the Terms of Service for how the data may be used.

Trends

topics

One row per topic: a subject our clustering found across the signals we collect (the posts, articles, filings and other items). It holds the AI name, the current label and this week's numbers, refreshed hourly. Topics are never deleted; retired topics keep their row.

GET https://trendintel.io/api/v1/topics · GET https://trendintel.io/api/v1/topics/{id}

id integer Unique topic ID; appears as topic_cluster_id in the other resources.
label string Short AI-written name (2-4 words), written once when the topic is first tracked and not changed afterwards. Reads "Topic N" until then.
velocity number This week's signals against the usual week, both counted on sources we have read for at least seven weeks and adjusted for how much we collected (0.5 = 50% above), plus up to +1.0 from matching search, trending and job data.
acceleration number Change in velocity (before the search-data boost) since the same day last week, relative to last week's value. Clamped to -10 to 10.
momentum_score number Ranking score, 0 to 100: velocity 40%, acceleration 25%, number of spread groups 20%, number of sources 15%. 0 for topics holding no signals.
problem_density number Percentage (0 to 100) of the topic's signals from the last 60 days classified as a complaint, question, workaround or request.
signal_count integer Signals currently filed in the topic (signals are kept for 90 days). A topic with 10 or more that is not noise is tracked.
first_seen timestamp (UTC) When clustering first drew this topic.
last_updated timestamp (UTC) Last time new signals were filed into the topic or its weekly numbers were recomputed.
label_refined_at timestamp (UTC) When the AI label and description were written. Null means the label is still a placeholder.
sustained_volume number The usual week: average weekly signals over the earlier weeks the topic has existed (up to six), from sources collected throughout. Velocity compares it, adjusted for how much we collected, with this week's signals from those same sources, not with week_count.
is_noise boolean True when our AI judged the topic's signals to share no common subject. Noise topics get no brief and are not shown.
velocity_boost_breakdown JSON JSON string: what boosted velocity this hour, as counts of matching items from the last 7 days under search_trends, social_trends, developer_interest, job_postings. Null if none.
trajectory string Current label: new, rising, steady, cooling, returning or quiet, judged against the topic's own usual week. Full history in topic-trajectories.
trajectory_since timestamp (UTC) When the topic took its current label.
week_count integer Signals in the last 7 days, each counted once, from every source, including sources added in the last seven weeks that velocity leaves out; so week_count against sustained_volume is not velocity. Social posts are dated by when they were posted, everything else by when we collected it.
source_count integer Number of distinct sources among the topic's signals in the last seven weeks.
community_count integer How many of the seven spread groups (research, developers, business, hiring, social, news, government) appear in its signals over the last seven weeks.
spread JSON JSON object: share (0 to 1) of the last four weeks' signals per group (research, developers, business, hiring, social, news, government), largest first; 0.03+ means present.
origin_group string The spread group with the largest share when the topic was first measured. Set once, never changed.
parent_topic_id integer For an offshoot: the older, closely related topic it grew out of, recorded when this topic was drawn. Null for most topics.
parent_similarity number Similarity (0 to 1) to the parent topic when drawn. Currently 0.85 to 0.90; topics drawn before 26 Oct 2026 used a looser test starting at 0.70.
category string Subject chosen by our AI when writing the brief: technology, science, health, business, politics, world, culture, sports, lifestyle or society. Null until briefed.
retired_at timestamp (UTC) When the topic was retired because its name no longer described its signals. It then holds none; history before this date may not match the label.
retired_reason string A few words from our AI naming what the retired topic's signals were actually about.
Filter by
trajectory, category, origin_group, parent_topic_id, is_noise
Sort and range by
id, momentum_score, velocity, acceleration, problem_density, signal_count, week_count, source_count, sustained_volume, first_seen, last_updated, trajectory_since (default -momentum_score)
Search (?q=)
label
Rows per page
Up to 200
/topics/{id}/opportunity or ?include=opportunity one opportunities The AI brief for this topic (one per topic): what it is, why now, who is driving it, what to watch.
/topics/{id}/trajectories a page of topic-trajectories Every label period this topic has had (new, rising, steady, cooling, returning, quiet), each with its start and end time. Use it to look for patterns that repeat, such as a topic that rises at the same time every year.
/topics/{id}/parent or ?include=parent one topics The older topic this one is an offshoot of: clustering drew it as a new subject closely related to that one (0.85 to 0.90 similar; 0.90 or more is the same subject). Null for most topics.
/topics/{id}/convergence or ?include=convergence one convergence-scores The multi-layer convergence score for this topic (social + institutional + entity + micro-cluster + narrative), if computed.
/topics/{id}/history a page of trend-history Daily time-series rows for this topic (velocity, momentum, signal_count, etc.).
/topics/{id}/geo a page of geo-distribution Per-country / per-language signal counts for this topic.
/topics/{id}/narratives a page of narratives Macro narratives this topic is a component of.

opportunities

One row per topic that has held signals: its AI brief (what it is, why now, who is driving it, what to watch) and a copy of its velocity. Brief fields are empty until the topic is tracked, and cleared if it drops below 10 signals or is retired.

GET https://trendintel.io/api/v1/opportunities · GET https://trendintel.io/api/v1/opportunities/{id}

id integer Unique row ID.
topic_cluster_id integer The topic this brief describes; one row per topic.
ai_summary string What it is: 2-3 AI-written sentences on what people are talking about. On brief_version 1 rows, a summary in an older format.
summary_generated_at timestamp (UTC) When the current brief was written. Null when there is no brief. Briefs are rewritten when a topic turns rising or returning.
velocity number Copy of the topic's velocity (search-data boost included), refreshed hourly. 0 for retired topics.
ai_why_now string Why now: 1-2 AI-written sentences on what explains the current level of attention.
ai_drivers string Who is driving it: 1-2 AI-written sentences on the people, communities, organisations or outlets behind the signals.
ai_watch JSON JSON array of 2-4 short strings: concrete things to watch that would show the trend growing, fading or changing.
brief_version integer Brief format: 2 is the current four-part brief; 1 is an older format with only ai_summary filled.
Filter by
topic_cluster_id, brief_version
Sort and range by
id, velocity, summary_generated_at (default -velocity)
Rows per page
Up to 200
/opportunities/{id}/topic or ?include=topic one topics The topic this brief is about: its name, label, spread and scores. Its history, label periods and languages hang off /topics/{id}.

trend-history

One row per topic per UTC day on which it had a signal in the past seven weeks, holding that day's last hourly reading. A missing day means zero. Rows are kept indefinitely; calc_version says how each was measured.

GET https://trendintel.io/api/v1/trend-history · GET https://trendintel.io/api/v1/trend-history/{id}

id integer Unique row ID.
topic_cluster_id integer The topic this reading belongs to.
date date The UTC day the row describes.
signal_count integer Signals in the 7 days up to the reading. On calc_version 1 rows, weighted by community (research and developer signals counted extra).
velocity number That day's velocity: signals against the usual week (0.5 = 50% above), before the search-data boost. On version 2 rows, measured_count / expected_count - 1.
momentum_score number The topic's momentum (0 to 100) from the same hourly run. Rows before Oct 2026 used an earlier formula.
updated_at timestamp (UTC) Time of the day's last hourly reading, the one this row holds.
sustained_volume number The usual week the day was compared with: average weekly signals over up to six earlier weeks. Weighted on version 1 rows.
daily_count integer Signals dated that UTC day: social posts by when they were posted, everything else by when we collected it.
trajectory string The topic's label after that reading (new, rising, steady, cooling, returning, quiet). Filled in afterwards on version 1 rows by replaying the rules.
calc_version integer How the row was measured. 1 (before Oct 2026): weighted counts dated by collection. 2: each signal once, posting-time dating, adjusted for collection volume.
measured_count integer Signals in the week from sources collected throughout the comparison window; the numerator of velocity. Null on version 1 rows.
expected_count number The usual week scaled by how much we collected from each source this week; the denominator of velocity. Null on version 1 rows.
Filter by
topic_cluster_id, trajectory, calc_version
Sort and range by
id, date, signal_count, daily_count, velocity, sustained_volume, momentum_score (default -date)
Rows per page
Up to 200
/trend-history/{id}/topic or ?include=topic one topics The topic this snapshot belongs to. Hop here for the topic's full metadata.

topic-trajectories

One row per label period of a topic: the label it took, the one before, when it started and ended, and the reading that triggered the change. Rows are only added; the current period has ended_at null.

GET https://trendintel.io/api/v1/topic-trajectories · GET https://trendintel.io/api/v1/topic-trajectories/{id}

id integer Unique period ID.
topic_cluster_id integer The topic this label period belongs to.
trajectory string Label for the period: new (first 14 days), rising (from +75%), steady, cooling (from -50%), returning (active after 28+ quiet days) or quiet (under 3 signals a week).
previous_trajectory string The label before this period. Null for a topic's first period.
started_at timestamp (UTC) When the label took effect. Rising, cooling, steady and quiet must be seen for 24 hours first, and a label lasts at least 72 hours.
ended_at timestamp (UTC) When the next label took over. Null for the current period.
velocity number Velocity of the reading that started the period (signals against the usual week, 0.5 = 50% above), before the search-data boost.
measured_count integer Signals in the week of that reading, from sources collected throughout the comparison window.
expected_count number The usual week at that reading, scaled by how much we collected that week.
rule_version integer Version of the labelling thresholds that decided the period; raised whenever they change. 1 on every row so far.
replayed boolean True when rebuilt from daily history for the months before labels were recorded live (to mid-Oct 2026), using the older velocity measure.
after_recluster boolean True when the change was first seen right after a daily re-clustering, which moves signals between topics, so it may reflect regrouping.
after_source_change boolean True when the change came within two weeks of one of our sources being switched off, on a trend that source fed: it may reflect what we stopped collecting rather than the world.
Filter by
topic_cluster_id, trajectory, previous_trajectory, replayed, after_recluster, after_source_change, rule_version
Sort and range by
id, started_at, ended_at, velocity (default -started_at)
Rows per page
Up to 200
/topic-trajectories/{id}/topic or ?include=topic one topics The topic this label period belongs to.

geo-distribution

One row per topic per language seen in at least 3 of its signals from the last 90 days. The whole table is rebuilt every hour, so it is a current snapshot, not a history.

GET https://trendintel.io/api/v1/geo-distribution · GET https://trendintel.io/api/v1/geo-distribution/{id}

id integer Row ID. Rows are deleted and rebuilt hourly, so IDs change; identify a row by topic_cluster_id and geo_key.
topic_cluster_id integer The topic counted.
geo_key string Two-letter language code (ISO 639-1, e.g. en, fr, ja) detected from signal text. A country row would hold an uppercase ISO country code.
geo_type string language or country. Currently always language: country data comes only from search and trending sources, which are not filed into topics.
signal_count integer Number of the topic's signals from the last 90 days in this language (at least 3).
first_seen_at timestamp (UTC) When we collected the earliest of those signals.
last_seen_at timestamp (UTC) When we collected the most recent of those signals.
recorded_at timestamp (UTC) When this hourly snapshot was computed; the same on every row.
Filter by
topic_cluster_id, geo_type, geo_key
Sort and range by
id, signal_count, first_seen_at, last_seen_at (default -signal_count)
Rows per page
Up to 200
/geo-distribution/{id}/topic or ?include=topic one topics The topic this geo row belongs to. Hop here for the topic's full metadata.

narratives

One row per narrative: a group of two or more related topics, found by linking topics with similar subjects and picking out tightly connected groups. Named and summarised by AI; recomputed weekly on Sundays.

GET https://trendintel.io/api/v1/narratives · GET https://trendintel.io/api/v1/narratives/{id}

id integer Unique narrative ID.
label string AI-written name (2-4 words). If the AI call failed, the first two topic names joined with " + ".
description string One AI-written sentence on the common thread.
strength number Rank of the narrative's weekly signal volume among active narratives, 0 (smallest) to 100 (largest). Set weekly; archived narratives keep their last value.
component_topic_ids JSON JSON array of the IDs of the topics in the narrative as of its last weekly run.
ai_summary string 2-3 AI-written sentences on the broader narrative and its implications. Can be null.
created_at timestamp (UTC) When the narrative was first detected.
updated_at timestamp (UTC) Last time the row changed (weekly detection or archiving).
labeled_at timestamp (UTC) When our AI last named it. It is renamed when 30% or more of its topics change.
momentum_score number Average momentum (0 to 100) of its topics at the last weekly run.
is_active boolean False once archived: fewer than two of its topics are still tracked and not quiet. Checked weekly and after each daily re-clustering.
parent_narrative_id integer A larger narrative holding at least 85% of this one's topics, making this a sub-narrative. Null otherwise; recomputed weekly.
velocity number Average velocity of its topics at the last weekly run (0.5 = 50% above their usual week).
Filter by
is_active, parent_narrative_id
Sort and range by
id, strength, momentum_score, velocity, labeled_at (default -strength)
Rows per page
Up to 200
/narratives/{id}/topics a page of topics Component topics of this narrative.
/narratives/{id}/parent or ?include=parent one narratives Parent narrative (if this is a sub-narrative).
/narratives/{id}/children a page of narratives Child sub-narratives.

convergence-scores

One row per tracked topic: how strongly separate layers (social discussion, SEC filings, rising companies and products, emerging micro-trends, narratives) point at it at once. Recomputed daily at 07:00 UTC; a topic that stops qualifying keeps its last row.

GET https://trendintel.io/api/v1/convergence-scores · GET https://trendintel.io/api/v1/convergence-scores/{id}

id integer Unique row ID.
topic_cluster_id integer The topic scored; one row per topic.
social_score number The topic's momentum score (0 to 100) when computed.
institutional_score number SEC filings from the last 30 days naming a company or product also named in the topic's signals, scaled so the topic with the most = 100.
entity_score number Companies and products named in the topic's signals that are mentioned more this week than in the three weeks before; 10 or more = 100.
micro_cluster_score number 100 if any of the topic's signals also belong to an emerging micro-trend whose latest reading was growing, otherwise 0.
narrative_score number 0 if the topic is in no active narrative; otherwise 50 to 100, higher for larger narratives.
convergence_score number Overall score, 0 to 100: social 35%, institutional 25%, entity 20%, micro-trend 10%, narrative 10%.
computed_at timestamp (UTC) When the row was last computed (daily, 07:00 UTC). An older date means the topic no longer qualifies.
created_at timestamp (UTC) When the topic was first scored.
institutional_sentiment number Average tone, -1 (negative) to +1 (positive), of the filing sentences mentioning those companies and products. Null when no filings match.
Filter by
topic_cluster_id
Sort and range by
id, convergence_score, social_score, institutional_score, entity_score, micro_cluster_score, narrative_score, institutional_sentiment, computed_at (default -convergence_score)
Rows per page
Up to 200
/convergence-scores/{id}/topic or ?include=topic one topics The topic this score belongs to: its name, label, spread and scores.

Entities and emerging trends

entity-history large: no total, after_id paging

One entity's mention counts for one calendar week (Monday to Sunday, UTC); the week in progress is updated hourly. A quiet entity gets zero rows for about 13 weeks after its last mention; after that a missing week means zero.

GET https://trendintel.io/api/v1/entity-history · GET https://trendintel.io/api/v1/entity-history/{id}

id integer Unique ID of the history row.
normalized_entity string The entity's name, lowercased and trimmed, with a leading 'the', 'a' or 'an' removed. Matches entity-trends.
entity_label string Entity type: PRODUCT, ORG, PERSON, GPE (country, city or state), EVENT or WORK_OF_ART.
week_start date Monday (UTC) of the week this row covers.
week_current integer Distinct signals mentioning the entity during the week; for the week in progress, the count so far.
velocity number week_current divided by week_prior_avg, minus 1; 0 when there is no baseline; capped at 9999.9999. The week in progress compares a partial week.
source_diversity integer Distinct data sources among its mentions in this week and the 3 before. Zero-mention weeks carry the entity's 90-day figure instead.
cluster_diversity integer Distinct topics (trends) among signals mentioning it in this week and the 3 before. Zero-mention weeks carry the 90-day figure instead.
recorded_at timestamp (UTC) When the row was last written; for the week in progress, roughly how current the counts are.
week_prior_avg number Weekly average of distinct signals mentioning the entity over the 3 calendar weeks before this one.
Filter by
normalized_entity, entity_label
Sort and range by
id, week_start, velocity, week_current (default -week_start)
Rows per page
Up to 200

entity-pairs

Two entities mentioned in the same signals, with rolling co-mention counts, stored once per pair in alphabetical order. A pair is tracked once it has 2+ co-mentions in 7 days; both entities need 3+ mentions in 28 days. Updated hourly.

GET https://trendintel.io/api/v1/entity-pairs · GET https://trendintel.io/api/v1/entity-pairs/{id}

id integer Unique ID of the pair row.
entity_a_normalized string Normalized name of the first entity (the one that sorts first alphabetically).
entity_a_label string Entity type of the first entity: PRODUCT, ORG, PERSON, GPE or EVENT (creative works are not paired).
entity_b_normalized string Normalized name of the second entity.
entity_b_label string Entity type of the second entity: PRODUCT, ORG, PERSON, GPE or EVENT.
week_current integer Distinct signals mentioning both entities in the last 7 days. Reset to 0 once the pair drops below 2.
week_prior_avg number Weekly average of signals mentioning both over the 3 weeks before (8 to 28 days ago). 0 while the pair is below 2 this week.
velocity number week_current divided by week_prior_avg, minus 1 (0 = steady, 1 = doubled). 0 when there is no baseline or the pair has gone quiet.
source_diversity integer Distinct data sources among signals mentioning both in the last 90 days, as of the last hour the pair had 2+ co-mentions.
cluster_diversity integer Distinct topics (trends) among signals mentioning both in the last 90 days, as of the last hour the pair had 2+ co-mentions.
first_co_seen_at timestamp (UTC) Earliest co-mention of the two we have recorded.
last_co_seen_at timestamp (UTC) Most recent co-mention, as of the last hour the pair had 2+ co-mentions in 7 days.
Filter by
entity_a_normalized, entity_b_normalized
Sort and range by
id, velocity, week_current, source_diversity, cluster_diversity (default -velocity)
Rows per page
Up to 200

entity-communities

A group of entities being mentioned together more and more, found daily by community detection over the entity-pairs graph. An oversized group is split, and the broader group is kept as the parent of the smaller ones.

GET https://trendintel.io/api/v1/entity-communities · GET https://trendintel.io/api/v1/entity-communities/{id}

id integer Unique ID of the community.
label string Name of the community: an AI-written theme name when label_is_llm is true, otherwise its three most-mentioned members joined with ' · '.
label_is_llm boolean True when label, description and ai_summary were written by our AI. False for the member-name fallback (parents and lower-ranked communities).
description string AI-written sentence on what connects the members and why their co-mentions matter. Null until the community is AI-labelled.
ai_summary string AI-written 2-3 sentences on what is happening that has these entities discussed together. Null until the community is AI-labelled.
member_count integer Number of member entities at the last detection (usually 3 to 18; a parent can be larger).
aggregate_velocity number Average velocity of the entity pairs among its members (this week vs the weekly average of the 3 before, minus 1).
emergence_score number Ranking score: aggregate_velocity x ln(member_count) x ln(signal_volume_7d), each log taken of at least 2. Higher means more emergent.
signal_volume_7d integer Distinct signals in the last 7 days mentioning any member, as of the last detection.
is_active boolean False once the community has not been detected for 14 days.
first_seen_at timestamp (UTC) When the community was first detected.
labeled_at timestamp (UTC) When our AI last wrote its label. Null if it has only the fallback label.
last_detected_at timestamp (UTC) Most recent daily run that found the community.
parent_community_id integer ID of the broader community this one was split out of. Null for a top-level community.
Filter by
is_active, parent_community_id
Sort and range by
id, emergence_score, aggregate_velocity, signal_volume_7d, member_count, last_detected_at (default -emergence_score)
Rows per page
Up to 200
/entity-communities/{id}/members a page of entity-community-members Member entities of this community.
/entity-communities/{id}/parent or ?include=parent one entity-communities Parent community (if this is a sub-community).
/entity-communities/{id}/children a page of entity-communities Child sub-communities.

entity-community-members

One entity's membership in one community, as of the community's latest detection. A community's members are deleted and rewritten each time it is detected.

GET https://trendintel.io/api/v1/entity-community-members · GET https://trendintel.io/api/v1/entity-community-members/{id}

id integer ID of the membership row. Changes each time the community's members are rewritten, so do not store it.
community_id integer ID of the entity community this member belongs to.
normalized_entity string The member entity's normalized name (lowercased, leading article removed). Matches entity-trends.
entity_label string The member entity's type: PRODUCT, ORG, PERSON, GPE or EVENT.
mention_count_7d integer Distinct signals mentioning the entity in the last 7 days, as of the community's last detection.
Filter by
community_id
Sort and range by
id, mention_count_7d (default -mention_count_7d)
Rows per page
Up to 200
/entity-community-members/{id}/community or ?include=community one entity-communities The community this member belongs to. Hop here for community-level metrics.

micro-clusters

A small group of closely similar signals that no existing topic (trend) covers yet: a possible trend at its earliest stage. Found and re-measured once or twice a day, and promoted into a topic once it sits close enough to one.

GET https://trendintel.io/api/v1/micro-clusters · GET https://trendintel.io/api/v1/micro-clusters/{id}

id integer Unique ID of the micro-cluster.
label string Automatic short label: an entity named in a quarter or more of its signals, else a 1-2 word keyword phrase. Can be null.
label_source string How label was made: 'ner' (a dominant named entity) or 'tfidf' (keywords from the signals' text). Null when there is no label.
week_current integer Voices in the cluster: the different people behind its signals (any age, up to 90 days). One account posting many times counts once; a source that names no author counts each signal. Despite the name, not a 7-day count. Until 2026-11 it counted signals (see signal_count).
signal_count integer Total signals (posts, articles) the cluster holds, any age up to 90 days: what week_current counted until 2026-11.
week_prior_avg number Voices a day over the 7 days before the last 24 hours: each person counted once for each day they spoke.
density_velocity number (Voices in the last 24 hours + 2) divided by (week_prior_avg + 2), minus 1 (0 = usual pace, 1 = double). The 2 added to both keeps a handful of people against none from reading as a surge and barely moves a busy cluster. An account posting every day reads as steady, not growing.
source_diversity integer Number of different data sources among the cluster's signals.
dominant_community string Most common audience type among its signals: developer, startup, consumer, academic, mainstream_media, institutional, market_demand, or enterprise (older data).
nearest_topic_id integer ID of the topic whose centre is closest to this cluster's, as of the last run that measured it. Retired topics are not considered.
nearest_topic_distance number Cosine distance to that nearest topic (0 = identical, lower is closer). At 0.15 or below the cluster is promoted into it.
status string 'active' while forming, 'promoted' once it matched an existing topic. Clusters 14 days without new signals are marked 'dissolved' and deleted in the same run.
promoted_to_topic_id integer Topic the cluster was promoted into; may be moved to the nearest live topic if that one is later retired. Null if not promoted.
promoted_at timestamp (UTC) When the cluster was promoted. Null if not promoted.
first_detected_at timestamp (UTC) When the cluster was first detected.
last_updated_at timestamp (UTC) Last detection run that matched or measured the cluster. Stops moving once promoted; an active cluster 14 days past this is removed.
llm_label string AI-written 3-6 word label, written once an active cluster has 5+ voices and density_velocity of 2 or more, busiest first and up to a daily limit, so a cluster that qualifies may wait for a later run. Replaced if it stops fitting.
llm_summary string AI-written 2-3 sentence summary of what is happening and why it is worth watching, written with llm_label. Null until then.
Filter by
status, dominant_community, nearest_topic_id, promoted_to_topic_id
Sort and range by
id, density_velocity, week_current, signal_count, source_diversity, last_updated_at (default -density_velocity)
Search (?q=)
label, llm_label
Rows per page
Up to 200
/micro-clusters/{id}/history a page of micro-cluster-history Daily measurements of this cluster, one row per day a detection run measured it.
/micro-clusters/{id}/nearbyTopics a page of topics Nearest macro topics to this micro-cluster (pivot exposes distance).

micro-cluster-history large: no total, after_id paging

One micro-cluster's measurements on one day, written by each detection run for every active cluster (a later run the same day replaces the row). Kept 90 days; no new rows after a cluster is promoted, and days with no completed run have no row.

GET https://trendintel.io/api/v1/micro-cluster-history · GET https://trendintel.io/api/v1/micro-cluster-history/{id}

id integer Unique ID of the history row.
micro_cluster_id integer ID of the micro-cluster this row measures.
recorded_date date Date (UTC) of the detection run. One row per cluster per day.
signal_count integer The cluster's week_current at that run: voices (different people) on counts_voices rows, signals on older rows.
density_velocity number The cluster's density_velocity at that run. On counts_voices rows: (voices in the last 24 hours + 2) / (voices a day over the 7 days before + 2) - 1. On older rows: signals instead of voices, with nothing added.
source_diversity integer Number of different data sources among the cluster's signals at that run.
recorded_at timestamp (UTC) Exact time (UTC) of the run that wrote the row; daily_count covers the 24 hours before it.
daily_count integer Voices in the cluster that spoke in the 24 hours before the run (signals gained, on older rows).
counts_voices boolean True from 2026-11 when sizes and velocity count voices, not signals, and velocity adds 2 to both days. The numbers change once at the switch (a cluster one account was filling drops to one voice, and a jump from almost nothing reads far smaller), so compare rows on the same side of it.
Filter by
micro_cluster_id, counts_voices
Sort and range by
id, recorded_date, signal_count, density_velocity (default -recorded_date)
Rows per page
Up to 200
/micro-cluster-history/{id}/microCluster or ?include=microCluster one micro-clusters The micro-cluster this row measures: its labels, status and current numbers.

SEC filings and the Fed

institutional-documents

One row per document we collect: an SEC filing, or a Federal Reserve FOMC statement or minutes release. Structured details and detected entities link back to it by document_id.

GET https://trendintel.io/api/v1/institutional-documents · GET https://trendintel.io/api/v1/institutional-documents/{id}

id integer Unique document ID. Other finance resources point to it as document_id.
source string What kind of document it is. See the list of values below.
entity_name string The company (SEC filings; often with tickers in parentheses), the investment manager (13F), the subject company (13D/13G) or "Federal Open Market Committee" (fomc).
filed_at timestamp (UTC) Date the document was filed or released: the SEC filing date or the Fed release date. Date only; the time is always 00:00 UTC.
period_covered string Reporting period as YYYY-MM-DD: the period-end date for sec_10q, sec_10k and sec_20f, the holdings' quarter-end date for sec_13f, the release date for fomc. Null for the other sources.
created_at timestamp (UTC) When we first stored the document.
Filter by
source, entity_name
Sort and range by
id, filed_at, created_at (default -filed_at)
Rows per page
Up to 200
/institutional-documents/{id}/entityMentions a page of filing-entity-mentions Entities (companies, products) detected in this filing with per-section mention counts.
/institutional-documents/{id}/holdings a page of institutional-holdings Structured 13F positions reported in this filing (populated only for 13F-HR documents; empty for narrative filings).
/institutional-documents/{id}/insiderTransactions a page of insider-transactions Structured insider buy/sell transactions reported in this filing (populated only for Form 4 documents).
/institutional-documents/{id}/ownershipStakes a page of ownership-stakes Structured 13D/13G beneficial-ownership stakes reported in this filing (populated only for Schedule 13D/13G documents).
/institutional-documents/{id}/privatePlacements a page of private-placements Structured Form D private-placement offerings reported in this filing (populated only for Form D documents).

Values of source

sec_10q SEC Form 10-Q, a company's quarterly report. Original filings only; amendments are skipped.
sec_10k SEC Form 10-K, a company's annual report. Original filings only; amendments are skipped.
sec_8k SEC Form 8-K, a current report on a material event. Kept only when it covers Item 1.01, 2.02, 5.02, 7.01 or 8.01 and the main document has text for it.
sec_s1 SEC Form S-1, a registration statement for an IPO or new share offering. Amendments (S-1/A) are included.
sec_20f SEC Form 20-F, the annual report of a foreign company listed in the US.
sec_def14a SEC Schedule 14A definitive proxy statement (DEF 14A), filed before a shareholder meeting.
sec_424b SEC Rule 424(b) final prospectus for a completed offering (forms 424B1, 424B3, 424B4 and 424B5).
sec_13f SEC Form 13F-HR, an institutional investment manager's quarterly holdings report. Positions are in institutional-holdings. Amendments are skipped.
sec_form4 SEC Form 4, an insider's report of a change in their holdings of the company's securities. Transactions are in insider-transactions. Amendments are skipped.
sec_13dg SEC Schedule 13D or 13G, a disclosure of beneficial ownership above 5% of a share class, including amendments. Stakes are in ownership-stakes.
form_d SEC Form D, notice of a private securities offering exempt from registration. The offering is in private-placements. Amendments and Investment Company Act 3(c) fund filings are skipped.
fomc A Federal Open Market Committee policy statement or meeting minutes, published by the Federal Reserve.

filing-entity-mentions

One row per entity (company, product, person, place, event or titled work) our entity recognition found in one section type of one narrative document, with how often it appeared and how the surrounding sentences frame it. 13F, Form 4, 13D/13G and Form D documents have no mentions.

GET https://trendintel.io/api/v1/filing-entity-mentions · GET https://trendintel.io/api/v1/filing-entity-mentions/{id}

id integer Unique mention row ID.
document_id integer The document the entity appeared in (an institutional-documents id).
section_type string Part of the document the entity came from: mda = Management's Discussion and Analysis; risk_factors = Risk Factors; business = Business description; market_risk = market-risk disclosures (these four from 10-Q, 10-K, 20-F, S-1 and 424B); 8-K items: material_agreement (1.01), results (2.02), management_change (5.02), regulation_fd (7.01), other_events (8.01); DEF 14A: compensation, governance; 424B: use_of_proceeds; fomc_statement; fomc_minutes; litigation (case caption, court, cause and parties).
normalized_entity string Entity name as detected, lowercased with spaces collapsed (e.g. "boston scientific corporation"). Can include a leading "the" or partial words.
entity_label string Entity type: ORG = company or organization; PRODUCT = product; PERSON = person; GPE = country, state or city; EVENT = named event; WORK_OF_ART = titled work such as a report or law.
mention_count integer Times the entity appeared in one ~600-word passage of the section. For longer sections, the last passage's count, not a section total.
created_at timestamp (UTC) When the mention was first recorded.
sentiment_score number Tone of the sentences naming the entity, -1 (negative) to 1 (positive): our finance-tuned AI sentiment model's average over up to 3 sentences. ORG and PRODUCT only.
sentiment_label string positive (score above 0.15), negative (below -0.15) or neutral (in between). Null when not scored.
sentiment_samples integer Number of sentences scored for sentiment_score (0 to 3). 0 when not scored.
Filter by
document_id, section_type, normalized_entity, entity_label, sentiment_label
Sort and range by
id, mention_count, sentiment_score, created_at (default -mention_count)
Rows per page
Up to 200
/filing-entity-mentions/{id}/document or ?include=document one institutional-documents The filing this entity was mentioned in.

finance-themes

One row per theme our AI drew from the last 30 days of entity mentions in one section type, such as risk factors or 8-K management changes: a title, a written summary and the entities behind it. Generated weekly; each run adds new rows and older ones are kept.

GET https://trendintel.io/api/v1/finance-themes · GET https://trendintel.io/api/v1/finance-themes/{id}

id integer Unique theme ID.
label string Short theme title written by our AI (about 5 to 10 words).
summary string Two-paragraph explanation by our AI of what the filings show and why it matters. If the AI was unavailable, a template marked "Heuristic summary".
theme_type string risk = entities framed mostly negatively; opportunity or investment = mostly positively (our AI picks which); event = allowed, rarely used. Without the AI, neutral framing gives investment.
section_type string Section type the theme was drawn from; same values as filing-entity-mentions.section_type (e.g. risk_factors, management_change, use_of_proceeds, litigation).
period_start date First day of the 30-day window of filings the theme covers (filing date).
period_end date Last day of the window: the day the theme was generated.
document_count integer Sum of filing counts over all entities considered for this section and run; not distinct filings. Same for every theme of that section and run.
entity_count integer Number of entities considered for this section and run (each in 10+ filings; at most 25), not the entities in this theme.
top_entities JSON JSON array of up to 10 entities behind the theme: entity, label (ORG/PRODUCT), doc_count (filings in the window), sentiment (average, -1 to 1, or null).
related_topic_cluster_ids JSON JSON array of up to 10 topic IDs (see topics) whose signals mention this theme's entities. Null when none match.
generated_at timestamp (UTC) The hour the weekly run that produced the theme started. Themes from one run share this value.
created_at timestamp (UTC) When the theme row was stored.
Filter by
theme_type, section_type
Sort and range by
id, document_count, entity_count, period_start, period_end, generated_at (default -generated_at)
Rows per page
Up to 100

institutional-holdings large: no total, after_id paging

One row per position in an institutional investment manager's quarterly Form 13F-HR report: which security it held at quarter end, how many shares and the market value. Up to 5,000 positions are stored per filing.

GET https://trendintel.io/api/v1/institutional-holdings · GET https://trendintel.io/api/v1/institutional-holdings/{id}

id integer Unique holding row ID.
document_id integer The 13F filing this position came from (an institutional-documents id).
filer_name string Investment manager that filed the 13F, as filed (may include its own tickers in parentheses).
filer_cik string Manager's SEC Central Index Key (CIK), without leading zeros.
issuer_name string Issuer of the security as written in the filing, often abbreviated (e.g. "VANGUARD TOTAL INTERNATIONAL").
cusip string 9-character CUSIP identifying the security.
title_of_class string Class of security as the filer wrote it, e.g. COM, CL A or OTHER.
value_usd integer Market value of the position at quarter end, in whole US dollars, as reported by the filer.
shares integer Number of shares held, or the principal amount when shares_type is PRN.
shares_type string SH = number of shares; PRN = principal amount (bonds and other debt).
put_call string Put or Call when the row is an option position; null for a direct holding.
investment_discretion string Who makes investment decisions for the position: SOLE = this manager alone; DFND = shared-defined (shared with a related manager); OTR = shared-other.
period_of_report date Quarter-end date the holdings are reported as of.
filed_at timestamp (UTC) Date the 13F was filed with the SEC.
created_at timestamp (UTC) When we stored the row.
Filter by
document_id, filer_name, filer_cik, issuer_name, cusip, put_call
Sort and range by
id, value_usd, shares, period_of_report, filed_at (default -value_usd)
Rows per page
Up to 200
/institutional-holdings/{id}/document or ?include=document one institutional-documents The 13F filing this position was reported in (filer, period, filed_at).

insider-transactions

One row per transaction a company insider (officer, director or 10% owner) reported on SEC Form 4: a purchase, sale, grant, option exercise, gift or other change. Covers both shares and derivatives such as options.

GET https://trendintel.io/api/v1/insider-transactions · GET https://trendintel.io/api/v1/insider-transactions/{id}

id integer Unique transaction row ID.
document_id integer The Form 4 filing this transaction came from (an institutional-documents id).
issuer_name string Company whose securities were traded, as named on the Form 4.
issuer_ticker string Company's trading symbol as given on the Form 4.
insider_name string Reporting insider's name as filed, usually last name first. If several people filed together, the first.
insider_title string Officer title as filed (e.g. Chief Financial Officer); null if the insider is not an officer.
insider_is_director boolean True if the insider is a director of the company.
insider_is_officer boolean True if the insider is an officer of the company.
insider_is_ten_percent boolean True if the insider owns more than 10% of a class of the company's shares.
security_title string Security traded, as filed, e.g. "Common Stock" or "Stock Option (right to buy)".
transaction_date date Date the transaction took place.
transaction_code string SEC Form 4 code: P = open-market or private purchase; S = open-market or private sale; A = grant or award from the company; D = sale or return to the company; F = shares withheld to pay exercise price or tax; M = exercise or conversion of an exempt derivative; C = conversion of a derivative; X = exercise of an in-the-money derivative; O = exercise of an out-of-the-money derivative; E = expiration of a short derivative position; H = expiration of a long derivative position; G = gift; I = discretionary transaction; J = other (explained in the filing's footnotes); K = equity swap; L = small acquisition; U = shares tendered in a change of control; W = inheritance; Z = voting trust deposit or withdrawal.
shares number Number of shares, or of derivative units for derivative rows, in this transaction.
price_per_share number Price per share or unit in US dollars as reported; null or 0 when no price applies (grants, gifts, awards).
acquired_disposed string A = acquired (holding went up); D = disposed (holding went down).
shares_owned_after number Shares, or derivative units, of this security the insider held after the transaction.
is_derivative boolean True for derivative securities (options, stock units, warrants); false for shares themselves.
filed_at timestamp (UTC) Date the Form 4 was filed with the SEC.
created_at timestamp (UTC) When we stored the row.
Filter by
document_id, issuer_name, issuer_ticker, insider_name, transaction_code, acquired_disposed, is_derivative
Sort and range by
id, transaction_date, shares, price_per_share, shares_owned_after, filed_at (default -transaction_date)
Rows per page
Up to 200
/insider-transactions/{id}/document or ?include=document one institutional-documents The Form 4 filing this transaction was reported in (issuer, insider, filed_at).

ownership-stakes

One row per holder (reporting person) on an SEC Schedule 13D or 13G filing, disclosing beneficial ownership of more than 5% of a company's share class, or a change to it on amendments. Related holders on one filing often report the same shares.

GET https://trendintel.io/api/v1/ownership-stakes · GET https://trendintel.io/api/v1/ownership-stakes/{id}

id integer Unique stake row ID.
document_id integer The 13D/13G filing this stake came from (an institutional-documents id).
subject_name string Company whose shares are held, as named on the filing's cover page.
subject_cik string Company's SEC Central Index Key (CIK), without leading zeros.
cusip string CUSIP of the share class the stake is in.
holder_name string Holder (reporting person) named on the filing.
stake_type string 13D = Schedule 13D, filed by holders who may seek to influence or control the company (activist); 13G = Schedule 13G, the short form for passive investors and certain institutions.
is_amendment boolean True for an amendment (13D/A or 13G/A) that updates an earlier filing, often a stake change or exit.
percent_of_class number Share of the class this holder beneficially owns, in percent (13.3 means 13.3%).
shares number Total number of shares this holder beneficially owns.
reporting_person_type string SEC type code: IN = individual; CO = corporation; PN = partnership; IA = investment adviser; HC = parent holding company or control person; BD = broker-dealer; BK = bank; IC = insurance company; IV = investment company; EP = employee benefit plan; SA = savings association; CP = church plan; FI = non-US institution; OO = other.
event_date date Date of the event that required the filing, such as crossing 5%.
filed_at timestamp (UTC) Date the filing was made with the SEC.
created_at timestamp (UTC) When we stored the row.
Filter by
document_id, subject_name, subject_cik, cusip, holder_name, stake_type, is_amendment
Sort and range by
id, percent_of_class, shares, event_date, filed_at (default -filed_at)
Rows per page
Up to 200
/ownership-stakes/{id}/document or ?include=document one institutional-documents The Schedule 13D/13G filing this stake was reported in (subject, holder, filed_at).

private-placements

One row per SEC Form D notice: a company raising money in a private offering exempt from registration, with its industry, offering size, amount sold so far and number of investors. Amendments and Investment Company Act 3(c) fund filings are excluded.

GET https://trendintel.io/api/v1/private-placements · GET https://trendintel.io/api/v1/private-placements/{id}

id integer Unique placement row ID.
document_id integer The Form D filing this offering came from (an institutional-documents id).
issuer_name string Company raising the money, as named on the Form D.
issuer_cik string Issuer's SEC Central Index Key (CIK), without leading zeros.
jurisdiction string Where the issuer is incorporated, as filed in capitals, e.g. DELAWARE or BRITISH COLUMBIA, CANADA.
entity_type string Issuer's legal form as filed: Corporation, Limited Liability Company, Limited Partnership, General Partnership, Business Trust or Other.
industry_group string Industry group the issuer chose on the Form D, e.g. Biotechnology, Other Technology, Commercial (real estate), Pooled Investment Fund or Other.
revenue_range string Issuer's revenue band as filed: No Revenues, $1 - $1,000,000, $1,000,001 - $5,000,000, $5,000,001 - $25,000,000, $25,000,001 - $100,000,000, Over $100,000,000, Decline to Disclose or Not Applicable. Funds give a net-asset-value band instead.
total_offering_amount integer Total size of the offering in US dollars; null when filed as indefinite.
total_amount_sold integer Amount sold so far, in US dollars, as of the filing.
total_remaining integer Amount still to be sold, in US dollars; null when the offering size is indefinite.
num_investors integer Number of investors who have already invested in the offering.
has_non_accredited boolean True if any non-accredited investors have invested; null if the filing doesn't say.
exemptions string Comma-separated exemption codes claimed: 06b = Rule 506(b); 06c = Rule 506(c) (public advertising allowed); 04, 04.1, 04.2, 04.3 = Rule 504; 4a5 = Securities Act Section 4(a)(5).
date_of_first_sale date Date of the first sale in the offering; null when it had not happened yet.
filed_at timestamp (UTC) Date the Form D was filed with the SEC.
created_at timestamp (UTC) When we stored the row.
Filter by
document_id, issuer_name, issuer_cik, jurisdiction, entity_type, industry_group, revenue_range, has_non_accredited
Sort and range by
id, total_offering_amount, total_amount_sold, total_remaining, num_investors, date_of_first_sale, filed_at (default -filed_at)
Rows per page
Up to 200
/private-placements/{id}/document or ?include=document one institutional-documents The Form D filing this offering was reported in (issuer, jurisdiction, filed_at).