Pressroom API
A deterministic, fully-cited news-intelligence API. Query events, entities, quotes, certified facts, and analysis across a corpus of 200,000+ articles — every answer traceable to its source.
https://api.pressroom.news
export PRESSROOM_KEY="YOUR_API_KEY" curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/search?q=election&page_size=3"
Quick start
Every request is authenticated with your API key in the X-API-Key header. Base URL: https://api.pressroom.news
Set your key once and make your first call — the panels on the right show the base URL and the request.
https://api.pressroom.news
export PRESSROOM_KEY="YOUR_API_KEY" curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/search?q=election&page_size=3"
Authentication
Pass your key on every call, either header form:
Unauthenticated requests to data endpoints return 401. Keep your key secret; it is tied to your quota and tier. Two endpoints are open (no key): /v1/health and /v1/version.
X-API-Key: YOUR_API_KEY # — or — Authorization: Bearer YOUR_API_KEY
Tiers & rate limits
Each key belongs to a tier with a monthly call quota and a per-minute burst limit. Exceeding either returns 429 with a Retry-After hint.
| Tier | Monthly quota | Burst |
|---|---|---|
free | 1,000 | 30/min |
academic | 50,000 | 60/min |
starter | 100,000 | 120/min |
growth | 1,000,000 | 300/min |
pro | 5,000,000 | 600/min |
enterprise | unlimited | 1200/min |
What you get — features & roadmap
Deterministic, provenance-cited news intelligence over a 200K+ article corpus (India / Bangladesh / UK / Nepal focus, 28 sources, English + Hindi + Bengali + Nepali originals). Every number links back to the articles and text spans it came from. No generative model sits between the corpus and your response.
| Feature | What it does | Status |
|---|---|---|
| Entity graph | Canonical people / organisations / locations — profiles, search, disambiguation, coverage timeseries, co-mention relationships, identity-change history | Live |
| Quotes as objects | 385K+ attributed quote spans, searchable, with speaker resolution (people, and institutional speakers — "the RBI said"), full provenance chain | Live |
| Canonical events | Precision-gated event registry with per-event narrative timelines and coverage breakdowns | Live |
| Certified depth cards | Typed, certified fact cards (casualty counts, deadlines, legal status…) that pass a published safety gate before they exist | Live |
| Intelligence analyses | 11 POST analyses: narrative momentum, story lifecycle, signal-vs-noise, blind spots, epistemic confidence, story attribution, quote provenance, crisis trajectory… | Live |
| Cited briefs & QA | Deterministic analyst briefs and retrieval QA — every sentence cited, no LLM hallucination surface | Live |
| Geo layer | Heatmaps, radius queries, sentiment geography over geocoded locations | Live — coverage expanding |
| Real-time stream | SSE mention stream from a cursor | Live |
| Workspace | Saved searches (watchlists) and per-key article tags | Live |
| Embeddable widgets | Drop-in intelligence widgets (quotes, entity cards, narratives, coverage maps, analyses) rendered on your site via domain-locked publishable keys — each fetch meters as one API call on your plan | Live |
| Entity enrichment at depth | Wikidata-grounded org typing, industry, country and multilingual aliases across the long tail | Rolling out |
| Self-serve keys & billing | Sign up, get a key, pay online — today keys are issued by request (below) | Planned |
| Continuous corpus sync | Cloud replica updated continuously from the extraction pipeline | Planned |
What we deliberately do not offer: article body text. Pressroom is not a content-redistribution service — endpoints return metadata, entities, quotes, and analyses, each linking to the publisher's canonical URL. Read the journalism where it was published.
Response format
Every response is JSON. List endpoints wrap results in data with a meta block for pagination; single-object endpoints return data directly.
Paginate with page and page_size query parameters.
{
"data": [ /* … results … */ ],
"meta": { "total": 9690, "page": 1, "page_size": 3 }
}Errors
The API uses conventional HTTP status codes and returns every error in one uniform envelope: a machine-readable code, a human-readable message, and a structured detail object naming the offending field or id. Nothing about your request internals is ever echoed back — no SQL, no stack traces, by design.
Every response — success or error — carries an X-Request-Id header and an X-Response-Time-ms header. Include the request_id when contacting support; it pins your exact request in our logs.
| Code | HTTP | Meaning |
|---|---|---|
bad_request | 400 | Invalid parameter — detail names the field (e.g. page_size out of range). |
unauthorized | 401 | Missing, invalid, or revoked API key. |
forbidden | 403 | Key class or tier not allowed here — a publishable pk_ key on a non-widget route, an unauthorised embedding domain, or a tier-gated endpoint. |
not_found | 404 | Unknown id or resource — detail carries the id you sent. |
rate_limited | 429 | Over a limit; comes with a Retry-After header. detail.scope is per_minute (burst) or monthly_quota (plan quota; resets at month rollover, UTC). |
internal_error | 500 | Something failed on our side. The message is deliberately generic — nothing about your request is echoed back. |
widget_unavailable | 501 | The widget id exists but has no sellable data substrate yet — detail.reason explains. |
Handling 429s. Honor the Retry-After header. When detail.scope is per_minute you hit the burst limit — back off for the given seconds and retry. When it is monthly_quota your plan's included calls are exhausted for the period; retrying sooner than the month rollover (or a tier upgrade) will not help.
Metering headers. Responses also carry X-Metering-State: normally FINALIZED. The rare RESERVED_RECONCILIATION_REQUIRED means the call was counted but its final status/latency record is pending reconciliation — an operational signal on our side, nothing you need to act on.
{
"error": {
"code": "not_found",
"message": "event not found.",
"detail": { "id": 999999 },
"request_id": "3f61c2a97d0b4e18"
}
}{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded.",
"detail": { "retry_after": 42, "scope": "per_minute" },
"request_id": "9b04d7c1e52a8f36"
}
}X-Request-Id: 3f61c2a97d0b4e18 X-Response-Time-ms: 104 X-Metering-State: FINALIZED Retry-After: 42 # 429 responses only
Search & discovery
Full-text article search GET /v1/search
Search 200K+ articles with filters for source, language, date range, and entity.
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/search?q=election&page_size=3"
{
"data": [
{
"article_id": 194929,
"headline": "Union Minister Amit Shah addresses Vijay Sankalp Abhiyan of booth workers in Indore & starts BJP's election campaign from Malwa region",
"dek": null,
"language": "en",
"provenance": {
"source_id": "news-on-air",
"source_name": "News On AIR",
"source_url": "https://newsonair.gov.in/union-minister-amit-shah-addresses-vijay-sankalp-abhiyan-of-booth-workers-in-indore-starts-bjps-election-campaign-from-malwa-region",
"extraction_method": "trafilatura",
"extracted_at": "2026-07-22T11:04:10Z",
"date_published_utc": null,
"word_count": 145
}
},
{
"article_id": 192850,
"headline": "Karnataka High Court issues notice to CM Siddaramaiah on election petition",
"dek": null,
"language": "en",
"provenance": {
"source_id": "news-on-air",
"source_name": "News On AIR",
"source_url": "https://newsonair.gov.in/karnataka-high-court-issues-notice-to-cm-siddaramaiah-on-election-petition",
"extraction_method": "trafilatura",
"extracted_at": "2026-07-21T09:06:47Z",
"date_published_utc": null,
"word_count": 167
}
},
{
"article_id": 186957,
"headline": "BNP forms Central Election Steering Committee for 13th parliamentary polls",
"dek": null,
"language": "en",
"provenance": {
… (16 more lines)Canonical event registry GET /v1/events
Paginated registry of de-duplicated real-world events, each with domain, type, and coverage counts.
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/events?page_size=3"
{
"data": [
{
"id": 47133,
"label": "World Cup",
"wikidata_id": null,
"event_year": null,
"event_domain": "sport",
"event_type": "sports",
"article_count": 14783,
"has_timeline": false,
"beat_count": 0
},
{
"id": 47132,
"label": "FIFA World Cup 2026",
"wikidata_id": "Q5020214",
"event_year": "2026",
"event_domain": "sport",
"event_type": "sports",
"article_count": 2488,
"has_timeline": false,
"beat_count": 0
},
{
"id": 47187,
"label": "World Cups",
"wikidata_id": null,
"event_year": null,
"event_domain": "sport",
"event_type": "sports",
"article_count": 1110,
"has_timeline": false,
"beat_count": 0
}
],
"meta": {
"total": 9690,
… (4 more lines)Event profile GET /v1/events/47133
A single canonical event with its metadata and linkage.
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/events/47133"
{
"data": {
"id": 47133,
"kind": "event",
"name": "World Cup",
"event_domain": "sport",
"event_type": "sports",
"event_year": null,
"event_date": {
"start": null,
"end": null,
"precision": null
},
"identity": {
"resolved": false,
"wikidata_id": null
},
"description": null,
"hierarchy": {
"role": "franchise",
"parent": null,
"children": [
{
"id": 52491,
"name": "World Cup 2035",
"event_year": "2035",
"event_domain": "sport"
},
{
"id": 49379,
"name": "2034 World Cup",
"event_year": "2034",
"event_domain": "sport"
},
{
"id": 47211,
"name": "2030 World Cup",
"event_year": "2030",
… (307 more lines)Quote search GET /v1/quotes/search
Find quotes by text; each carries full provenance and a resolved speaker where known.
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/quotes/search?q=economy&page_size=3"
{
"data": [
{
"quote_id": 359746,
"text": "It is the country's confidence that when you bring another no-confidence motion in 2028, India will be the third largest economy in the world,",
"verb": null,
"type": "direct",
"confidence": 0.0,
"speaker": {
"person_id": null,
"name": null,
"speaker_text": null,
"resolved": false
},
"provenance": {
"article_id": 184949,
"headline": "Review of Parliament Proceedings",
"source_id": "news-on-air",
"source_url": "https://newsonair.gov.in/review-of-parliament-proceedings-3",
"extraction_method": "trafilatura",
"extracted_at": "2026-07-18T05:00:48Z",
"date_published_utc": null
}
},
{
"quote_id": 326004,
"text": "When a nation embarks upon a process of shifting from an ‘inward-leaning economy’ to an ‘outward-leaning economy’, the arena of national security concerns begins to move to the oceans. This is a phenomenon in history that occurs so frequently that it has almost become a rule rather than an exception.",
"verb": null,
"type": "direct",
"confidence": 0.0,
"speaker": {
"person_id": null,
"name": null,
"speaker_text": null,
"resolved": false
},
"provenance": {
"article_id": 156806,
… (37 more lines)Curated topics GET /v1/topics
The curated topic catalog.
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/topics"
{
"data": [
{
"slug": "artificial-intelligence",
"label": "Artificial Intelligence",
"source": "curated",
"article_count": 668,
"keywords": [
"artificial intelligence",
"openai",
"chatgpt",
"machine learning",
"large language model",
"generative ai",
"neural network"
],
"aliases": [
"ai",
"genai",
"generative ai",
"machine learning"
],
"sections": [],
"updated_at": "2026-07-26T09:42:49Z"
},
{
"slug": "climate-change",
"label": "Climate & Environment",
"source": "curated",
"article_count": 2239,
"keywords": [
"climate",
"emission",
"global warming",
"renewable",
"carbon",
"net zero",
"monsoon",
… (249 more lines)Topic profile GET /v1/topics/artificial-intelligence
A single topic with its profile.
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/topics/artificial-intelligence"
{
"data": {
"slug": "artificial-intelligence",
"label": "Artificial Intelligence",
"source": "curated",
"keywords": [
"artificial intelligence",
"openai",
"chatgpt",
"machine learning",
"large language model",
"generative ai",
"neural network"
],
"aliases": [
"ai",
"genai",
"generative ai",
"machine learning"
],
"sections": [],
"stats": {
"article_count": 668,
"first_seen": "2025-07-06T12:11:14Z",
"last_seen": "2026-07-26T03:53:15Z"
},
"top_sources": [
{
"source": "Mint",
"articles": 324
},
{
"source": "Reuters",
"articles": 83
},
{
"source": "Hindustan Times",
"articles": 46
… (32 more lines)Entities — people, organisations, locations
Entity profile GET /v1/people/174
Canonical profile for a person, organisation, or location (the {kind} is people / organisations / locations).
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/people/174"
{
"data": {
"id": 174,
"kind": "people",
"name": "Narendra Modi",
"identity": {
"resolved": true,
"wikidata_id": "Q1058",
"lei_code": null,
"status": "resolved"
},
"attributes": {
"current_title": null,
"current_employer": null,
"nationality": null,
"date_of_birth": null,
"wikipedia_url": "https://en.wikipedia.org/wiki/Narendra_Modi",
"twitter_handle": "narendramodi",
"twitter_url": "https://twitter.com/narendramodi",
"linkedin_url": "narendramodi",
"official_bio_url": "https://www.narendramodi.in",
"image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5f/The_official_portrait_of_Shri_Narendra_Modi%2C_the_Prime_Minister_of_the_Republic_of_India.jpg/330px-The_official_portrait_of_Shri_Narendra_Modi%2C_the_Prime_Minister_of_the_Republic_of_India.jpg",
"bio_text": "Narendra Damodardas Modi is an Indian politician who has served as the prime minister of India since 26 May 2014. Modi was the chief minister of Gujarat from 2001 to 2014 and is the Member of Parliament (MP) for Varanasi. He is a member of the Bharatiya Janata Party (BJP) and of the Rashtriya Swayamsevak Sangh (RSS), a right-wing Hindutva paramilitary volunteer organisation. He is India's third-longest-serving prime minister, and the longest-serving prime minister outside the Indian National Congress.",
"bio_source": "wikipedia"
},
"aliases": [
"Modi",
"Modi ji",
"Narender Modi",
"Narendra Damodardas Modi",
"Narendra Modi",
"Narendra) Modi",
"Narendra] Modi",
"Shri Modi",
"Shri Narendra Modi",
"Shri Narendra Modi ji"
],
"stats": {
… (9 more lines)Entity relationships GET /v1/people/174/relationships
Top co-mentioned people, organisations, and locations for an entity.
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/people/174/relationships"
{
"data": {
"entity_id": 174,
"kind": "people",
"source_article_count": 5501,
"people": [
{
"id": 11084,
"name": "Modi",
"wikidata_id": null,
"co_count": 702,
"first_seen": "2025-11-24T18:30:00Z",
"last_seen": "2026-07-26T10:40:47Z",
"salience": 0.1276
},
{
"id": 1,
"name": "Donald Trump",
"wikidata_id": "Q22686",
"co_count": 553,
"first_seen": "2025-09-10T18:15:00Z",
"last_seen": "2026-07-25T12:00:00Z",
"salience": 0.1005
},
{
"id": 622,
"name": "Amit Shah",
"wikidata_id": "Q4746875",
"co_count": 449,
"first_seen": "2023-06-02T18:30:00Z",
"last_seen": "2026-07-26T10:40:47Z",
"salience": 0.0816
},
{
"id": 1268,
"name": "Rahul Gandhi",
"wikidata_id": "Q10218",
"co_count": 416,
… (520 more lines)Quotes by a person GET /v1/people/174/quotes
Quotes attributed to a person, with provenance.
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/people/174/quotes?page_size=2"
{
"data": [
{
"quote_id": 377063,
"text": "Smt. Sonia Gandhi’s mother, Mrs. Paola Maino passed away at her home in Italy on Saturday the 27th August 2022. The funeral took place yesterday,",
"verb": "tweeted",
"type": "direct",
"confidence": 0.85,
"provenance": {
"article_id": 174102,
"headline": "Congress chief Sonia Gandhi's mother passes away",
"source_id": "the-hindu",
"source_url": "https://thehindu.com/news/national/congress-chief-sonia-gandhis-mother-passes-away/article65833715.ece",
"extraction_method": "trafilatura",
"extracted_at": "2026-07-15T20:02:30Z",
"date_published_utc": null
}
},
{
"quote_id": 377062,
"text": "May her soul rest in peace. In this hour of grief, my thoughts are with the entire family.",
"verb": "tweeted",
"type": "direct",
"confidence": 0.85,
"provenance": {
"article_id": 174102,
"headline": "Congress chief Sonia Gandhi's mother passes away",
"source_id": "the-hindu",
"source_url": "https://thehindu.com/news/national/congress-chief-sonia-gandhis-mother-passes-away/article65833715.ece",
"extraction_method": "trafilatura",
"extracted_at": "2026-07-15T20:02:30Z",
"date_published_utc": null
}
}
],
"meta": {
"total": 1758,
"page": 1,
… (3 more lines)Certified depth cards
Depth cards GET /v1/depth-cards
Certified, provenance-cited story-state facts (e.g. casualty / arrest counts) — every card is gated and traceable to its source span.
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/depth-cards?page_size=3"
{
"data": [
{
"card_id": "cc_arrest_count_ca89a2c654546c73",
"contract_version": "depth_card_v1",
"disposition": "PUBLISHED",
"object_class": "ARREST_COUNT",
"base_class": "ARREST_COUNT",
"claim": "people arrested = 11",
"claimed_value": 11.0,
"unit": "people",
"story_unit_id": null,
"minted_at": "2026-07-25T14:38:07.732862Z",
"provenance": {
"article_ids": [
26091
],
"primary_article_id": 26091,
"source_name": "myrepublica",
"publication_date": null,
"license_path": "P2_PERSON_HEAD",
"span": "“Chinese security personnel recently arrested 11 Nepali traders.",
"offsets": {
"start": 949,
"end": 951
},
"method": "typed_count_factory -> publish_safety_gate -> held_queue(rubric_v3, qwen3:14b local) -> reader_canary",
"gate": {
"status": "AUTO_PUBLISH",
"families": [],
"reason": null
},
"frozen_gate_sha256": "ede56aeb1bc2709caf77596e6489cd41a73fe6140e521ba5afddb7bbf2acbf24",
"adjudicator": "none",
"adjudicator_rationale": "publish_safety_gate AUTO_PUBLISH (deterministic; no model call)",
"verdict_cache_key": null,
"cert_ref": null,
"content_hash": "ad2527eb0a086145acda10df8add427dc7a5358c3091fd6bede08e968fc6a923"
… (85 more lines)Single depth card GET /v1/depth-cards/cc_arrest_count_ca89a2c654546c73
One certified card by id, with full provenance.
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/depth-cards/cc_arrest_count_ca89a2c654546c73"
{
"data": {
"card_id": "cc_arrest_count_ca89a2c654546c73",
"contract_version": "depth_card_v1",
"disposition": "PUBLISHED",
"object_class": "ARREST_COUNT",
"base_class": "ARREST_COUNT",
"claim": "people arrested = 11",
"claimed_value": 11.0,
"unit": "people",
"story_unit_id": null,
"minted_at": "2026-07-25T14:38:07.732862Z",
"provenance": {
"article_ids": [
26091
],
"primary_article_id": 26091,
"source_name": "myrepublica",
"publication_date": null,
"license_path": "P2_PERSON_HEAD",
"span": "“Chinese security personnel recently arrested 11 Nepali traders.",
"offsets": {
"start": 949,
"end": 951
},
"method": "typed_count_factory -> publish_safety_gate -> held_queue(rubric_v3, qwen3:14b local) -> reader_canary",
"gate": {
"status": "AUTO_PUBLISH",
"families": [],
"reason": null
},
"frozen_gate_sha256": "ede56aeb1bc2709caf77596e6489cd41a73fe6140e521ba5afddb7bbf2acbf24",
"adjudicator": "none",
"adjudicator_rationale": "publish_safety_gate AUTO_PUBLISH (deterministic; no model call)",
"verdict_cache_key": null,
"cert_ref": null,
"content_hash": "ad2527eb0a086145acda10df8add427dc7a5358c3091fd6bede08e968fc6a923"
}
… (2 more lines)Analysis & briefs (POST)
Narrative momentum POST /v1/analyse/narrative-momentum
Coverage momentum for a query — volume, diversity, geographic and sentiment trend.
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"q": "election"}' \
"https://api.pressroom.news/v1/analyse/narrative-momentum"{
"data": {
"subject": "q:election",
"window": {
"from": "2026-04-27",
"to": "2026-07-26",
"midpoint": "2026-06-11"
},
"total_articles": 1093,
"recent_half": {
"volume": 472,
"sources": 75,
"countries": 5,
"sentiment": -0.0067
},
"prior_half": {
"volume": 621,
"sources": 24,
"countries": 5,
"sentiment": 0.0707
},
"components": {
"volume_rate_change": -0.2399,
"source_diversity_delta": 0.2881,
"geographic_spread_delta": 0.0,
"sentiment_delta": -0.0774
},
"momentum_score": -0.0701,
"method": "deterministic; weights v=0.5 div=0.2 geo=0.2 sent=0.1"
}
}Cited retrieval QA POST /v1/chat
Deterministic question-answering over the corpus with citations — no LLM, fully reproducible.
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"question": "What has been reported about elections?"}' \
"https://api.pressroom.news/v1/chat"{
"data": {
"question": "What has been reported about elections?",
"answer": "8 relevant article(s) from 5 source(s) address this. Leading coverage: \"As heat wave sweeps across several states in the US, White House has reportedly deleted thousands of web pages about...\" (the-times-of-india, 2026-07-05). See cited passages below.",
"matched_terms": [
"has",
"reported",
"elections"
],
"passages": [
{
"headline": "As heat wave sweeps across several states in the US, White House has reportedly deleted thousands of web pages about...",
"dek": null,
"provenance": {
"article_id": 186888,
"source_id": "the-times-of-india",
"source_url": "https://timesofindia.indiatimes.com/technology/tech-news/as-heat-wave-sweeps-across-several-states-in-the-us-white-house-has-reportedly-deleted-thousands-of-web-pages-about-/articleshow/132196710.cms",
"date_published_utc": "2026-07-05T13:43:00Z"
}
},
{
"headline": "Paul Hogan has reportedly called Pauline Hanson a ‘pelican’. Please explain?",
"dek": null,
"provenance": {
"article_id": 132390,
"source_id": "the-guardian",
"source_url": "https://theguardian.com/australia-news/2026/jun/28/paul-hogan-pauline-hanson-pelican-insult-australian-slang-please-explain",
"date_published_utc": "2026-06-28T07:41:24Z"
}
},
{
"headline": "Republicans reportedly weigh stopgap funding plan to avert Government shutdown before midterm elections",
"dek": "Senator Rick Scott's proposal comes ahead of a planned meeting between President Donald Trump and Senate Republicans, where lawmakers are expected to discuss priorities for the remainder of the year.",
"provenance": {
"article_id": 108287,
"source_id": "mint",
"source_url": "https://livemint.com/news/us-news/republicans-reportedly-weigh-stopgap-funding-plan-to-avert-government-shutdown-before-midterm-elections-11782317710245.html",
"date_published_utc": "2026-06-24T16:35:08Z"
… (91 more lines)Analyst brief POST /v1/briefs/generate
A deterministic, cited analyst brief for a query or entity.
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"q": "election"}' \
"https://api.pressroom.news/v1/briefs/generate"{
"data": {
"subject": "q:election",
"window": {
"from": "2026-04-27",
"to": "2026-07-26"
},
"total_articles": 1093,
"summary": "1093 articles from 8 sources cover q:election (2026-04-27–2026-07-26). Most-associated people: Donald Trump, Andy Burnham, Keir Starmer; organisations: BJP, Reuters, Labour; locations: United States, India, UK. 5 attributed quote(s) surfaced. Every claim is cited below.",
"top_entities": {
"people": [
{
"name": "Donald Trump",
"co_count": 183
},
{
"name": "Andy Burnham",
"co_count": 76
},
{
"name": "Keir Starmer",
"co_count": 62
},
{
"name": "Nigel Farage",
"co_count": 53
},
{
"name": "Joe Biden",
"co_count": 42
}
],
"organisations": [
{
"name": "BJP",
"co_count": 211
},
{
… (301 more lines)Embeddable widgets
Put live Pressroom intelligence on your own pages — attributed quotes, entity cards, active narratives, coverage maps, and analyses — with two lines of HTML. Widgets are a feature of your API plan, not a separate product: every widget data fetch meters as one API request against your monthly quota.
Publishable keys. Embeds use a pk_ publishable key minted from your account. It is safe to expose in page source: it only works on domains you allow-list, only reaches widget-data endpoints, and spends only your own quota. Your secret pr_ key never appears in a browser. Rotate or revoke a pk_ key at any time.
Honest states. A widget over quota or on an unauthorised domain renders a labelled error state — it never silently shows stale or fabricated data. Every widget carries a "Powered by Pressroom" attribution.
Catalogue. GET /v1/widgets lists the available widget ids: narrative_pulse, active_narrative_list, quote_provenance, daily_executive_brief, source_diversity, entity_intelligence_card, regional_news_map, narrative_conflict, coverage_trajectory, narrative_momentum. Widgets without a production-grade data substrate are not offered.
<script async src="https://api.pressroom.news/widget.js"></script>
<div class="pressroom-widget"
data-widget="quote_provenance"
data-subject="Reserve Bank of India"
data-key="pk_YOUR_PUBLISHABLE_KEY"></div>curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/widgets/entity_intelligence_card/data?subject=Adani"
{
"data": { "profile": { "name": "Gautam Adani", "…": "…" } },
"meta": {
"widget": "entity_intelligence_card",
"attribution_required": true,
"window_days": 30
}
}Widget catalogue GET /v1/widgets
Lists the widgets available to embed, with each id's display name, whether it needs a subject, and its data URL. Accepts secret or publishable keys.
| Widget id | Name | subject |
|---|---|---|
narrative_pulse | Narrative Pulse | optional |
active_narrative_list | Active Narratives | optional |
quote_provenance | Quote Provenance | required |
daily_executive_brief | Daily Executive Brief | required |
source_diversity | Source Diversity | optional |
entity_intelligence_card | Entity Intelligence Card | required |
regional_news_map | Coverage Map | optional |
narrative_conflict | Narrative Conflict | required |
coverage_trajectory | Coverage Trajectory | required |
narrative_momentum | Narrative Momentum | required |
Widget ids from our internal gallery that lack a production-grade public data substrate are not listed; requesting one returns 501 widget_unavailable with the reason — never fabricated data.
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/widgets"
{
"data": [
{
"id": "narrative_pulse",
"name": "Narrative Pulse",
"needs_subject": false,
"data_url": "/v1/widgets/narrative_pulse/data"
},
{
"id": "quote_provenance",
"name": "Quote Provenance",
"needs_subject": true,
"data_url": "/v1/widgets/quote_provenance/data"
},
{ "…": "… 8 more widgets …" }
],
"meta": {
"total": 10,
"embed": {
"loader": "/widget.js",
"iframe": "/widgets/embed"
},
"billing": "each data fetch meters as one API request on the key's account"
}
}Widget data (metered) GET /v1/widgets/{id}/data
The data payload behind a widget — the same payload the iframe renders, usable directly from your own code.
Parameters. subject — the entity or query the widget is about; required for subject-scoped widgets (see the catalogue). days — the coverage window in days; default 30, max 365.
Auth. Pass an X-API-Key header (publishable pk_ or secret key), or — for pk_ keys, which are public by design — a ?key= query parameter (that is how the embed iframe authenticates its plain GET navigation).
Metering. Every fetch meters as one API request on the owning account. Payloads are cached server-side for up to 5 minutes to protect the database from hot embeds; cached fetches still meter — the cache protects the corpus, not the bill.
Attribution. When meta.attribution_required is true, the embed must display the "Powered by Pressroom" badge.
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/widgets/quote_provenance/data?subject=India"
{
"data": {
"quotes": [
{
"quote_id": 399748,
"text": "India has exported its food culture to the world, but not its alcohol. We are still drinking a colonial legacy. There will be an Indian alcohol story, and we are working towards it,",
"verb": "said",
"type": "direct",
"confidence": 0.82,
"speaker": {
"kind": "person",
"person_id": 293146,
"name": "Sameer Mahandru",
"speaker_text": "Mahandru",
"resolved": true
},
"provenance": {
"article_id": 206027,
"headline": "UK FTA to intensify competition in alcobev market: IndoBevs",
"source_id": "financial-express",
"source_url": "https://financialexpress.com/policy/economy/uk-fta-to-intensify-competition-in-alcobev-market-indobevs/4303156",
"extraction_method": "ld_json",
"date_published_utc": "2026-07-26T18:13:30Z"
}
},
{ "…": "9 more" }
],
"total": 11785
},
"meta": {
"widget": "quote_provenance",
"name": "Quote Provenance",
"subject": "India",
"window_days": 30,
"attribution_required": true
}
}Embed attributes
Attributes on the <div class="pressroom-widget"> loader element.
| Attribute | Meaning |
|---|---|
data-widget | Widget id from the catalogue. Required. |
data-subject | Entity or query the widget is about (required for subject-scoped widgets). |
data-key | Your publishable pk_ key. Required. |
data-days | Coverage window in days (default 30). |
data-theme | dark | light. |
data-width | Iframe width (default 100%). |
data-height | Pins a fixed height; otherwise the iframe auto-grows. |
data-title | Accessible iframe title. |
Embed error states
Each renders as a labelled state inside the iframe — never silent emptiness, never fake data.
| HTTP | State shown |
|---|---|
| 401 | The widget's API key is invalid or revoked. |
| 403 | Key not authorised for this domain — add the site to the key's allowed domains. |
| 429 | The account's API quota is exhausted for the current period. |
| 501 | Widget not available via the public API (reason shown). |
Live examples
These are real embeds — the exact snippets shown, rendering live corpus data on this page right now. They run on a demo publishable key that is domain-locked to pressroom.news: copy the snippet, and it will render an honest "domain not authorised" state on your site until you swap in your own pk_ key.
Each render below made one metered API call (served from the 5-minute cache when hot).
<script async src="https://api.pressroom.news/widget.js"></script>
Entity intelligence card
A person's resolved identity, links and coverage stats.
<div class="pressroom-widget"
data-widget="entity_intelligence_card"
data-subject="Narendra Modi"
data-key="pk_YOUR_KEY"></div>Quote provenance
Attributed quotes about a subject, each traceable to its article.
<div class="pressroom-widget"
data-widget="quote_provenance"
data-subject="Reserve Bank of India"
data-key="pk_YOUR_KEY"></div>Narrative pulse
The most active corroborated story units right now (no subject needed).
<div class="pressroom-widget"
data-widget="narrative_pulse"
data-key="pk_YOUR_KEY"></div>Coverage map
Where the news is happening — top mapped coverage cells, last 30 days.
<div class="pressroom-widget"
data-widget="regional_news_map"
data-key="pk_YOUR_KEY"></div>Source diversity
The registry's spread across countries and languages.
<div class="pressroom-widget"
data-widget="source_diversity"
data-key="pk_YOUR_KEY"></div>Narrative momentum
Is coverage of a subject accelerating or fading? Volume, source spread and tone, half-window over half-window.
<div class="pressroom-widget"
data-widget="narrative_momentum"
data-subject="Adani"
data-key="pk_YOUR_KEY"></div>Account & meta
Account usage GET /v1/account/usage
Your key's metering and quota state.
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/account/usage"
{
"data": {
"tier": "enterprise",
"monthly_quota": -1,
"monthly_used": 6,
"usage_period": "2026-07",
"lifetime_calls": 7,
"lifetime_cost_units": 7,
"recent": [
{
"ts": "2026-07-26 13:51:42.693016+00",
"method": "GET",
"endpoint": "/v1/account/usage",
"status": null,
"latency_ms": null
},
{
"ts": "2026-07-26 13:45:34.45839+00",
"method": "GET",
"endpoint": "/v1/depth-cards",
"status": 200,
"latency_ms": 100
},
{
"ts": "2026-07-26 13:45:33.81118+00",
"method": "GET",
"endpoint": "/v1/events",
"status": 200,
"latency_ms": 153
},
{
"ts": "2026-07-26 13:29:26.953925+00",
"method": "GET",
"endpoint": "/v1/depth-cards",
"status": 200,
"latency_ms": 112
},
{
… (23 more lines)Version & tiers GET /v1/version
API version and the tier catalog.
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/version"
{
"name": "Pressroom Analytics API",
"version": "1.0.0-dev",
"tiers": {
"free": {
"monthly_quota": 1000,
"rate_per_minute": 30
},
"academic": {
"monthly_quota": 50000,
"rate_per_minute": 60
},
"starter": {
"monthly_quota": 100000,
"rate_per_minute": 120
},
"growth": {
"monthly_quota": 1000000,
"rate_per_minute": 300
},
"pro": {
"monthly_quota": 5000000,
"rate_per_minute": 600
},
"enterprise": {
"monthly_quota": -1,
"rate_per_minute": 1200
}
}
}Corpus health GET /v1/health
Outcome-based corpus health (unauthenticated).
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/health"
{
"state": "DEGRADED",
"reasons": [
"stale_leases",
"backlog_with_zero_recent_commits"
],
"process_reachable": true,
"durable_work_healthy": false,
"corpus_reachable": true,
"articles": 204333,
"corpus_db": "/opt/pressroom/data/pressroom.db",
"metering_reconciliation_required": 0,
"oldest_metering_reservation": null
}Source registry GET /v1/sources
Every publication with its audience taxonomy.
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/sources"
{
"data": [
{
"source_id": "aajkaal",
"name": "Aajkaal",
"country_of_origin": "India",
"country_of_audience": null,
"language": "bn",
"nav_group": null,
"category": "[\"regional\"]",
"article_count": 265
},
{
"source_id": "aapti-institute",
"name": "Aapti Institute",
"country_of_origin": "India",
"country_of_audience": "India",
"language": "en",
"nav_group": null,
"category": "[\"data-governance\", \"technology\", \"policy\"]",
"article_count": 138
},
{
"source_id": "ajit",
"name": "Ajit",
"country_of_origin": "India",
"country_of_audience": null,
"language": "pa",
"nav_group": null,
"category": "[\"regional\"]",
"article_count": 49
},
{
"source_id": "algerie-eco",
"name": "Algerie-eco",
"country_of_origin": "Algeria",
"country_of_audience": null,
"language": null,
… (1739 more lines)Changelog
Versioning & stability. The /v1 surface is stable. Additive changes — new fields on existing responses, new endpoints, new enum values — are not considered breaking and can land at any time; write clients that tolerate unknown fields. Breaking changes (removing or renaming a field, changing a field's type or meaning, removing an endpoint) get a new version path (/v2) with a deprecation window on the old one — /v1 is never broken in place. Every response carries meta.generated_at, so any payload can be located in time against this changelog.
| Date | Change |
|---|---|
| 2026-07-27 | Canonical id/name fields (additive). Every primary object now exposes a canonical id and name alongside its historical key: quotes add id (= quote_id), story units add id (= unit_id), depth cards add id (= card_id), events and graph entity references add name (= label), event-related threads add id/name (= thread_id/label), sources add id (= source_id), topics add id/name (= slug/label; slug remains the URL path key), and the stance-dossier subject adds id (= person_id). Nothing is removed today: the legacy keys keep working as deprecated aliases for one API version and will be dropped in the next version path. Migrate reads to id/name now. |
| 2026-07-27 | Typed OpenAPI schema across all operations. Every endpoint now declares a typed response model with per-field descriptions; the endpoint reference below is generated from that schema and cannot drift from the code. |
| 2026-07-27 | Embeddable widgets launched. Drop-in intelligence widgets rendered via domain-locked publishable pk_ keys; every data fetch meters as one API call. |
| 2026-07-27 | Errors documented. The uniform error envelope, every error code, and the metering / request-id headers are documented above. |
| 2026-07-27 | v1.0.0 live. The Pressroom Analytics API is live at api.pressroom.news. |
Full endpoint reference
All public operations, generated from the API's typed OpenAPI schema. Every path takes the same X-API-Key auth (widget data additionally accepts publishable pk_ keys).
X-API-Key: <key> (or Authorization: Bearer <key>) — omitted from the parameter tables. Widget-data routes additionally accept publishable pk_ keys. /v1/health and /v1/version are open. This reference is generated from the API's typed OpenAPI schema (scripts/deploy/gen_api_docs.py) — it cannot drift from the code.Search, stream & workspace
Full-text article search with filters GET /v1/search
Article search over headline and dek with source / language / date / entity filters, newest first.
Returns matching article summaries with provenance and pagination meta.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
q query | string | null | optional | — | Full-text query over headline and dek. |
source query | string | null | optional | — | Restrict to one source id (see /v1/sources). |
language query | string | null | optional | — | Restrict to one article language (ISO code, e.g. en, hi). |
date_from query | string | null | optional | — | Published on/after this date (ISO YYYY-MM-DD). |
date_to query | string | null | optional | — | Published on/before this date (ISO YYYY-MM-DD). |
entity_kind query | string | null | optional | — | With entity_id: restrict to articles mentioning the entity (people | organisations | locations). |
entity_id query | integer | null | optional | — | With entity_kind: the canonical entity id. |
starting_after query | integer | null | optional | — | Optional cursor pagination: only articles with id strictly below this article id, ordered id-descending (the default newest-first date order is not id-monotone, so cursor requests switch to id order to stay sound). page/page_size keep working unchanged without it. When passed, meta.next_cursor carries the last id of the page (null = exhausted; has_more == next_cursor is not null). Start a walk with any id above the newest article. |
page query | integer | optional | 1 | Page number (1-based). |
page_size query | integer | optional | 50 | Items per page (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of ArticleItem | The endpoint's payload. |
data[].article_id | integer | null | Corpus article id. |
data[].headline | string | null | Article headline. |
data[].dek | string | null | Article dek / standfirst, when extracted. |
data[].language | string | null | Detected article language (ISO code). |
data[].mention_count | integer | null | How many times the queried entity is mentioned in this article. |
data[].provenance | Provenance | null | Provenance of the article (source, URL, extraction record). |
data[].provenance.article_id | integer | null | Corpus article id the claim came from. |
data[].provenance.headline | string | null | Headline of the source article. |
data[].provenance.source_id | string | null | Registry id of the publishing source. |
data[].provenance.source_name | string | null | Display name of the publishing source. |
data[].provenance.source_url | string | null | Canonical URL of the source article. |
data[].provenance.extraction_method | string | null | Extractor that captured the article (trafilatura, playwright, …). |
data[].provenance.extracted_at | string | null | UTC timestamp of extraction. |
data[].provenance.date_published_utc | string | null | Publisher-stated publication time (UTC). |
data[].provenance.word_count | integer | null | Extracted body word count. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/search?q=election"
import requests
r = requests.get(
"https://api.pressroom.news/v1/search",
headers={"X-API-Key": PRESSROOM_KEY},
params={"q": "election"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/search?q=election", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Real-time mention stream (SSE, held open, since a cursor) GET /v1/stream
Server-Sent Events (text/event-stream), not JSON: emits `article` events for every article after the cursor, stays open polling for new arrivals with keepalive comments, then closes with a final `cursor` event carrying the resume URL.
Returns an SSE stream.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
since_id query | integer | optional | 0 | Resume cursor: only articles with id > since_id are streamed (0 = from the latest batch). |
limit query | integer | optional | 50 | Max articles per poll batch (default 50, max 500). |
Response attributes
No JSON schema — this endpoint streams text/event-stream (see the description).
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/stream"
import requests
r = requests.get(
"https://api.pressroom.news/v1/stream",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/stream", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Attach a custom tag to an article (per-key, non-corpus) POST /v1/tag
Tags an article for your key only — tags live in the API meta store and never touch the corpus.
Returns the attached (article_id, tag) pair; 404 when the article does not exist.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
article_id body | integer | required | — | Corpus article id to tag. |
tag body | string | required | — | Tag value (1-60 chars; stored per-key, never in the corpus). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | TagResult | The endpoint's payload. |
data.article_id | integer | null | The tagged article id. |
data.tag | string | null | The tag value. |
data.created_at | string | null | When the tag was attached (list responses). |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"article_id": 186888, "tag": "follow-up"}' \
"https://api.pressroom.news/v1/tag"import requests
r = requests.post(
"https://api.pressroom.news/v1/tag",
headers={"X-API-Key": PRESSROOM_KEY},
json={"article_id": 186888, "tag": "follow-up"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/tag", {
headers: { "X-API-Key": PRESSROOM_KEY, "Content-Type": "application/json" },
method: "POST",
body: JSON.stringify({"article_id": 186888, "tag": "follow-up"})
});
const data = await res.json();List your tagged articles GET /v1/tags
Your key's article tags, newest first, optionally filtered to one tag value.
Returns the tag rows.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
tag query | string | null | optional | — | Only rows with this exact tag value. |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of TagResult | The endpoint's payload. |
data[].article_id | integer | null | The tagged article id. |
data[].tag | string | null | The tag value. |
data[].created_at | string | null | When the tag was attached (list responses). |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/tags"
import requests
r = requests.get(
"https://api.pressroom.news/v1/tags",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/tags", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();List your saved searches GET /v1/watchlists
All saved searches owned by your key, newest first.
Returns the watchlist rows with their stored queries.
Parameters
No parameters (beyond the auth header).
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of Watchlist | The endpoint's payload. |
data[].id | integer | null | Watchlist id. |
data[].name | string | null | Your name for the saved search. |
data[].query | object | null | The saved search query object. |
data[].created_at | string | null | When the watchlist was created. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/watchlists"
import requests
r = requests.get(
"https://api.pressroom.news/v1/watchlists",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/watchlists", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Create a saved search POST /v1/watchlists
Stores a named search query against your key (in the API meta store, not the corpus).
Returns the created watchlist with its id.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name body | string | required | — | Your name for the saved search (1-120 chars). |
query body | object | required | — | The search query object to save (same fields as /v1/search). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | Watchlist | The endpoint's payload. |
data.id | integer | null | Watchlist id. |
data.name | string | null | Your name for the saved search. |
data.query | object | null | The saved search query object. |
data.created_at | string | null | When the watchlist was created. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "my-watchlist", "query": "election"}' \
"https://api.pressroom.news/v1/watchlists"import requests
r = requests.post(
"https://api.pressroom.news/v1/watchlists",
headers={"X-API-Key": PRESSROOM_KEY},
json={"name": "my-watchlist", "query": "election"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/watchlists", {
headers: { "X-API-Key": PRESSROOM_KEY, "Content-Type": "application/json" },
method: "POST",
body: JSON.stringify({"name": "my-watchlist", "query": "election"})
});
const data = await res.json();Delete a saved search DELETE /v1/watchlists/{wid}
Deletes one of your saved searches.
Returns the deleted watchlist id; 404 when it does not exist or is not yours.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
wid path | integer | required | — | Watchlist id to delete. |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | WatchlistDeleted | The endpoint's payload. |
data.deleted | integer | null | Id of the deleted watchlist. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -X DELETE -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/watchlists/1"
import requests
r = requests.delete(
"https://api.pressroom.news/v1/watchlists/1",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/watchlists/1", {
headers: { "X-API-Key": PRESSROOM_KEY },
method: "DELETE"
});
const data = await res.json();Events
Paginated canonical event registry GET /v1/events
The canonical event registry (franchises, editions, and flat events) with optional domain/type/year/QID filters.
Returns event rows with coverage counts and timeline availability flags.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
domain query | string | null | optional | — | filter event_domain: sport|policy|other|non-sport |
type query | string | null | optional | — | filter event_type |
year query | string | null | optional | — | filter event_year |
has_qid query | string | null | optional | — | Wikidata-linked filter |
page query | integer | optional | 1 | Page number (1-based). |
page_size query | integer | optional | 50 | Items per page (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of EventListItem | The endpoint's payload. |
data[].id | integer | null | Canonical event id. |
data[].name | string | null | Event display name (canonical). |
data[].label | string | null | Deprecated alias of `name`; will be removed in the next API version. |
data[].wikidata_id | string | null | Wikidata QID when linked. |
data[].event_year | string | null | Edition year, when the event is an edition. |
data[].event_domain | string | null | Coarse domain: sport | policy | other. |
data[].event_type | string | null | Granular type: conflict | election | disaster | sports | summit | conference | festival | observance | ceremony | other. |
data[].parent_id | integer | null | Parent (franchise) event id, when an edition. |
data[].children_count | integer | null | Number of child events. |
data[].article_count | integer | null | Distinct articles mentioning the event. |
data[].has_timeline | boolean | null | True when a pre-generated narrative timeline artifact exists. |
data[].beat_count | integer | null | Beats in the timeline artifact (0 when none). |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/events"
import requests
r = requests.get(
"https://api.pressroom.news/v1/events",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/events", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Search canonical events GET /v1/events/search
Substring search over canonical event labels with optional domain/type filters, ranked by coverage.
Returns matching events with article counts and hierarchy hints.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
q query | string | required | — | Substring query over the canonical event label. |
domain query | string | null | optional | — | filter event_domain: sport|policy|other|non-sport |
type query | string | null | optional | — | filter event_type: conflict|election|disaster|sports|summit|conference|festival|observance|ceremony|other |
page query | integer | optional | 1 | Page number (1-based). |
page_size query | integer | optional | 50 | Items per page (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of EventListItem | The endpoint's payload. |
data[].id | integer | null | Canonical event id. |
data[].name | string | null | Event display name (canonical). |
data[].label | string | null | Deprecated alias of `name`; will be removed in the next API version. |
data[].wikidata_id | string | null | Wikidata QID when linked. |
data[].event_year | string | null | Edition year, when the event is an edition. |
data[].event_domain | string | null | Coarse domain: sport | policy | other. |
data[].event_type | string | null | Granular type: conflict | election | disaster | sports | summit | conference | festival | observance | ceremony | other. |
data[].parent_id | integer | null | Parent (franchise) event id, when an edition. |
data[].children_count | integer | null | Number of child events. |
data[].article_count | integer | null | Distinct articles mentioning the event. |
data[].has_timeline | boolean | null | True when a pre-generated narrative timeline artifact exists. |
data[].beat_count | integer | null | Beats in the timeline artifact (0 when none). |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/events/search?q=election"
import requests
r = requests.get(
"https://api.pressroom.news/v1/events/search",
headers={"X-API-Key": PRESSROOM_KEY},
params={"q": "election"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/events/search?q=election", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Canonical event profile GET /v1/events/{eid}
The canonical event profile: identity, dates, franchise/edition hierarchy, coverage stats, timeline availability, and cross-referenced Emergence threads.
Returns the EventProfile object.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
eid path | integer | required | — | Canonical event id. |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | EventProfile | The endpoint's payload. |
data.object | string | null | Object type discriminator: always "event". |
data.id | integer | null | Canonical event id. |
data.kind | string | null | Always 'event'. |
data.name | string | null | Event display label. |
data.event_domain | string | null | Coarse domain: sport | policy | other. |
data.event_type | string | null | Granular event type. |
data.event_year | string | null | Edition year, when applicable. |
data.event_date | object | null | Known event dates {start, end, precision}. |
data.identity | object | null | Identity block {resolved, wikidata_id}. |
data.description | string | null | Event description, when available. |
data.hierarchy | EventHierarchy | null | Franchise/edition hierarchy. |
data.hierarchy.role | string | null | franchise (has editions) | child (an edition/sub-event) | flat. |
data.hierarchy.parent | object | null | The parent event {id, name, event_year}, when any. |
data.hierarchy.children | array of object | null | Direct child events {id, name, event_year, event_domain}. |
data.hierarchy.children_count | integer | null | Number of direct children. |
data.stats | object | null | Coverage stats {article_count, mention_count, first_seen, last_seen}. |
data.timeline | object | null | Timeline availability {has_timeline, beat_count}. |
data.related_threads | array of RelatedThread | null | Emergence threads covering this happening (cross-reference only). |
data.related_threads[].id | integer | null | Emergence thread id (canonical). |
data.related_threads[].thread_id | integer | null | Deprecated alias of `id`; will be removed in the next API version. |
data.related_threads[].name | string | null | Thread label surface (canonical). |
data.related_threads[].label | string | null | Deprecated alias of `name`; will be removed in the next API version. |
data.related_threads[].detector | string | null | Detector that raised the thread. |
data.related_threads[].kind | string | null | Thread kind (event | topic). |
data.related_threads[].state | string | null | Thread lifecycle state (watch | dormant | …). |
data.related_threads[].link_basis | string | null | Why the thread was linked to the event. |
data.related_threads[].note | string | null | Cross-reference caveat. |
data.note | string | null | Scope note (clustering is owned by Emergence). |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/events/174"
import requests
r = requests.get(
"https://api.pressroom.news/v1/events/174",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/events/174", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Articles mentioning an event GET /v1/events/{eid}/articles
Paginated articles mentioning the event, newest first, each with mention count and provenance.
Returns the article list with pagination meta.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
eid path | integer | required | — | Canonical event id. |
page query | integer | optional | 1 | Page number (1-based). |
page_size query | integer | optional | 50 | Items per page (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of ArticleItem | The endpoint's payload. |
data[].article_id | integer | null | Corpus article id. |
data[].headline | string | null | Article headline. |
data[].dek | string | null | Article dek / standfirst, when extracted. |
data[].language | string | null | Detected article language (ISO code). |
data[].mention_count | integer | null | How many times the queried entity is mentioned in this article. |
data[].provenance | Provenance | null | Provenance of the article (source, URL, extraction record). |
data[].provenance.article_id | integer | null | Corpus article id the claim came from. |
data[].provenance.headline | string | null | Headline of the source article. |
data[].provenance.source_id | string | null | Registry id of the publishing source. |
data[].provenance.source_name | string | null | Display name of the publishing source. |
data[].provenance.source_url | string | null | Canonical URL of the source article. |
data[].provenance.extraction_method | string | null | Extractor that captured the article (trafilatura, playwright, …). |
data[].provenance.extracted_at | string | null | UTC timestamp of extraction. |
data[].provenance.date_published_utc | string | null | Publisher-stated publication time (UTC). |
data[].provenance.word_count | integer | null | Extracted body word count. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/events/174/articles"
import requests
r = requests.get(
"https://api.pressroom.news/v1/events/174/articles",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/events/174/articles", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Event coverage timeseries + by-source GET /v1/events/{eid}/coverage
Mention timeseries (articles + mentions per bucket) and the top publishing sources for the event.
Returns the EventCoverage object.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
eid path | integer | required | — | Canonical event id. |
bucket query | string | optional | "month" | Bucket granularity: day | week | month (default month). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | EventCoverage | The endpoint's payload. |
data.id | integer | null | Canonical event id. |
data.bucket | string | null | Bucket granularity: day | week | month. |
data.method | string | null | How the series was computed. |
data.timeseries | array of SeriesBucket | null | Articles + mentions per time bucket. |
data.timeseries[].bucket | string | null | Bucket key (YYYY-MM-DD day, YYYY-Www week, or YYYY-MM month). |
data.timeseries[].articles | integer | null | Distinct articles in the bucket. |
data.timeseries[].mentions | integer | number | null | Total mentions in the bucket (event coverage only). |
data.by_source | array of SourceBreakdown | null | Top publishing sources. |
data.by_source[].source | string | null | Source display name. |
data.by_source[].articles | integer | null | Distinct articles from this source in the window. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/events/174/coverage"
import requests
r = requests.get(
"https://api.pressroom.news/v1/events/174/coverage",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/events/174/coverage", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Emergence threads covering this event (read-only cross-reference) GET /v1/events/{eid}/threads
Emergence threads (ADR-057) clustering the same happening, matched on label/anchor overlap — a read-only cross-reference, never a merge.
Returns up to 5 linked threads.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
eid path | integer | required | — | Canonical event id. |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of RelatedThread | The endpoint's payload. |
data[].id | integer | null | Emergence thread id (canonical). |
data[].thread_id | integer | null | Deprecated alias of `id`; will be removed in the next API version. |
data[].name | string | null | Thread label surface (canonical). |
data[].label | string | null | Deprecated alias of `name`; will be removed in the next API version. |
data[].detector | string | null | Detector that raised the thread. |
data[].kind | string | null | Thread kind (event | topic). |
data[].state | string | null | Thread lifecycle state (watch | dormant | …). |
data[].link_basis | string | null | Why the thread was linked to the event. |
data[].note | string | null | Cross-reference caveat. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/events/174/threads"
import requests
r = requests.get(
"https://api.pressroom.news/v1/events/174/threads",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/events/174/threads", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Deterministic per-event narrative timeline (beats + provenance) GET /v1/events/{eid}/timeline
Full event-arc timeline: gap-clustered beats (representative + secondary headlines with article_id citations, verbatim actor-action lines with sentence provenance, quotes), an UNDATED shelf and a What's-next tail — served from pre-generated artifacts. When no artifact exists, a degraded DB-derived monthly digest is returned with status='fallback'.
Returns the EventTimeline artifact.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
eid path | integer | required | — | Canonical event id. |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | EventTimeline | The endpoint's payload. |
data.schema | string | null | Artifact schema version. |
data.status | string | null | 'fallback' marks the degraded DB-derived timeline; absent/other for the full pre-generated artifact. |
data.method | string | null | How the timeline was generated. |
data.event_id | integer | null | Canonical event id. |
data.name | string | null | Event display name (canonical). |
data.label | string | null | Deprecated alias of `name`; will be removed in the next API version. |
data.beats | array of object | null | Chronological beats: representative + secondary headlines with article_id citations; the full artifact adds verbatim actor-action lines and quotes with provenance. |
data.stats | object | null | Timeline aggregates. |
data.note | string | null | Honesty note for fallback timelines. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/events/174/timeline"
import requests
r = requests.get(
"https://api.pressroom.news/v1/events/174/timeline",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/events/174/timeline", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Topics
List curated topics GET /v1/topics
The curated topic overlay: every topic with its keywords, aliases, mapped sections, and article count.
Returns the full topic list.
Parameters
No parameters (beyond the auth header).
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of Topic | The endpoint's payload. |
data[].object | string | null | Object type discriminator: always "topic". |
data[].id | string | null | Canonical topic id (same value as `slug`, which remains the URL path key). |
data[].name | string | null | Topic display name (canonical). |
data[].slug | string | null | Stable topic slug — the URL path key (same value as `id`). |
data[].label | string | null | Deprecated alias of `name`; will be removed in the next API version. |
data[].source | string | null | Where the topic came from (curated). |
data[].article_count | integer | null | Articles matched to the topic. |
data[].keywords | array of any | null | Matching keywords. |
data[].aliases | array of any | null | Alias surfaces. |
data[].sections | array of any | null | Publisher sections mapped to the topic. |
data[].updated_at | string | null | When the topic membership was last materialised. |
data[].stats | object | null | Coverage stats (topic profile only). |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/topics"
import requests
r = requests.get(
"https://api.pressroom.news/v1/topics",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/topics", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Hybrid topic search (curated + keyword fallback) GET /v1/topics/search
Matches the query against curated topics and, in parallel, runs a free-form keyword scan over headlines.
Returns curated matches plus the keyword fallback with a sample of matching articles.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
q query | string | required | — | Topic name or free-form keyword query. |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | TopicSearchResult | The endpoint's payload. |
data.query | string | null | The search query. |
data.matched_curated | array of Topic | null | Curated topics matching the query. |
data.matched_curated[].object | string | null | Object type discriminator: always "topic". |
data.matched_curated[].id | string | null | Canonical topic id (same value as `slug`, which remains the URL path key). |
data.matched_curated[].name | string | null | Topic display name (canonical). |
data.matched_curated[].slug | string | null | Stable topic slug — the URL path key (same value as `id`). |
data.matched_curated[].label | string | null | Deprecated alias of `name`; will be removed in the next API version. |
data.matched_curated[].source | string | null | Where the topic came from (curated). |
data.matched_curated[].article_count | integer | null | Articles matched to the topic. |
data.matched_curated[].keywords | array of any | null | Matching keywords. |
data.matched_curated[].aliases | array of any | null | Alias surfaces. |
data.matched_curated[].sections | array of any | null | Publisher sections mapped to the topic. |
data.matched_curated[].updated_at | string | null | When the topic membership was last materialised. |
data.matched_curated[].stats | object | null | Coverage stats (topic profile only). |
data.keyword_fallback | object | null | Free-form keyword result: {query, article_count, sample[…]}. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/topics/search?q=election"
import requests
r = requests.get(
"https://api.pressroom.news/v1/topics/search",
headers={"X-API-Key": PRESSROOM_KEY},
params={"q": "election"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/topics/search?q=election", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Curated topic profile GET /v1/topics/{slug}
One curated topic with its keywords, aliases, sections, and coverage stats.
Returns the Topic object.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
slug path | string | required | — | Topic slug (lowercase letters, digits, hyphens). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | Topic | The endpoint's payload. |
data.object | string | null | Object type discriminator: always "topic". |
data.id | string | null | Canonical topic id (same value as `slug`, which remains the URL path key). |
data.name | string | null | Topic display name (canonical). |
data.slug | string | null | Stable topic slug — the URL path key (same value as `id`). |
data.label | string | null | Deprecated alias of `name`; will be removed in the next API version. |
data.source | string | null | Where the topic came from (curated). |
data.article_count | integer | null | Articles matched to the topic. |
data.keywords | array of any | null | Matching keywords. |
data.aliases | array of any | null | Alias surfaces. |
data.sections | array of any | null | Publisher sections mapped to the topic. |
data.updated_at | string | null | When the topic membership was last materialised. |
data.stats | object | null | Coverage stats (topic profile only). |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/topics/artificial-intelligence"
import requests
r = requests.get(
"https://api.pressroom.news/v1/topics/artificial-intelligence",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/topics/artificial-intelligence", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Articles under a topic GET /v1/topics/{slug}/articles
Paginated articles matched to the topic, newest first, each with provenance.
Returns the article list with pagination meta.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
slug path | string | required | — | Topic slug (lowercase letters, digits, hyphens). |
page query | integer | optional | 1 | Page number (1-based). |
page_size query | integer | optional | 50 | Items per page (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of ArticleItem | The endpoint's payload. |
data[].article_id | integer | null | Corpus article id. |
data[].headline | string | null | Article headline. |
data[].dek | string | null | Article dek / standfirst, when extracted. |
data[].language | string | null | Detected article language (ISO code). |
data[].mention_count | integer | null | How many times the queried entity is mentioned in this article. |
data[].provenance | Provenance | null | Provenance of the article (source, URL, extraction record). |
data[].provenance.article_id | integer | null | Corpus article id the claim came from. |
data[].provenance.headline | string | null | Headline of the source article. |
data[].provenance.source_id | string | null | Registry id of the publishing source. |
data[].provenance.source_name | string | null | Display name of the publishing source. |
data[].provenance.source_url | string | null | Canonical URL of the source article. |
data[].provenance.extraction_method | string | null | Extractor that captured the article (trafilatura, playwright, …). |
data[].provenance.extracted_at | string | null | UTC timestamp of extraction. |
data[].provenance.date_published_utc | string | null | Publisher-stated publication time (UTC). |
data[].provenance.word_count | integer | null | Extracted body word count. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/topics/artificial-intelligence/articles"
import requests
r = requests.get(
"https://api.pressroom.news/v1/topics/artificial-intelligence/articles",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/topics/artificial-intelligence/articles", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Topic coverage timeseries + breakdowns GET /v1/topics/{slug}/coverage
Article counts for the topic per time bucket, with source / geography / language breakdowns over the window.
Returns the coverage series and breakdowns.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
slug path | string | required | — | Topic slug (lowercase letters, digits, hyphens). |
date_from query | string | null | optional | — | Window start, ISO YYYY-MM-DD (default: 90 days before date_to; max window 1825 days). |
date_to query | string | null | optional | — | Window end, ISO YYYY-MM-DD (default: today, UTC). |
bucket query | string | optional | "day" | Bucket granularity: day | week | month (default day). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | TopicCoverage | The endpoint's payload. |
data.slug | string | null | The topic slug. |
data.bucket | string | null | Bucket granularity: day | week | month. |
data.window | object | null | Resolved date window {from, to}. |
data.total_articles | integer | null | Distinct articles in the window. |
data.series | array of object | null | Article counts per time bucket. |
data.by_source | array of object | null | Breakdown by publishing source. |
data.by_geography | array of object | null | Breakdown by source geography. |
data.by_language | array of object | null | Breakdown by article language. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/topics/artificial-intelligence/coverage"
import requests
r = requests.get(
"https://api.pressroom.news/v1/topics/artificial-intelligence/coverage",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/topics/artificial-intelligence/coverage", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Top co-occurring people / orgs / locations GET /v1/topics/{slug}/entities
The entities most covered under the topic, per kind, ranked by distinct articles.
Returns top people, organisations, and locations.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
slug path | string | required | — | Topic slug (lowercase letters, digits, hyphens). |
limit query | integer | optional | 15 | Max entities per kind (default 15, max 50). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | TopicEntities | The endpoint's payload. |
data.slug | string | null | The topic slug. |
data.people | array of any | null | Top people under the topic. |
data.organisations | array of any | null | Top organisations under the topic. |
data.locations | array of any | null | Top locations under the topic. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/topics/artificial-intelligence/entities"
import requests
r = requests.get(
"https://api.pressroom.news/v1/topics/artificial-intelligence/entities",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/topics/artificial-intelligence/entities", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Entities (people · organisations · locations)
People affiliated with an organisation (employer link) GET /v1/organisations/{eid}/people
People linked to the organisation through the normalised employer relation, highest link-confidence first.
Returns the affiliated people with link method and confidence.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
eid path | integer | required | — | Canonical organisation id. |
page query | integer | optional | 1 | Page number (1-based). |
page_size query | integer | optional | 50 | Items per page (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of OrgPerson | The endpoint's payload. |
data[].id | integer | null | Canonical person id. |
data[].name | string | null | Canonical person name. |
data[].title | string | null | Current title, when known. |
data[].wikidata_id | string | null | Wikidata QID when resolved. |
data[].employer_text | string | null | The employer surface the link was made from. |
data[].link_method | string | null | How the employer was matched (exact, acronym, …). |
data[].confidence | integer | number | null | Employer-link confidence in [0, 1]. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/organisations/174/people"
import requests
r = requests.get(
"https://api.pressroom.news/v1/organisations/174/people",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/organisations/174/people", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Quotes attributed to a person GET /v1/people/{eid}/quotes
Quotes attributed to the person (canonical entity linkage plus legacy attribution rows), newest first, each with provenance.
Returns the quote list with pagination meta.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
eid path | integer | required | — | Canonical person id. |
page query | integer | optional | 1 | Page number (1-based). |
page_size query | integer | optional | 50 | Items per page (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of Quote | The endpoint's payload. |
data[].object | string | null | Object type discriminator: always "quote". |
data[].id | integer | null | Corpus quote id (canonical). |
data[].quote_id | integer | null | Deprecated alias of `id`; will be removed in the next API version. |
data[].text | string | null | Verbatim quote text. |
data[].verb | string | null | Attribution verb (said, told, announced, …). |
data[].type | string | null | Quote type: direct | indirect. |
data[].confidence | integer | number | null | Extraction/attribution confidence in [0, 1]. |
data[].speaker | Speaker | null | Resolved speaker (absent on person-scoped quote lists, where the person is the request subject). |
data[].speaker.kind | string | null | Speaker entity kind: person | org | location; null when unresolved. |
data[].speaker.entity_id | integer | null | Canonical entity id of the speaker (per kind), when resolved. |
data[].speaker.person_id | integer | null | Legacy person id linkage (kept for backward compatibility). |
data[].speaker.name | string | null | Canonical name of the resolved speaker entity. |
data[].speaker.speaker_text | string | null | The verbatim speaker surface as written in the article. |
data[].speaker.resolved | boolean | null | True when the speaker is linked to ANY canonical entity. |
data[].provenance | Provenance | null | Source article the quote was extracted from. |
data[].provenance.article_id | integer | null | Corpus article id the claim came from. |
data[].provenance.headline | string | null | Headline of the source article. |
data[].provenance.source_id | string | null | Registry id of the publishing source. |
data[].provenance.source_name | string | null | Display name of the publishing source. |
data[].provenance.source_url | string | null | Canonical URL of the source article. |
data[].provenance.extraction_method | string | null | Extractor that captured the article (trafilatura, playwright, …). |
data[].provenance.extracted_at | string | null | UTC timestamp of extraction. |
data[].provenance.date_published_utc | string | null | Publisher-stated publication time (UTC). |
data[].provenance.word_count | integer | null | Extracted body word count. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/people/174/quotes"
import requests
r = requests.get(
"https://api.pressroom.news/v1/people/174/quotes",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/people/174/quotes", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Resolve an ambiguous surface to candidates GET /v1/{kind}/disambiguate
Real candidate ranking for an ambiguous surface form: matched against canonical names, alias tables, and whole-token containment; ranked by resolution then coverage, each with a one-line distinguishing context.
Returns up to 10 candidates, best first.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
kind path | string | required | — | Entity kind: people | organisations | locations. |
surface query | string | required | — | The ambiguous surface form to resolve (e.g. 'Modi', 'Congress'). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of DisambiguationCandidate | The endpoint's payload. |
data[].id | integer | null | Canonical entity id of the candidate. |
data[].name | string | null | Canonical name of the candidate. |
data[].wikidata_id | string | null | Wikidata QID when resolved. |
data[].resolved | boolean | null | True when identity-resolved. |
data[].status | string | null | Identity-resolution status. |
data[].article_count | integer | null | Distinct articles mentioning the candidate. |
data[].context | string | null | One-line human hint distinguishing same-named candidates (title + employer, org type + country, admin region). |
data[].match | string | null | How the surface matched: exact_name | alias | name_token. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/people/disambiguate?surface=example"
import requests
r = requests.get(
"https://api.pressroom.news/v1/people/disambiguate",
headers={"X-API-Key": PRESSROOM_KEY},
params={"surface": "example"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/people/disambiguate?surface=example", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Search entities by name / alias GET /v1/{kind}/search
Substring search over canonical entity names, ranked by aboutness (coverage centrality); location duplicates are QID-deduped and likely stubs of resolved entities are flagged and ranked last.
Returns matching entities with resolution status.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
kind path | string | required | — | Entity kind: people | organisations | locations. |
q query | string | required | — | Substring query over the canonical name. |
page query | integer | optional | 1 | Page number (1-based). |
page_size query | integer | optional | 50 | Items per page (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of EntitySearchItem | The endpoint's payload. |
data[].id | integer | null | Canonical entity id. |
data[].name | string | null | Canonical name. |
data[].resolved | boolean | null | True when identity-resolved (QID/LEI/geo). |
data[].wikidata_id | string | null | Wikidata QID when resolved. |
data[].status | string | null | Identity-resolution status. |
data[].possible_duplicate | boolean | null | Set when this unresolved row looks like a stub of a resolved entity it co-occurs with (e.g. 'Modi' vs 'Narendra Modi'); such rows rank last. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/people/search?q=election"
import requests
r = requests.get(
"https://api.pressroom.news/v1/people/search",
headers={"X-API-Key": PRESSROOM_KEY},
params={"q": "election"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/people/search?q=election", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Canonical entity profile GET /v1/{kind}/{eid}
The canonical profile: identity resolution (Wikidata QID / LEI / geo status), per-kind attributes, aliases, and corpus coverage stats including aboutness centrality.
Returns the EntityProfile object.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
kind path | string | required | — | Entity kind: people | organisations | locations. |
eid path | integer | required | — | Canonical entity id within the kind. |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | EntityProfile | The endpoint's payload. |
data.object | string (enum) | null | Object type discriminator: person | organisation | location (the singular of the requested kind). |
data.id | integer | null | Canonical entity id (scoped to its kind). |
data.kind | string | null | Entity kind: people | organisations | locations. |
data.name | string | null | Canonical display name. |
data.identity | EntityIdentity | null | Identity-resolution block. |
data.identity.resolved | boolean | null | True when bound to an external identity (Wikidata QID, LEI, or a resolved geo record). |
data.identity.wikidata_id | string | null | Wikidata QID (null when unresolved or identity-suppressed). |
data.identity.lei_code | string | null | Legal Entity Identifier (organisations only). |
data.identity.status | string | null | Resolution status from the identity pipeline (resolved | not_found | pending | …). |
data.attributes | object | null | Per-kind attributes: people carry title/employer/bio/social links; organisations carry type/sector/country/website; locations carry type/coordinates/admin region/population. |
data.aliases | array of any | null | Known aliases and alternate surfaces. |
data.stats | EntityStats | null | Corpus coverage statistics. |
data.stats.article_count | integer | null | Distinct articles mentioning the entity. |
data.stats.mention_count | integer | number | null | Total mentions across all articles. |
data.stats.aboutness_total | integer | number | null | Sum of per-article aboutness weight (a headline subject weighs ~5x a body name-drop) — the centrality signal. |
data.stats.subject_article_count | integer | null | Articles that are ABOUT the entity (aboutness weight >= 2.0), vs merely mentioning it. |
data.stats.first_seen | string | null | Earliest publication date mentioning the entity. |
data.stats.last_seen | string | null | Latest publication date mentioning the entity. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/people/174"
import requests
r = requests.get(
"https://api.pressroom.news/v1/people/174",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/people/174", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Articles mentioning the entity GET /v1/{kind}/{eid}/articles
Paginated articles mentioning the entity, newest first, each with mention count and provenance (locations sharing a QID are collapsed).
Returns the article list with pagination meta.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
kind path | string | required | — | Entity kind: people | organisations | locations. |
eid path | integer | required | — | Canonical entity id within the kind. |
starting_after query | integer | null | optional | — | Optional cursor pagination: only articles with id strictly below this article id, ordered id-descending (the default newest-first date order is not id-monotone, so cursor requests switch to id order to stay sound). page/page_size keep working unchanged without it. When passed, meta.next_cursor carries the last id of the page (null = exhausted; has_more == next_cursor is not null). Start a walk with any id above the newest article. |
page query | integer | optional | 1 | Page number (1-based). |
page_size query | integer | optional | 50 | Items per page (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of ArticleItem | The endpoint's payload. |
data[].article_id | integer | null | Corpus article id. |
data[].headline | string | null | Article headline. |
data[].dek | string | null | Article dek / standfirst, when extracted. |
data[].language | string | null | Detected article language (ISO code). |
data[].mention_count | integer | null | How many times the queried entity is mentioned in this article. |
data[].provenance | Provenance | null | Provenance of the article (source, URL, extraction record). |
data[].provenance.article_id | integer | null | Corpus article id the claim came from. |
data[].provenance.headline | string | null | Headline of the source article. |
data[].provenance.source_id | string | null | Registry id of the publishing source. |
data[].provenance.source_name | string | null | Display name of the publishing source. |
data[].provenance.source_url | string | null | Canonical URL of the source article. |
data[].provenance.extraction_method | string | null | Extractor that captured the article (trafilatura, playwright, …). |
data[].provenance.extracted_at | string | null | UTC timestamp of extraction. |
data[].provenance.date_published_utc | string | null | Publisher-stated publication time (UTC). |
data[].provenance.word_count | integer | null | Extracted body word count. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/people/174/articles"
import requests
r = requests.get(
"https://api.pressroom.news/v1/people/174/articles",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/people/174/articles", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Mention timeseries + breakdowns GET /v1/{kind}/{eid}/coverage
Distinct-article counts for the entity per time bucket with source / geography / language breakdowns (locations sharing a QID are collapsed).
Returns the coverage series and breakdowns for the window.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
kind path | string | required | — | Entity kind: people | organisations | locations. |
eid path | integer | required | — | Canonical entity id within the kind. |
date_from query | string | null | optional | — | Window start, ISO YYYY-MM-DD (default: 90 days before date_to; max window 1825 days). |
date_to query | string | null | optional | — | Window end, ISO YYYY-MM-DD (default: today, UTC). |
bucket query | string | optional | "day" | Bucket granularity: day | week | month (default day). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | EntityCoverage | The endpoint's payload. |
data.entity_id | integer | null | The queried entity id. |
data.kind | string | null | Entity kind. |
data.bucket | string | null | Bucket granularity: day | week | month. |
data.window | Window | null | Resolved date window. |
data.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
data.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
data.total_articles | integer | null | Distinct articles in the window. |
data.series | array of SeriesBucket | null | Article counts per time bucket. |
data.series[].bucket | string | null | Bucket key (YYYY-MM-DD day, YYYY-Www week, or YYYY-MM month). |
data.series[].articles | integer | null | Distinct articles in the bucket. |
data.series[].mentions | integer | number | null | Total mentions in the bucket (event coverage only). |
data.by_source | array of SourceBreakdown | null | Breakdown by publishing source. |
data.by_source[].source | string | null | Source display name. |
data.by_source[].articles | integer | null | Distinct articles from this source in the window. |
data.by_geography | array of GeographyBreakdown | null | Breakdown by source geography. |
data.by_geography[].geography | string | null | Source primary geography. |
data.by_geography[].articles | integer | null | Distinct articles from sources in this geography. |
data.by_language | array of LanguageBreakdown | null | Breakdown by article language. |
data.by_language[].language | string | null | Article language (ISO code). |
data.by_language[].articles | integer | null | Distinct articles in this language. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/people/174/coverage"
import requests
r = requests.get(
"https://api.pressroom.news/v1/people/174/coverage",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/people/174/coverage", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Identity-change history (from the change journals) GET /v1/{kind}/{eid}/history
How the entity's identity changed over time, merged chronologically from the change journals (audit_decisions + org cascade / location recovery logs).
Returns the change events with before/after state.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
kind path | string | required | — | Entity kind: people | organisations | locations. |
eid path | integer | required | — | Canonical entity id within the kind. |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | EntityHistory | The endpoint's payload. |
data.entity_id | integer | null | The queried entity id. |
data.kind | string | null | Entity kind. |
data.count | integer | null | Number of history events. |
data.events | array of HistoryEvent | null | Chronological change events. |
data.events[].ts | string | null | When the change was recorded (UTC). |
data.events[].source | string | null | Journal of record: audit_decisions | org_cascade_log | location_recovery_log. |
data.events[].action | string | null | What happened (action taken / stage:outcome / status transition). |
data.events[].before | any | State before the change (journal-specific JSON). |
data.events[].after | any | State after the change (journal-specific JSON). |
data.note | string | null | Scope of the journals backing this history. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/people/174/history"
import requests
r = requests.get(
"https://api.pressroom.news/v1/people/174/history",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/people/174/history", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Deterministic sentiment over time GET /v1/{kind}/{eid}/sentiment-trend
Lexicon-based (deterministic, no LLM) sentiment of the entity's coverage per bucket, plus window aggregates.
Returns the sentiment series and overall counts.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
kind path | string | required | — | Entity kind: people | organisations | locations. |
eid path | integer | required | — | Canonical entity id within the kind. |
date_from query | string | null | optional | — | Window start, ISO YYYY-MM-DD (default: 90 days before date_to; max window 1825 days). |
date_to query | string | null | optional | — | Window end, ISO YYYY-MM-DD (default: today, UTC). |
bucket query | string | optional | "month" | Bucket granularity: day | week | month (default month). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | SentimentTrend | The endpoint's payload. |
data.entity_id | integer | null | The queried entity id. |
data.kind | string | null | Entity kind. |
data.bucket | string | null | Bucket granularity: day | week | month. |
data.window | Window | null | Resolved date window. |
data.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
data.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
data.overall | object | null | Window aggregate: avg_compound, scored_articles, positive/negative/neutral counts. |
data.series | array of object | null | Per-bucket sentiment aggregates. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/people/174/sentiment-trend"
import requests
r = requests.get(
"https://api.pressroom.news/v1/people/174/sentiment-trend",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/people/174/sentiment-trend", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Relationships
Top co-mentioned people / organisations / locations GET /v1/{kind}/{eid}/relationships
The entity's co-occurrence neighbourhood: for each requested target kind, the entities most often sharing articles with it, with co-counts, salience, and first/last co-coverage dates, plus asserted typed edges from the Wikidata-grounded graph.
Returns a Relationships object keyed by target kind.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
kind path | string | required | — | Entity kind: people | organisations | locations. |
eid path | integer | required | — | Canonical entity id within the kind. |
target query | string | optional | "people,organisations,locations" | Comma-separated target kinds to include (any of people, organisations, locations). |
limit query | integer | optional | 20 | Max related entities per target kind (default 20, max 100). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | Relationships | The endpoint's payload. |
data.entity_id | integer | null | The source entity id. |
data.kind | string | null | Source entity kind. |
data.source_article_count | integer | null | Articles mentioning the source entity (the salience denominator). |
data.people | array of RelatedEntity | null | Top co-mentioned people. |
data.people[].id | integer | null | Canonical entity id. |
data.people[].name | string | null | Canonical name. |
data.people[].wikidata_id | string | null | Wikidata QID when resolved. |
data.people[].co_count | integer | null | Distinct articles shared with the source entity. |
data.people[].first_seen | string | null | Earliest shared article date. |
data.people[].last_seen | string | null | Latest shared article date. |
data.people[].salience | integer | number | null | co_count / source entity's article count — how central this relationship is to the source's coverage. |
data.people[].possible_duplicate | boolean | null | Set when this row looks like an unresolved stub of another entity in the list (ranked last). |
data.organisations | array of RelatedEntity | null | Top co-mentioned organisations. |
data.organisations[].id | integer | null | Canonical entity id. |
data.organisations[].name | string | null | Canonical name. |
data.organisations[].wikidata_id | string | null | Wikidata QID when resolved. |
data.organisations[].co_count | integer | null | Distinct articles shared with the source entity. |
data.organisations[].first_seen | string | null | Earliest shared article date. |
data.organisations[].last_seen | string | null | Latest shared article date. |
data.organisations[].salience | integer | number | null | co_count / source entity's article count — how central this relationship is to the source's coverage. |
data.organisations[].possible_duplicate | boolean | null | Set when this row looks like an unresolved stub of another entity in the list (ranked last). |
data.locations | array of RelatedEntity | null | Top co-mentioned locations (QID-deduped). |
data.locations[].id | integer | null | Canonical entity id. |
data.locations[].name | string | null | Canonical name. |
data.locations[].wikidata_id | string | null | Wikidata QID when resolved. |
data.locations[].co_count | integer | null | Distinct articles shared with the source entity. |
data.locations[].first_seen | string | null | Earliest shared article date. |
data.locations[].last_seen | string | null | Latest shared article date. |
data.locations[].salience | integer | number | null | co_count / source entity's article count — how central this relationship is to the source's coverage. |
data.locations[].possible_duplicate | boolean | null | Set when this row looks like an unresolved stub of another entity in the list (ranked last). |
data.typed | array of object | null | Asserted TYPED relationships from entity_edges (Wikidata-grounded), both directions: {direction, predicate, predicate_qid, confidence, method, target|source}. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/people/174/relationships"
import requests
r = requests.get(
"https://api.pressroom.news/v1/people/174/relationships",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/people/174/relationships", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Relationship graph
All LITIGATION edges for an entity, dated, with assertion_status GET /v1/graph/entities/{entity_id}/litigation
The entity's LITIGATION edges with dates and assertion_status (asserted vs alleged — the allegation firewall).
Returns the entity plus the paginated edge list.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
entity_id path | integer | required | — | Canonical entity id. |
page query | integer | optional | 1 | Page number (1-based). |
page_size query | integer | optional | 50 | Items per page (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | GraphNeighbors | The endpoint's payload. |
data.entity | GraphEntity | null | The queried entity. |
data.entity.id | integer | null | Canonical entity id. |
data.entity.kind | string | null | Entity kind. |
data.entity.name | string | null | Canonical name (canonical). |
data.entity.label | string | null | Deprecated alias of `name`; will be removed in the next API version. |
data.edges | array of GraphEdge | null | Edges touching the entity (in + out). |
data.edges[].edge_type | string | null | Typed relation (EMPLOYMENT, OWNERSHIP, LITIGATION, KINSHIP, …). |
data.edges[].src_entity_id | integer | null | Source entity id. |
data.edges[].dst_entity_id | integer | null | Destination entity id. |
data.edges[].confidence | integer | number | null | Gate-passed extraction confidence. |
data.edges[].assertion_status | string | null | Assertion status (asserted vs alleged — the allegation firewall). |
data.edges[].is_current | any | Whether the relation is flagged current. |
data.edges[].valid_from | string | null | Temporal validity start, when stated. |
data.edges[].valid_to | string | null | Temporal validity end, when stated. |
data.edges[].evidence | any | Evidence spans (article + sentence + char-span). |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/graph/entities/174/litigation"
import requests
r = requests.get(
"https://api.pressroom.news/v1/graph/entities/174/litigation",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/graph/entities/174/litigation", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();All typed edges touching an entity (in + out), provenance-cited GET /v1/graph/entities/{entity_id}/neighbors
Every gate-passed typed edge touching the entity, both directions, each with evidence spans and confidence.
Returns the entity plus its paginated edge list.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
entity_id path | integer | required | — | Canonical entity id. |
current_only query | boolean | optional | false | only edges flagged is_current |
page query | integer | optional | 1 | Page number (1-based). |
page_size query | integer | optional | 50 | Items per page (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | GraphNeighbors | The endpoint's payload. |
data.entity | GraphEntity | null | The queried entity. |
data.entity.id | integer | null | Canonical entity id. |
data.entity.kind | string | null | Entity kind. |
data.entity.name | string | null | Canonical name (canonical). |
data.entity.label | string | null | Deprecated alias of `name`; will be removed in the next API version. |
data.edges | array of GraphEdge | null | Edges touching the entity (in + out). |
data.edges[].edge_type | string | null | Typed relation (EMPLOYMENT, OWNERSHIP, LITIGATION, KINSHIP, …). |
data.edges[].src_entity_id | integer | null | Source entity id. |
data.edges[].dst_entity_id | integer | null | Destination entity id. |
data.edges[].confidence | integer | number | null | Gate-passed extraction confidence. |
data.edges[].assertion_status | string | null | Assertion status (asserted vs alleged — the allegation firewall). |
data.edges[].is_current | any | Whether the relation is flagged current. |
data.edges[].valid_from | string | null | Temporal validity start, when stated. |
data.edges[].valid_to | string | null | Temporal validity end, when stated. |
data.edges[].evidence | any | Evidence spans (article + sentence + char-span). |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/graph/entities/174/neighbors"
import requests
r = requests.get(
"https://api.pressroom.news/v1/graph/entities/174/neighbors",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/graph/entities/174/neighbors", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Recursive OWNERSHIP closure up (owners) + down (holdings) GET /v1/graph/entities/{entity_id}/ownership
Walks OWNERSHIP edges recursively in both directions up to max_depth.
Returns the ownership tree: upward owners and downward holdings.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
entity_id path | integer | required | — | Canonical entity id. |
max_depth query | integer | optional | 5 | Maximum recursion depth (default 5, max 8). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | OwnershipTree | The endpoint's payload. |
data.entity | GraphEntity | null | The queried entity. |
data.entity.id | integer | null | Canonical entity id. |
data.entity.kind | string | null | Entity kind. |
data.entity.name | string | null | Canonical name (canonical). |
data.entity.label | string | null | Deprecated alias of `name`; will be removed in the next API version. |
data.owners | array of any | null | Upward ownership chain (who owns it). |
data.holdings | array of any | null | Downward closure (what it owns). |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/graph/entities/174/ownership"
import requests
r = requests.get(
"https://api.pressroom.news/v1/graph/entities/174/ownership",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/graph/entities/174/ownership", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();An entity's typed edges in chronological order (relationship evolution) GET /v1/graph/entities/{entity_id}/timeline
The entity's typed edges ordered by temporal validity (valid_from / as_of ascending) — how its relationships evolved.
Returns the entity plus the ordered edge list.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
entity_id path | integer | required | — | Canonical entity id. |
page query | integer | optional | 1 | Page number (1-based). |
page_size query | integer | optional | 50 | Items per page (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | GraphNeighbors | The endpoint's payload. |
data.entity | GraphEntity | null | The queried entity. |
data.entity.id | integer | null | Canonical entity id. |
data.entity.kind | string | null | Entity kind. |
data.entity.name | string | null | Canonical name (canonical). |
data.entity.label | string | null | Deprecated alias of `name`; will be removed in the next API version. |
data.edges | array of GraphEdge | null | Edges touching the entity (in + out). |
data.edges[].edge_type | string | null | Typed relation (EMPLOYMENT, OWNERSHIP, LITIGATION, KINSHIP, …). |
data.edges[].src_entity_id | integer | null | Source entity id. |
data.edges[].dst_entity_id | integer | null | Destination entity id. |
data.edges[].confidence | integer | number | null | Gate-passed extraction confidence. |
data.edges[].assertion_status | string | null | Assertion status (asserted vs alleged — the allegation firewall). |
data.edges[].is_current | any | Whether the relation is flagged current. |
data.edges[].valid_from | string | null | Temporal validity start, when stated. |
data.edges[].valid_to | string | null | Temporal validity end, when stated. |
data.edges[].evidence | any | Evidence spans (article + sentence + char-span). |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/graph/entities/174/timeline"
import requests
r = requests.get(
"https://api.pressroom.news/v1/graph/entities/174/timeline",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/graph/entities/174/timeline", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Shortest typed-relation path between two entities (bounded BFS) GET /v1/graph/path
Bounded breadth-first search over the typed graph.
Returns whether a path exists within max_depth, the hop count, and the path's edges in order.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
src query | integer | required | — | canonical entity id |
dst query | integer | required | — | canonical entity id |
max_depth query | integer | optional | 4 | Maximum BFS depth in edges (default 4, max 6). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | GraphPath | The endpoint's payload. |
data.src | GraphEntity | null | Path source entity. |
data.src.id | integer | null | Canonical entity id. |
data.src.kind | string | null | Entity kind. |
data.src.name | string | null | Canonical name (canonical). |
data.src.label | string | null | Deprecated alias of `name`; will be removed in the next API version. |
data.dst | GraphEntity | null | Path destination entity. |
data.dst.id | integer | null | Canonical entity id. |
data.dst.kind | string | null | Entity kind. |
data.dst.name | string | null | Canonical name (canonical). |
data.dst.label | string | null | Deprecated alias of `name`; will be removed in the next API version. |
data.found | boolean | null | True when a path exists within max_depth. |
data.hops | integer | null | Path length in edges (null when not found). |
data.edges | array of GraphEdge | null | The path's edges in order (empty when not found). |
data.edges[].edge_type | string | null | Typed relation (EMPLOYMENT, OWNERSHIP, LITIGATION, KINSHIP, …). |
data.edges[].src_entity_id | integer | null | Source entity id. |
data.edges[].dst_entity_id | integer | null | Destination entity id. |
data.edges[].confidence | integer | number | null | Gate-passed extraction confidence. |
data.edges[].assertion_status | string | null | Assertion status (asserted vs alleged — the allegation firewall). |
data.edges[].is_current | any | Whether the relation is flagged current. |
data.edges[].valid_from | string | null | Temporal validity start, when stated. |
data.edges[].valid_to | string | null | Temporal validity end, when stated. |
data.edges[].evidence | any | Evidence spans (article + sentence + char-span). |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/graph/path?src=1&dst=1"
import requests
r = requests.get(
"https://api.pressroom.news/v1/graph/path",
headers={"X-API-Key": PRESSROOM_KEY},
params={"src": 1, "dst": 1},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/graph/path?src=1&dst=1", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Geo, quotes & timelines
Geo-tagged locations within a radius GET /v1/locations/nearby
Geo-resolved locations within radius_km of a point, nearest first, with per-location coverage counts.
Returns the location list plus the query center.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
lat query | number | required | — | Latitude of the search center (-90 to 90). |
lon query | number | required | — | Longitude of the search center (-180 to 180). |
radius_km query | number | optional | 100 | Search radius in km (default 100, max 5000). |
limit query | integer | optional | 50 | Max locations returned (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | Nearby | The endpoint's payload. |
data.center | object | null | The query point {lat, lon}. |
data.radius_km | integer | number | null | Search radius in kilometres. |
data.count | integer | null | Locations returned. |
data.locations | array of NearbyLocation | null | Matching locations, nearest first. |
data.locations[].id | integer | null | Canonical location id. |
data.locations[].name | string | null | Canonical location name. |
data.locations[].lat | integer | number | null | Latitude. |
data.locations[].lon | integer | number | null | Longitude. |
data.locations[].distance_km | integer | number | null | Distance from the query point (km). |
data.locations[].article_count | integer | null | Distinct articles mentioning the location. |
data.meta | object | null | Suppression/aggregation notes. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/locations/nearby?lat=1.0&lon=1.0"
import requests
r = requests.get(
"https://api.pressroom.news/v1/locations/nearby",
headers={"X-API-Key": PRESSROOM_KEY},
params={"lat": 1.0, "lon": 1.0},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/locations/nearby?lat=1.0&lon=1.0", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Mentions aggregated into lat/lon cells GET /v1/map/heatmap
Location mentions in the window aggregated into rounded lat/lon cells for map rendering, optionally filtered by a headline/dek query.
Returns the cell grid with per-cell article counts.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
date_from query | string | null | optional | — | Window start, ISO YYYY-MM-DD (default: 90 days before date_to; max window 1825 days). |
date_to query | string | null | optional | — | Window end, ISO YYYY-MM-DD (default: today, UTC). |
q query | string | null | optional | — | Optional full-text filter over headline and dek. |
precision query | integer | optional | 1 | Cell rounding precision in decimal degrees (0-3; default 1 ≈ 11 km). |
limit query | integer | optional | 1000 | Max cells returned (default 1000, max 5000). |
include_regions query | boolean | optional | false | include country/admin1-level centroids in cells (default: excluded) |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | Heatmap | The endpoint's payload. |
data.window | Window | null | Resolved date window. |
data.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
data.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
data.query | string | null | The optional headline/dek filter applied. |
data.precision | integer | null | Cell rounding precision (decimal degrees). |
data.cells | array of HeatmapCell | null | Aggregated map cells. |
data.cells[].lat | integer | number | null | Cell centroid latitude. |
data.cells[].lon | integer | number | null | Cell centroid longitude. |
data.cells[].articles | integer | null | Distinct articles mentioning locations in the cell. |
data.meta | object | null | Aggregation notes: region-centroid inclusion and excluded counts. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/map/heatmap?q=election"
import requests
r = requests.get(
"https://api.pressroom.news/v1/map/heatmap",
headers={"X-API-Key": PRESSROOM_KEY},
params={"q": "election"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/map/heatmap?q=election", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Search quotes by text GET /v1/quotes/search
Substring search over verbatim quote text, newest first, optionally restricted to quotes with a resolved speaker.
Returns quotes with speaker resolution and full provenance.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
q query | string | required | — | Substring query over the verbatim quote text (min 2 chars). |
resolved_only query | boolean | optional | false | Only quotes whose speaker is linked to a canonical entity (person, organisation, or location metonym). |
starting_after query | integer | null | optional | — | Optional cursor pagination: only quotes with id strictly below this quote id, ordered id-descending (the default newest-first date order is not id-monotone, so cursor requests switch to id order to stay sound). page/page_size keep working unchanged without it. When passed, meta.next_cursor carries the last id of the page (null = exhausted; has_more == next_cursor is not null). Start a walk with any id above the newest quote. |
page query | integer | optional | 1 | Page number (1-based). |
page_size query | integer | optional | 50 | Items per page (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of Quote | The endpoint's payload. |
data[].object | string | null | Object type discriminator: always "quote". |
data[].id | integer | null | Corpus quote id (canonical). |
data[].quote_id | integer | null | Deprecated alias of `id`; will be removed in the next API version. |
data[].text | string | null | Verbatim quote text. |
data[].verb | string | null | Attribution verb (said, told, announced, …). |
data[].type | string | null | Quote type: direct | indirect. |
data[].confidence | integer | number | null | Extraction/attribution confidence in [0, 1]. |
data[].speaker | Speaker | null | Resolved speaker (absent on person-scoped quote lists, where the person is the request subject). |
data[].speaker.kind | string | null | Speaker entity kind: person | org | location; null when unresolved. |
data[].speaker.entity_id | integer | null | Canonical entity id of the speaker (per kind), when resolved. |
data[].speaker.person_id | integer | null | Legacy person id linkage (kept for backward compatibility). |
data[].speaker.name | string | null | Canonical name of the resolved speaker entity. |
data[].speaker.speaker_text | string | null | The verbatim speaker surface as written in the article. |
data[].speaker.resolved | boolean | null | True when the speaker is linked to ANY canonical entity. |
data[].provenance | Provenance | null | Source article the quote was extracted from. |
data[].provenance.article_id | integer | null | Corpus article id the claim came from. |
data[].provenance.headline | string | null | Headline of the source article. |
data[].provenance.source_id | string | null | Registry id of the publishing source. |
data[].provenance.source_name | string | null | Display name of the publishing source. |
data[].provenance.source_url | string | null | Canonical URL of the source article. |
data[].provenance.extraction_method | string | null | Extractor that captured the article (trafilatura, playwright, …). |
data[].provenance.extracted_at | string | null | UTC timestamp of extraction. |
data[].provenance.date_published_utc | string | null | Publisher-stated publication time (UTC). |
data[].provenance.word_count | integer | null | Extracted body word count. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/quotes/search?q=election"
import requests
r = requests.get(
"https://api.pressroom.news/v1/quotes/search",
headers={"X-API-Key": PRESSROOM_KEY},
params={"q": "election"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/quotes/search?q=election", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();A quote with full provenance + speaker GET /v1/quotes/{quote_id}
One quote as a first-class object: verbatim text, attribution verb and confidence, the resolved speaker entity, and the source article provenance.
Returns the Quote object.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
quote_id path | integer | required | — | Corpus quote id. |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | Quote | The endpoint's payload. |
data.object | string | null | Object type discriminator: always "quote". |
data.id | integer | null | Corpus quote id (canonical). |
data.quote_id | integer | null | Deprecated alias of `id`; will be removed in the next API version. |
data.text | string | null | Verbatim quote text. |
data.verb | string | null | Attribution verb (said, told, announced, …). |
data.type | string | null | Quote type: direct | indirect. |
data.confidence | integer | number | null | Extraction/attribution confidence in [0, 1]. |
data.speaker | Speaker | null | Resolved speaker (absent on person-scoped quote lists, where the person is the request subject). |
data.speaker.kind | string | null | Speaker entity kind: person | org | location; null when unresolved. |
data.speaker.entity_id | integer | null | Canonical entity id of the speaker (per kind), when resolved. |
data.speaker.person_id | integer | null | Legacy person id linkage (kept for backward compatibility). |
data.speaker.name | string | null | Canonical name of the resolved speaker entity. |
data.speaker.speaker_text | string | null | The verbatim speaker surface as written in the article. |
data.speaker.resolved | boolean | null | True when the speaker is linked to ANY canonical entity. |
data.provenance | Provenance | null | Source article the quote was extracted from. |
data.provenance.article_id | integer | null | Corpus article id the claim came from. |
data.provenance.headline | string | null | Headline of the source article. |
data.provenance.source_id | string | null | Registry id of the publishing source. |
data.provenance.source_name | string | null | Display name of the publishing source. |
data.provenance.source_url | string | null | Canonical URL of the source article. |
data.provenance.extraction_method | string | null | Extractor that captured the article (trafilatura, playwright, …). |
data.provenance.extracted_at | string | null | UTC timestamp of extraction. |
data.provenance.date_published_utc | string | null | Publisher-stated publication time (UTC). |
data.provenance.word_count | integer | null | Extracted body word count. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/quotes/359746"
import requests
r = requests.get(
"https://api.pressroom.news/v1/quotes/359746",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/quotes/359746", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Date-anchored coverage timeline GET /v1/{kind}/{eid}/timeline
Per-day coverage of the entity across the window: article counts plus each day's representative (longest) article with provenance.
Returns the EntityTimeline object, most recent day first.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
kind path | string | required | — | Entity kind: people | organisations | locations. |
eid path | integer | required | — | Canonical entity id within the kind. |
date_from query | string | null | optional | — | Window start, ISO YYYY-MM-DD (default: 90 days before date_to; max window 1825 days). |
date_to query | string | null | optional | — | Window end, ISO YYYY-MM-DD (default: today, UTC). |
limit query | integer | optional | 100 | Max days returned (default 100, max 365). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | EntityTimeline | The endpoint's payload. |
data.entity_id | integer | null | The queried entity id. |
data.kind | string | null | Entity kind. |
data.window | Window | null | Resolved date window. |
data.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
data.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
data.days | array of TimelineDay | null | Per-day coverage, most recent first. |
data.days[].date | string | null | The day (ISO YYYY-MM-DD). |
data.days[].article_count | integer | null | Distinct articles that day. |
data.days[].representative | object | null | The day's longest article: {article_id, headline, provenance}. |
data.note | string | null | Methodological caveats. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/people/174/timeline"
import requests
r = requests.get(
"https://api.pressroom.news/v1/people/174/timeline",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/people/174/timeline", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Certified depth cards
Paginated certified depth cards (story-state, PUBLISHED only) GET /v1/depth-cards
Certified, PUBLISHED-disposition depth cards minted by the story-state publisher, filterable by story unit, object class, and publication date.
Returns depth cards with full mint provenance, newest first.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
story_unit_id query | integer | null | optional | — | filter to one spine story unit |
object_class query | string | null | optional | — | filter object_class (e.g. DEATH_COUNT) |
base_class query | string | null | optional | — | filter coarse base_class |
date_from query | string | null | optional | — | publication_date >= (ISO date/datetime) |
date_to query | string | null | optional | — | publication_date <= (ISO date/datetime) |
page query | integer | optional | 1 | Page number (1-based). |
page_size query | integer | optional | 50 | Items per page (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of DepthCard | The endpoint's payload. |
data[].object | string | null | Object type discriminator: always "depth_card". |
data[].id | string | null | Stable card id (canonical). |
data[].card_id | string | null | Deprecated alias of `id`; will be removed in the next API version. |
data[].contract_version | string | null | Card contract version (depth_card_v1). |
data[].disposition | string | null | Always PUBLISHED (only published cards persist). |
data[].object_class | string | null | Typed object class (e.g. DEATH_COUNT). |
data[].base_class | string | null | Coarse base class. |
data[].claim | string | null | The card's claim text. |
data[].claimed_value | any | The typed claimed value (number, range, …). |
data[].unit | string | null | Unit of the claimed value (e.g. people). |
data[].story_unit_id | integer | null | Spine story unit the card belongs to, when linked. |
data[].minted_at | string | null | When the guarded writer minted the card. |
data[].provenance | DepthCardProvenance | null | Full mint provenance. |
data[].provenance.article_ids | any | All article ids backing the card. |
data[].provenance.primary_article_id | integer | null | The primary evidence article. |
data[].provenance.source_name | string | null | Publishing source of the primary article. |
data[].provenance.publication_date | string | null | Publication time of the primary article. |
data[].provenance.license_path | string | null | License record for the quoted span. |
data[].provenance.span | string | null | The verbatim evidence span. |
data[].provenance.offsets | object | null | Character offsets {start, end} of the span. |
data[].provenance.method | string | null | The mint pipeline (factory -> gate -> canary). |
data[].provenance.gate | DepthCardGate | null | Publish-safety gate record. See the DepthCardGate object. |
data[].provenance.frozen_gate_sha256 | string | null | SHA-256 of the frozen gate code that admitted the card. |
data[].provenance.adjudicator | string | null | Who/what adjudicated the card (e.g. held_queue rubric). |
data[].provenance.adjudicator_rationale | string | null | Adjudicator rationale, when recorded. |
data[].provenance.verdict_cache_key | string | null | Cache key of the adjudication verdict. |
data[].provenance.cert_ref | string | null | Certification run reference. |
data[].provenance.content_hash | string | null | Content hash of the card payload. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/depth-cards"
import requests
r = requests.get(
"https://api.pressroom.news/v1/depth-cards",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/depth-cards", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Certified depth cards for one story unit GET /v1/depth-cards/story/{story_unit_id}
All persisted depth cards scoped to a story unit — matched by story_unit_id, falling back to article membership when the mint keyed cards by article (meta.method states which route resolved).
Returns the card list with pagination meta.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
story_unit_id path | integer | required | — | Spine story unit id. |
page query | integer | optional | 1 | Page number (1-based). |
page_size query | integer | optional | 50 | Items per page (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of DepthCard | The endpoint's payload. |
data[].object | string | null | Object type discriminator: always "depth_card". |
data[].id | string | null | Stable card id (canonical). |
data[].card_id | string | null | Deprecated alias of `id`; will be removed in the next API version. |
data[].contract_version | string | null | Card contract version (depth_card_v1). |
data[].disposition | string | null | Always PUBLISHED (only published cards persist). |
data[].object_class | string | null | Typed object class (e.g. DEATH_COUNT). |
data[].base_class | string | null | Coarse base class. |
data[].claim | string | null | The card's claim text. |
data[].claimed_value | any | The typed claimed value (number, range, …). |
data[].unit | string | null | Unit of the claimed value (e.g. people). |
data[].story_unit_id | integer | null | Spine story unit the card belongs to, when linked. |
data[].minted_at | string | null | When the guarded writer minted the card. |
data[].provenance | DepthCardProvenance | null | Full mint provenance. |
data[].provenance.article_ids | any | All article ids backing the card. |
data[].provenance.primary_article_id | integer | null | The primary evidence article. |
data[].provenance.source_name | string | null | Publishing source of the primary article. |
data[].provenance.publication_date | string | null | Publication time of the primary article. |
data[].provenance.license_path | string | null | License record for the quoted span. |
data[].provenance.span | string | null | The verbatim evidence span. |
data[].provenance.offsets | object | null | Character offsets {start, end} of the span. |
data[].provenance.method | string | null | The mint pipeline (factory -> gate -> canary). |
data[].provenance.gate | DepthCardGate | null | Publish-safety gate record. See the DepthCardGate object. |
data[].provenance.frozen_gate_sha256 | string | null | SHA-256 of the frozen gate code that admitted the card. |
data[].provenance.adjudicator | string | null | Who/what adjudicated the card (e.g. held_queue rubric). |
data[].provenance.adjudicator_rationale | string | null | Adjudicator rationale, when recorded. |
data[].provenance.verdict_cache_key | string | null | Cache key of the adjudication verdict. |
data[].provenance.cert_ref | string | null | Certification run reference. |
data[].provenance.content_hash | string | null | Content hash of the card payload. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/depth-cards/story/su_2026_0001"
import requests
r = requests.get(
"https://api.pressroom.news/v1/depth-cards/story/su_2026_0001",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/depth-cards/story/su_2026_0001", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Single certified depth card by id (provenance-cited) GET /v1/depth-cards/{card_id}
One certified depth card with its complete mint provenance (article lineage, evidence span, license, gate record, adjudicator, certification reference).
Returns the DepthCard object; 404 when the id is unknown or persistence is not yet activated.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
card_id path | string | required | — | Stable depth-card id. |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | DepthCard | The endpoint's payload. |
data.object | string | null | Object type discriminator: always "depth_card". |
data.id | string | null | Stable card id (canonical). |
data.card_id | string | null | Deprecated alias of `id`; will be removed in the next API version. |
data.contract_version | string | null | Card contract version (depth_card_v1). |
data.disposition | string | null | Always PUBLISHED (only published cards persist). |
data.object_class | string | null | Typed object class (e.g. DEATH_COUNT). |
data.base_class | string | null | Coarse base class. |
data.claim | string | null | The card's claim text. |
data.claimed_value | any | The typed claimed value (number, range, …). |
data.unit | string | null | Unit of the claimed value (e.g. people). |
data.story_unit_id | integer | null | Spine story unit the card belongs to, when linked. |
data.minted_at | string | null | When the guarded writer minted the card. |
data.provenance | DepthCardProvenance | null | Full mint provenance. |
data.provenance.article_ids | any | All article ids backing the card. |
data.provenance.primary_article_id | integer | null | The primary evidence article. |
data.provenance.source_name | string | null | Publishing source of the primary article. |
data.provenance.publication_date | string | null | Publication time of the primary article. |
data.provenance.license_path | string | null | License record for the quoted span. |
data.provenance.span | string | null | The verbatim evidence span. |
data.provenance.offsets | object | null | Character offsets {start, end} of the span. |
data.provenance.method | string | null | The mint pipeline (factory -> gate -> canary). |
data.provenance.gate | DepthCardGate | null | Publish-safety gate record. See the DepthCardGate object. |
data.provenance.frozen_gate_sha256 | string | null | SHA-256 of the frozen gate code that admitted the card. |
data.provenance.adjudicator | string | null | Who/what adjudicated the card (e.g. held_queue rubric). |
data.provenance.adjudicator_rationale | string | null | Adjudicator rationale, when recorded. |
data.provenance.verdict_cache_key | string | null | Cache key of the adjudication verdict. |
data.provenance.cert_ref | string | null | Certification run reference. |
data.provenance.content_hash | string | null | Content hash of the card payload. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/depth-cards/cc_arrest_count_ca89a2c654546c73"
import requests
r = requests.get(
"https://api.pressroom.news/v1/depth-cards/cc_arrest_count_ca89a2c654546c73",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/depth-cards/cc_arrest_count_ca89a2c654546c73", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Story units
Active story units (deterministic order, no ranking model) GET /v1/story/active
Story units still receiving coverage within the last `days`, most recently updated first — no ranking model.
Returns the unit summaries and their count.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
days query | integer | optional | 7 | Recency window in days (default 7, max 90). |
limit query | integer | optional | 50 | Max units returned (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | StoryActive | The endpoint's payload. |
data.units | array of StoryUnit | null | Active units, most recently updated first. |
data.units[].object | string | null | Object type discriminator: always "story_unit". |
data.units[].id | integer | null | Story unit id (canonical). |
data.units[].unit_id | integer | null | Deprecated alias of `id`; will be removed in the next API version. |
data.units[].headline | string | null | The unit's representative headline (origin article). |
data.units[].first_published_at | string | null | Publication time of the first member article. |
data.units[].last_published_at | string | null | Publication time of the latest member article. |
data.units[].article_count | integer | null | Member articles in the unit. |
data.units[].source_count | integer | null | Distinct sources covering the unit. |
data.count | integer | null | Number of units returned. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/story/active"
import requests
r = requests.get(
"https://api.pressroom.news/v1/story/active",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/story/active", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Second click: article → its grounded story page GET /v1/story/by-article/{article_id}
The second-click surface: resolves the article to its corroborated story unit and composes the grounded page (what happened, timeline with novelty, canonical statements, disagreement, key players — all cited). An article without a unit gets an honest article-only fallback (unit: null), never a 404.
Returns the StoryPage object.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
article_id path | integer | required | — | Corpus article id (the tapped article). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | StoryPage | The endpoint's payload. |
data.unit | StoryUnit | null | The story unit summary; null in the article-only fallback. |
data.unit.object | string | null | Object type discriminator: always "story_unit". |
data.unit.id | integer | null | Story unit id (canonical). |
data.unit.unit_id | integer | null | Deprecated alias of `id`; will be removed in the next API version. |
data.unit.headline | string | null | The unit's representative headline (origin article). |
data.unit.first_published_at | string | null | Publication time of the first member article. |
data.unit.last_published_at | string | null | Publication time of the latest member article. |
data.unit.article_count | integer | null | Member articles in the unit. |
data.unit.source_count | integer | null | Distinct sources covering the unit. |
data.article | object | null | Fallback only: the tapped article with source + translation-safety state. |
data.what_happened | string | null | Templated, fully-cited narrative summary (no LLM). |
data.timeline | array of object | null | Member articles in publication order with per-article novelty (novel/repeat quote counts, novel entities). |
data.signal | object | null | Novel-vs-repeated statement counts and the signal ratio. |
data.statements | array of StoryStatement | null | Canonical statements (quotes grouped by verbatim identity). |
data.statements[].text | string | null | Verbatim statement text. |
data.statements[].speaker | string | null | Resolved speaker name (or the raw speaker surface). |
data.statements[].speaker_person_id | integer | null | Canonical person id when resolved. |
data.statements[].first_said_in | integer | null | Article id where the statement first appeared. |
data.statements[].first_said_at | string | null | Publication time of the first appearance. |
data.statements[].articles | array of integer | null | All member article ids carrying the statement. |
data.statements[].repeat_count | integer | null | Repetitions after the first appearance. |
data.statements[].stance_target | string | null | The issue the statement takes a position on. |
data.statements[].stance_polarity | string | null | Position polarity: support | oppose | …. |
data.disagreement | array of object | null | Stance targets where statements carry mixed polarity. |
data.key_players | array of object | null | Aboutness-weighted entities across the unit, QID-linked. |
data.citations | array of object | null | Article citations backing every claim on the page. |
data.generation_mode | string | null | Always 'deterministic' (no LLM). |
data.generated_at | string | null | Server compute-time stamp (ISSUE-278). |
data.note | string | null | Fallback honesty note, when unit is null. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/story/by-article/186888"
import requests
r = requests.get(
"https://api.pressroom.news/v1/story/by-article/186888",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/story/by-article/186888", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Grounded story page by unit id GET /v1/story/units/{unit_id}
The same grounded story page, addressed by story unit id (merged units follow their merge target).
Returns the StoryPage object.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
unit_id path | integer | required | — | Story unit id. |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | StoryPage | The endpoint's payload. |
data.unit | StoryUnit | null | The story unit summary; null in the article-only fallback. |
data.unit.object | string | null | Object type discriminator: always "story_unit". |
data.unit.id | integer | null | Story unit id (canonical). |
data.unit.unit_id | integer | null | Deprecated alias of `id`; will be removed in the next API version. |
data.unit.headline | string | null | The unit's representative headline (origin article). |
data.unit.first_published_at | string | null | Publication time of the first member article. |
data.unit.last_published_at | string | null | Publication time of the latest member article. |
data.unit.article_count | integer | null | Member articles in the unit. |
data.unit.source_count | integer | null | Distinct sources covering the unit. |
data.article | object | null | Fallback only: the tapped article with source + translation-safety state. |
data.what_happened | string | null | Templated, fully-cited narrative summary (no LLM). |
data.timeline | array of object | null | Member articles in publication order with per-article novelty (novel/repeat quote counts, novel entities). |
data.signal | object | null | Novel-vs-repeated statement counts and the signal ratio. |
data.statements | array of StoryStatement | null | Canonical statements (quotes grouped by verbatim identity). |
data.statements[].text | string | null | Verbatim statement text. |
data.statements[].speaker | string | null | Resolved speaker name (or the raw speaker surface). |
data.statements[].speaker_person_id | integer | null | Canonical person id when resolved. |
data.statements[].first_said_in | integer | null | Article id where the statement first appeared. |
data.statements[].first_said_at | string | null | Publication time of the first appearance. |
data.statements[].articles | array of integer | null | All member article ids carrying the statement. |
data.statements[].repeat_count | integer | null | Repetitions after the first appearance. |
data.statements[].stance_target | string | null | The issue the statement takes a position on. |
data.statements[].stance_polarity | string | null | Position polarity: support | oppose | …. |
data.disagreement | array of object | null | Stance targets where statements carry mixed polarity. |
data.key_players | array of object | null | Aboutness-weighted entities across the unit, QID-linked. |
data.citations | array of object | null | Article citations backing every claim on the page. |
data.generation_mode | string | null | Always 'deterministic' (no LLM). |
data.generated_at | string | null | Server compute-time stamp (ISSUE-278). |
data.note | string | null | Fallback honesty note, when unit is null. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/story/units/su_2026_0001"
import requests
r = requests.get(
"https://api.pressroom.news/v1/story/units/su_2026_0001",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/story/units/su_2026_0001", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Stance
Deterministic stance dossier (person alias, D8) GET /v1/stance/dossier
The original person-scoped stance dossier: verbatim, attributed quotes grouped into topic sections with a stable content digest — deterministic, no LLM.
Returns the dossier with its digest in meta.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
person query | string | required | — | canonical name or people.id |
topic query | string | null | optional | — | comma-separated topic slugs |
since query | string | null | optional | — | ISO date lower bound |
until query | string | null | optional | — | ISO date upper bound |
min_len query | integer | optional | 40 | Minimum quote length in characters (default 40, range 10-400). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | StanceDossier | The endpoint's payload. |
data.digest | string | null | Content digest of the dossier (stable for identical inputs). |
data.subject | any | The dossier subject (person / entity block). |
data.person | any | The resolved person (v1 dossier). |
data.sections | any | Topic / act-family sections of cited positions. |
data.positions | any | Resolved-target positions with consistency, when present. |
data.coverage | any | Coverage stats backing the dossier. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/stance/dossier?person=example"
import requests
r = requests.get(
"https://api.pressroom.news/v1/stance/dossier",
headers={"X-API-Key": PRESSROOM_KEY},
params={"person": "example"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/stance/dossier?person=example", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Entity stance dossier v2 (voices + act-family sections + resolved-target positions with consistency; country = world-wide government-voice roll-up) GET /v1/{kind}/{eid}/stance
The entity's stated positions as a facet of its canonical profile: attributed voices, act-family sections, and resolved-target positions with consistency scoring; a COUNTRY location rolls up its world-wide government voices.
Returns the v2 dossier with its digest in meta.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
kind path | string | required | — | Entity kind: people | organisations | locations. |
eid path | integer | required | — | Canonical entity id within the kind. |
topic query | string | null | optional | — | comma-separated topic slugs |
since query | string | null | optional | — | ISO date lower bound |
until query | string | null | optional | — | ISO date upper bound |
min_len query | integer | optional | 40 | Minimum quote length in characters (default 40, range 10-400). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | StanceDossier | The endpoint's payload. |
data.digest | string | null | Content digest of the dossier (stable for identical inputs). |
data.subject | any | The dossier subject (person / entity block). |
data.person | any | The resolved person (v1 dossier). |
data.sections | any | Topic / act-family sections of cited positions. |
data.positions | any | Resolved-target positions with consistency, when present. |
data.coverage | any | Coverage stats backing the dossier. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/people/174/stance"
import requests
r = requests.get(
"https://api.pressroom.news/v1/people/174/stance",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/people/174/stance", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Intelligence analyses
Entities once co-covered with X that are now absent POST /v1/analyse/blind-spot
Entities that used to share coverage with the subject but have gone quiet in the recent half of the window.
Returns the dropped co-entities with their prior and recent co-counts.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
entity body | EntityRef | required | — | The entity whose dropped co-coverage to find. |
date_from body | string | null | optional | — | Window start, ISO YYYY-MM-DD. |
date_to body | string | null | optional | — | Window end, ISO YYYY-MM-DD. |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | AnalysisResult | The endpoint's payload. |
data.subject | string | null | The resolved subject: 'q:<query>' or '<kind>:<id>'. |
data.window | Window | null | Resolved date window. |
data.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
data.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
data.method | string | null | Exactly how the numbers were computed — every result is reproducible by an independent query. |
data.interpretation | string | null | Plain-language reading of the finding, when provided. |
data.reliability | string | null | Denominator-health grade of the underlying clusters, when relevant. |
data.note | string | null | Caveats, when any. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"entity": "example"}' \
"https://api.pressroom.news/v1/analyse/blind-spot"import requests
r = requests.post(
"https://api.pressroom.news/v1/analyse/blind-spot",
headers={"X-API-Key": PRESSROOM_KEY},
json={"entity": "example"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/analyse/blind-spot", {
headers: { "X-API-Key": PRESSROOM_KEY, "Content-Type": "application/json" },
method: "POST",
body: JSON.stringify({"entity": "example"})
});
const data = await res.json();Project peak / duration from the volume curve POST /v1/analyse/crisis-trajectory
Fits the subject's coverage volume curve to project the peak and expected duration.
Returns the curve, the projection, and the method.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
q body | string | null | optional | — | Keyword subject (headline match). Provide q or entity. |
entity body | EntityRef | null | optional | — | Entity subject. Provide q or entity. |
date_from body | string | null | optional | — | Window start, ISO YYYY-MM-DD (default: 90 days before date_to). |
date_to body | string | null | optional | — | Window end, ISO YYYY-MM-DD (default: today, UTC). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | AnalysisResult | The endpoint's payload. |
data.subject | string | null | The resolved subject: 'q:<query>' or '<kind>:<id>'. |
data.window | Window | null | Resolved date window. |
data.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
data.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
data.method | string | null | Exactly how the numbers were computed — every result is reproducible by an independent query. |
data.interpretation | string | null | Plain-language reading of the finding, when provided. |
data.reliability | string | null | Denominator-health grade of the underlying clusters, when relevant. |
data.note | string | null | Caveats, when any. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"q": "election"}' \
"https://api.pressroom.news/v1/analyse/crisis-trajectory"import requests
r = requests.post(
"https://api.pressroom.news/v1/analyse/crisis-trajectory",
headers={"X-API-Key": PRESSROOM_KEY},
json={"q": "election"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/analyse/crisis-trajectory", {
headers: { "X-API-Key": PRESSROOM_KEY, "Content-Type": "application/json" },
method: "POST",
body: JSON.stringify({"q": "election"})
});
const data = await res.json();How two entities' relationship moved over a window POST /v1/analyse/entity-relationship-delta
Compares the two entities' shared-article counts across the window midpoint.
Returns co-occurrence totals per half, the delta, and its direction (strengthening / weakening / stable).
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
a body | EntityRef | required | — | First entity. |
b body | EntityRef | required | — | Second entity. |
date_from body | string | null | optional | — | Window start, ISO YYYY-MM-DD. |
date_to body | string | null | optional | — | Window end, ISO YYYY-MM-DD. |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | RelationshipDelta | The endpoint's payload. |
data.subject | string | null | The resolved subject: 'q:<query>' or '<kind>:<id>'. |
data.window | Window | null | Resolved date window. |
data.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
data.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
data.method | string | null | Exactly how the numbers were computed — every result is reproducible by an independent query. |
data.interpretation | string | null | Plain-language reading of the finding, when provided. |
data.reliability | string | null | Denominator-health grade of the underlying clusters, when relevant. |
data.note | string | null | Caveats, when any. |
data.a | object | null | Entity A reference. |
data.b | object | null | Entity B reference. |
data.co_total | integer | null | Shared articles across the whole window. |
data.co_recent_half | integer | null | Shared articles in the recent half. |
data.co_prior_half | integer | null | Shared articles in the prior half. |
data.delta | integer | number | null | recent - prior shared-article delta. |
data.direction | string | null | strengthening | weakening | stable. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"a": "Adani", "b": "Reserve Bank of India"}' \
"https://api.pressroom.news/v1/analyse/entity-relationship-delta"import requests
r = requests.post(
"https://api.pressroom.news/v1/analyse/entity-relationship-delta",
headers={"X-API-Key": PRESSROOM_KEY},
json={"a": "Adani", "b": "Reserve Bank of India"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/analyse/entity-relationship-delta", {
headers: { "X-API-Key": PRESSROOM_KEY, "Content-Type": "application/json" },
method: "POST",
body: JSON.stringify({"a": "Adani", "b": "Reserve Bank of India"})
});
const data = await res.json();Corroboration vs contradiction across independent sources POST /v1/analyse/epistemic-confidence
How firmly the subject's coverage is corroborated: independent sources and countries, per-cluster corroboration, sentiment spread, contradiction.
Returns the component scores, the composite confidence, and an interpretation.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
q body | string | null | optional | — | Keyword subject (headline match). Provide q or entity. |
entity body | EntityRef | null | optional | — | Entity subject. Provide q or entity. |
date_from body | string | null | optional | — | Window start, ISO YYYY-MM-DD (default: 90 days before date_to). |
date_to body | string | null | optional | — | Window end, ISO YYYY-MM-DD (default: today, UTC). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | EpistemicConfidence | The endpoint's payload. |
data.subject | string | null | The resolved subject: 'q:<query>' or '<kind>:<id>'. |
data.window | Window | null | Resolved date window. |
data.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
data.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
data.method | string | null | Exactly how the numbers were computed — every result is reproducible by an independent query. |
data.interpretation | string | null | Plain-language reading of the finding, when provided. |
data.reliability | string | null | Denominator-health grade of the underlying clusters, when relevant. |
data.note | string | null | Caveats, when any. |
data.articles | integer | null | Articles in the result set. |
data.independent_sources | integer | null | Distinct sources. |
data.countries | integer | null | Distinct source origin countries. |
data.distinct_stories | integer | null | Distinct near-dup story clusters. |
data.corroboration | integer | number | null | Corroboration score component. |
data.contradiction | integer | number | null | Contradiction score component. |
data.confidence | integer | number | null | Composite epistemic-confidence score. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"q": "election"}' \
"https://api.pressroom.news/v1/analyse/epistemic-confidence"import requests
r = requests.post(
"https://api.pressroom.news/v1/analyse/epistemic-confidence",
headers={"X-API-Key": PRESSROOM_KEY},
json={"q": "election"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/analyse/epistemic-confidence", {
headers: { "X-API-Key": PRESSROOM_KEY, "Content-Type": "application/json" },
method: "POST",
body: JSON.stringify({"q": "election"})
});
const data = await res.json();Competing narratives across source clusters POST /v1/analyse/narrative-conflict
Contrasts how source clusters (by origin/audience taxonomy) frame the subject: volume and sentiment per cluster, divergence measures.
Returns the per-cluster framing comparison.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
q body | string | null | optional | — | Keyword subject (headline match). Provide q or entity. |
entity body | EntityRef | null | optional | — | Entity subject. Provide q or entity. |
date_from body | string | null | optional | — | Window start, ISO YYYY-MM-DD (default: 90 days before date_to). |
date_to body | string | null | optional | — | Window end, ISO YYYY-MM-DD (default: today, UTC). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | AnalysisResult | The endpoint's payload. |
data.subject | string | null | The resolved subject: 'q:<query>' or '<kind>:<id>'. |
data.window | Window | null | Resolved date window. |
data.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
data.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
data.method | string | null | Exactly how the numbers were computed — every result is reproducible by an independent query. |
data.interpretation | string | null | Plain-language reading of the finding, when provided. |
data.reliability | string | null | Denominator-health grade of the underlying clusters, when relevant. |
data.note | string | null | Caveats, when any. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"q": "election"}' \
"https://api.pressroom.news/v1/analyse/narrative-conflict"import requests
r = requests.post(
"https://api.pressroom.news/v1/analyse/narrative-conflict",
headers={"X-API-Key": PRESSROOM_KEY},
json={"q": "election"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/analyse/narrative-conflict", {
headers: { "X-API-Key": PRESSROOM_KEY, "Content-Type": "application/json" },
method: "POST",
body: JSON.stringify({"q": "election"})
});
const data = await res.json();Coverage momentum (volume/diversity/geo/sentiment derivative) POST /v1/analyse/narrative-momentum
Whether coverage of the subject is accelerating or decaying: derivatives of volume, source diversity, geographic spread, and sentiment across the window halves.
Returns the momentum components, a composite score, and the method.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
q body | string | null | optional | — | Keyword subject (headline match). Provide q or entity. |
entity body | EntityRef | null | optional | — | Entity subject. Provide q or entity. |
date_from body | string | null | optional | — | Window start, ISO YYYY-MM-DD (default: 90 days before date_to). |
date_to body | string | null | optional | — | Window end, ISO YYYY-MM-DD (default: today, UTC). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | AnalysisResult | The endpoint's payload. |
data.subject | string | null | The resolved subject: 'q:<query>' or '<kind>:<id>'. |
data.window | Window | null | Resolved date window. |
data.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
data.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
data.method | string | null | Exactly how the numbers were computed — every result is reproducible by an independent query. |
data.interpretation | string | null | Plain-language reading of the finding, when provided. |
data.reliability | string | null | Denominator-health grade of the underlying clusters, when relevant. |
data.note | string | null | Caveats, when any. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"q": "election"}' \
"https://api.pressroom.news/v1/analyse/narrative-momentum"import requests
r = requests.post(
"https://api.pressroom.news/v1/analyse/narrative-momentum",
headers={"X-API-Key": PRESSROOM_KEY},
json={"q": "election"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/analyse/narrative-momentum", {
headers: { "X-API-Key": PRESSROOM_KEY, "Content-Type": "application/json" },
method: "POST",
body: JSON.stringify({"q": "election"})
});
const data = await res.json();Every occurrence of a quote, chronologically POST /v1/analyse/quote-provenance
Traces a verbatim quote fragment through the corpus: who said it first, where it re-appeared, with article provenance on each occurrence.
Returns occurrences in chronological order.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
fragment body | string | required | — | Verbatim quote fragment to trace (min 4 chars). |
limit body | integer | optional | 50 | Max occurrences returned (default 50, max 200). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | QuoteProvenanceResult | The endpoint's payload. |
data.fragment | string | null | The searched quote fragment. |
data.occurrences | array of object | null | Chronological occurrences with article provenance. |
data.total | integer | null | Total occurrences found. |
data.method | string | null | How occurrences were matched. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"fragment": "example"}' \
"https://api.pressroom.news/v1/analyse/quote-provenance"import requests
r = requests.post(
"https://api.pressroom.news/v1/analyse/quote-provenance",
headers={"X-API-Key": PRESSROOM_KEY},
json={"fragment": "example"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/analyse/quote-provenance", {
headers: { "X-API-Key": PRESSROOM_KEY, "Content-Type": "application/json" },
method: "POST",
body: JSON.stringify({"fragment": "example"})
});
const data = await res.json();Sentiment per mentioned place POST /v1/analyse/sentiment-geography
Average article sentiment grouped by mentioned location (QID-deduped, country codes normalised to ISO-3166).
Returns per-place sentiment and coverage counts.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
q body | string | null | optional | — | Keyword subject (headline match). Provide q or entity. |
entity body | EntityRef | null | optional | — | Entity subject. Provide q or entity. |
date_from body | string | null | optional | — | Window start, ISO YYYY-MM-DD (default: 90 days before date_to). |
date_to body | string | null | optional | — | Window end, ISO YYYY-MM-DD (default: today, UTC). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | AnalysisResult | The endpoint's payload. |
data.subject | string | null | The resolved subject: 'q:<query>' or '<kind>:<id>'. |
data.window | Window | null | Resolved date window. |
data.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
data.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
data.method | string | null | Exactly how the numbers were computed — every result is reproducible by an independent query. |
data.interpretation | string | null | Plain-language reading of the finding, when provided. |
data.reliability | string | null | Denominator-health grade of the underlying clusters, when relevant. |
data.note | string | null | Caveats, when any. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"q": "election"}' \
"https://api.pressroom.news/v1/analyse/sentiment-geography"import requests
r = requests.post(
"https://api.pressroom.news/v1/analyse/sentiment-geography",
headers={"X-API-Key": PRESSROOM_KEY},
json={"q": "election"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/analyse/sentiment-geography", {
headers: { "X-API-Key": PRESSROOM_KEY, "Content-Type": "application/json" },
method: "POST",
body: JSON.stringify({"q": "election"})
});
const data = await res.json();% of a result set that is net-new vs repetition POST /v1/analyse/signal-vs-noise
Splits the subject's articles into originals vs near-duplicate repetition using the story clusters.
Returns signal/noise counts, the ratio, and cluster health.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
q body | string | null | optional | — | Keyword subject (headline match). Provide q or entity. |
entity body | EntityRef | null | optional | — | Entity subject. Provide q or entity. |
date_from body | string | null | optional | — | Window start, ISO YYYY-MM-DD (default: 90 days before date_to). |
date_to body | string | null | optional | — | Window end, ISO YYYY-MM-DD (default: today, UTC). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | AnalysisResult | The endpoint's payload. |
data.subject | string | null | The resolved subject: 'q:<query>' or '<kind>:<id>'. |
data.window | Window | null | Resolved date window. |
data.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
data.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
data.method | string | null | Exactly how the numbers were computed — every result is reproducible by an independent query. |
data.interpretation | string | null | Plain-language reading of the finding, when provided. |
data.reliability | string | null | Denominator-health grade of the underlying clusters, when relevant. |
data.note | string | null | Caveats, when any. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"q": "election"}' \
"https://api.pressroom.news/v1/analyse/signal-vs-noise"import requests
r = requests.post(
"https://api.pressroom.news/v1/analyse/signal-vs-noise",
headers={"X-API-Key": PRESSROOM_KEY},
json={"q": "election"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/analyse/signal-vs-noise", {
headers: { "X-API-Key": PRESSROOM_KEY, "Content-Type": "application/json" },
method: "POST",
body: JSON.stringify({"q": "election"})
});
const data = await res.json();Who broke each story + how it propagated POST /v1/analyse/story-attribution
For each multi-article story cluster on the subject: the earliest article (the originator) and the propagation chain, with denominator-health caveats.
Returns the attributed stories and cluster health.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
q body | string | null | optional | — | Keyword subject (headline match). Provide q or entity. |
entity body | EntityRef | null | optional | — | Entity subject. Provide q or entity. |
date_from body | string | null | optional | — | Window start, ISO YYYY-MM-DD (default: 90 days before date_to). |
date_to body | string | null | optional | — | Window end, ISO YYYY-MM-DD (default: today, UTC). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | AnalysisResult | The endpoint's payload. |
data.subject | string | null | The resolved subject: 'q:<query>' or '<kind>:<id>'. |
data.window | Window | null | Resolved date window. |
data.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
data.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
data.method | string | null | Exactly how the numbers were computed — every result is reproducible by an independent query. |
data.interpretation | string | null | Plain-language reading of the finding, when provided. |
data.reliability | string | null | Denominator-health grade of the underlying clusters, when relevant. |
data.note | string | null | Caveats, when any. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"q": "election"}' \
"https://api.pressroom.news/v1/analyse/story-attribution"import requests
r = requests.post(
"https://api.pressroom.news/v1/analyse/story-attribution",
headers={"X-API-Key": PRESSROOM_KEY},
json={"q": "election"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/analyse/story-attribution", {
headers: { "X-API-Key": PRESSROOM_KEY, "Content-Type": "application/json" },
method: "POST",
body: JSON.stringify({"q": "election"})
});
const data = await res.json();Emerging → Building → Peak → Declining → Dead POST /v1/analyse/story-lifecycle
Classifies the subject's coverage curve into a lifecycle stage from bucketed volume.
Returns the stage, the volume curve, and the method.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
q body | string | null | optional | — | Keyword subject (headline match). Provide q or entity. |
entity body | EntityRef | null | optional | — | Entity subject. Provide q or entity. |
date_from body | string | null | optional | — | Window start, ISO YYYY-MM-DD (default: 90 days before date_to). |
date_to body | string | null | optional | — | Window end, ISO YYYY-MM-DD (default: today, UTC). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | AnalysisResult | The endpoint's payload. |
data.subject | string | null | The resolved subject: 'q:<query>' or '<kind>:<id>'. |
data.window | Window | null | Resolved date window. |
data.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
data.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
data.method | string | null | Exactly how the numbers were computed — every result is reproducible by an independent query. |
data.interpretation | string | null | Plain-language reading of the finding, when provided. |
data.reliability | string | null | Denominator-health grade of the underlying clusters, when relevant. |
data.note | string | null | Caveats, when any. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"q": "election"}' \
"https://api.pressroom.news/v1/analyse/story-lifecycle"import requests
r = requests.post(
"https://api.pressroom.news/v1/analyse/story-lifecycle",
headers={"X-API-Key": PRESSROOM_KEY},
json={"q": "election"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/analyse/story-lifecycle", {
headers: { "X-API-Key": PRESSROOM_KEY, "Content-Type": "application/json" },
method: "POST",
body: JSON.stringify({"q": "election"})
});
const data = await res.json();Briefs & QA
Deterministic cited analyst brief POST /v1/briefs/generate
Composes an analyst brief for a subject + window from the substrate: a templated summary, top co-covered entities, highest-confidence quotes, source volumes, and citations — no LLM, fully reproducible.
Returns the Brief object.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
q body | string | null | optional | — | Keyword subject (headline match). Provide q or entity. |
entity body | EntityRef | null | optional | — | Entity subject. Provide q or entity. |
date_from body | string | null | optional | — | Window start, ISO YYYY-MM-DD (default: 90 days before date_to). |
date_to body | string | null | optional | — | Window end, ISO YYYY-MM-DD (default: today, UTC). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | Brief | The endpoint's payload. |
data.subject | string | null | The resolved subject. |
data.window | Window | null | Resolved date window. |
data.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
data.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
data.total_articles | integer | null | Articles covering the subject in the window. |
data.total_sources | integer | null | Distinct sources across those articles. |
data.summary | string | null | Templated narrative summary (no LLM). |
data.top_entities | object | null | Top co-covered {people, organisations, locations} with co-counts. |
data.top_quotes | array of object | null | Highest-confidence attributed quotes with provenance. |
data.top_sources | array of object | null | Sources by article volume. |
data.citations | array of object | null | Article citations backing the brief. |
data.generation_mode | string | null | Always 'deterministic'. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"q": "election"}' \
"https://api.pressroom.news/v1/briefs/generate"import requests
r = requests.post(
"https://api.pressroom.news/v1/briefs/generate",
headers={"X-API-Key": PRESSROOM_KEY},
json={"q": "election"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/briefs/generate", {
headers: { "X-API-Key": PRESSROOM_KEY, "Content-Type": "application/json" },
method: "POST",
body: JSON.stringify({"q": "election"})
});
const data = await res.json();Deterministic retrieval QA with citations (no LLM) POST /v1/chat
Retrieval question-answering: stopword-filtered terms plus entity resolution pull ranked evidence passages, deduped by story cluster; the answer is templated from them.
Returns the answer, passages, and citations.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
question body | string | required | — | A natural-language question over the corpus. |
date_from body | string | null | optional | — | Window start, ISO YYYY-MM-DD. |
date_to body | string | null | optional | — | Window end, ISO YYYY-MM-DD. |
k body | integer | optional | 8 | Max evidence passages to retrieve (default 8, max 25). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | ChatAnswer | The endpoint's payload. |
data.question | string | null | The question asked. |
data.answer | string | null | Templated answer composed from the passages. |
data.passages | array of object | null | Ranked evidence passages with article provenance. |
data.citations | array of object | null | Article citations. |
data.generation_mode | string | null | Always 'deterministic'. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -X POST -H "X-API-Key: $PRESSROOM_KEY" \
-H "Content-Type: application/json" \
-d '{"question": "What has been reported about elections?"}' \
"https://api.pressroom.news/v1/chat"import requests
r = requests.post(
"https://api.pressroom.news/v1/chat",
headers={"X-API-Key": PRESSROOM_KEY},
json={"question": "What has been reported about elections?"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/chat", {
headers: { "X-API-Key": PRESSROOM_KEY, "Content-Type": "application/json" },
method: "POST",
body: JSON.stringify({"question": "What has been reported about elections?"})
});
const data = await res.json();Embeddable widgets
Embeddable widget catalogue GET /v1/widgets
The catalogue of embeddable intelligence widgets (sellable-backed only), with each widget's data URL and whether it needs a subject.
Returns the widget list plus embed/billing pointers in meta.
Parameters
No parameters (beyond the auth header).
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of WidgetCatalogueItem | The endpoint's payload. |
data[].id | string | null | Widget id (pass to /v1/widgets/{id}/data). |
data[].name | string | null | Display name of the widget. |
data[].needs_subject | boolean | null | True when the widget requires ?subject=<entity or query>. |
data[].data_url | string | null | Path of the widget's metered data endpoint. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/widgets"
import requests
r = requests.get(
"https://api.pressroom.news/v1/widgets",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/widgets", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Widget data payload (metered) GET /v1/widgets/{widget_id}/data
The data payload for one widget, composed from the same v1 service layer as the public endpoints. Each fetch meters as one API request on the key's account; publishable (pk_) keys are domain-locked.
Returns the widget-specific payload with widget/subject/window context in meta; 501 for gallery ids without a sellable public substrate.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
widget_id path | string | required | — | Widget id from the catalogue. |
subject query | string | null | optional | — | The widget subject (an entity name or query); required when the catalogue marks needs_subject. |
days query | integer | optional | 30 | Coverage window in days (default 30, clamped to 1-365). |
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | any | The endpoint's payload. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/widgets/quote_provenance/data?subject=Adani"
import requests
r = requests.get(
"https://api.pressroom.news/v1/widgets/quote_provenance/data",
headers={"X-API-Key": PRESSROOM_KEY},
params={"subject": "Adani"},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/widgets/quote_provenance/data?subject=Adani", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Sources
Source registry with audience taxonomy GET /v1/sources
The full source registry with the audience taxonomy (origin country, audience country, language, category) and per-source article counts.
Returns the list of sources ordered by name.
Parameters
No parameters (beyond the auth header).
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | array of Source | The endpoint's payload. |
data[].object | string | null | Object type discriminator: always "source". |
data[].id | string | null | Stable registry id of the source (canonical). |
data[].source_id | string | null | Deprecated alias of `id`; will be removed in the next API version. |
data[].name | string | null | Source display name. |
data[].country_of_origin | string | null | Where the publisher is based. |
data[].country_of_audience | string | null | Primary audience: a country name or 'International'. |
data[].language | string | null | Primary publication language (ISO code). |
data[].nav_group | string | null | Navigation grouping (e.g. Global, India). |
data[].category | array of any | null | Editorial categories (wire, daily, business, …). |
data[].article_count | integer | null | Articles extracted from this source. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/sources"
import requests
r = requests.get(
"https://api.pressroom.news/v1/sources",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/sources", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Source-cluster facets (origin / audience / language) GET /v1/sources/facets
Source counts aggregated per taxonomy dimension — the cluster facets used by narrative-conflict grouping.
Returns per-dimension value/count buckets.
Parameters
No parameters (beyond the auth header).
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | SourceFacets | The endpoint's payload. |
data.country_of_origin | array of FacetBucket | null | Sources by publisher origin country. |
data.country_of_origin[].value | string | null | The facet value. |
data.country_of_origin[].sources | integer | null | Sources carrying this value. |
data.country_of_audience | array of FacetBucket | null | Sources by audience country/region. |
data.country_of_audience[].value | string | null | The facet value. |
data.country_of_audience[].sources | integer | null | Sources carrying this value. |
data.language | array of FacetBucket | null | Sources by language. |
data.language[].value | string | null | The facet value. |
data.language[].sources | integer | null | Sources carrying this value. |
data.nav_group | array of FacetBucket | null | Sources by navigation group. |
data.nav_group[].value | string | null | The facet value. |
data.nav_group[].sources | integer | null | Sources carrying this value. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/sources/facets"
import requests
r = requests.get(
"https://api.pressroom.news/v1/sources/facets",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/sources/facets", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();System & account
Your key's metering + quota state GET /v1/account/usage
Self-service usage introspection for the presented key.
Returns your tier, monthly quota and consumption, lifetime call totals, and your 20 most recent requests.
Parameters
No parameters (beyond the auth header).
Response attributes
| Attribute | Type | Description |
|---|---|---|
data | AccountUsage | The endpoint's payload. |
data.tier | string | null | Your tier (free | pro | …). |
data.monthly_quota | integer | null | Your monthly request quota (-1 = unlimited). |
data.monthly_used | integer | null | Requests used in the current period. |
data.usage_period | string | null | The current usage period (YYYY-MM). |
data.lifetime_calls | integer | null | Total calls ever made on the key. |
data.lifetime_cost_units | integer | number | null | Total metered cost units. |
data.recent | array of UsageRecord | null | Your 20 most recent calls. |
data.recent[].ts | string | null | When the call was made (UTC). |
data.recent[].method | string | null | HTTP method. |
data.recent[].endpoint | string | null | Path called. |
data.recent[].status | integer | null | HTTP status returned. |
data.recent[].latency_ms | integer | null | Server-side latency in milliseconds. |
meta | MetaBlock | null | Response metadata: compute time, pagination, endpoint extras. |
meta.generated_at | string | null | UTC timestamp when the server computed this response — use it to honestly label cached/stale data ('as of …'). |
meta.total | integer | null | Total matching items across all pages. |
meta.page | integer | null | Current page number (1-based). |
meta.page_size | integer | null | Items per page. |
meta.window | Window | null | The resolved date window the data covers. |
meta.window.from | string | null | Window start date (ISO YYYY-MM-DD, inclusive). |
meta.window.to | string | null | Window end date (ISO YYYY-MM-DD, inclusive). |
meta.next_cursor | integer | null | Cursor pagination (present only when the request passed starting_after): the last id in this page — pass it as the next request's starting_after. null means the list is exhausted (has_more == next_cursor is not null). |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/account/usage"
import requests
r = requests.get(
"https://api.pressroom.news/v1/account/usage",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/account/usage", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Outcome-based corpus health GET /v1/health
Unauthenticated liveness + data-honesty probe: corpus reachability, article count, serving backend, deployment mode, and metering-reconciliation state.
Returns a Health object (not enveloped).
Parameters
No parameters (beyond the auth header).
Response attributes
| Attribute | Type | Description |
|---|---|---|
status | string | null | Overall health verdict. |
corpus_reachable | boolean | null | Whether the corpus database answered. |
articles | integer | null | Articles in the corpus. |
backend | string | null | Database backend serving reads: postgresql | sqlite. |
corpus_db | string | null | Credential-stripped identifier of the corpus database. |
deployment_mode | string | null | primary | snapshot_replica (replicas report a data horizon instead of queue freshness). |
snapshot_as_of | string | null | Data horizon of a snapshot replica (latest extraction). |
metering_reconciliation_required | integer | null | Usage reservations awaiting finalization (operator signal). |
oldest_metering_reservation | string | null | Timestamp of the oldest unfinalized reservation. |
error_class | string | null | Exception class when the corpus is unreachable. |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/health"
import requests
r = requests.get(
"https://api.pressroom.news/v1/health",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/health", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();API version + tier catalog GET /v1/version
Unauthenticated API identity endpoint.
Returns the API name, version, and the tier catalog with monthly quotas and per-minute rate limits (not enveloped).
Parameters
No parameters (beyond the auth header).
Response attributes
| Attribute | Type | Description |
|---|---|---|
name | string | null | API product name. |
version | string | null | API version string. |
tiers | object | null | Available tiers with quota and rate limits. |
curl -H "X-API-Key: $PRESSROOM_KEY" \ "https://api.pressroom.news/v1/version"
import requests
r = requests.get(
"https://api.pressroom.news/v1/version",
headers={"X-API-Key": PRESSROOM_KEY},
)
print(r.json())const res = await fetch("https://api.pressroom.news/v1/version", {
headers: { "X-API-Key": PRESSROOM_KEY }
});
const data = await res.json();Request access
Pressroom is in private beta. To request an API key, email shobhit.dixit@gmail.com with your use case. Keys are provisioned manually and mapped to a tier.