Crossfiled / API
The API
Everything Crossfiled knows, readable by software. No key, no sign-up, no rate card. There is an OpenAPI spec and an MCP server if you would rather point a tool at it than read this.
Getting started
curl https://crossfiled.com/api/v1/stories?min_outlets=3&limit=5
No authentication. 120 requests a minute per IP. Every response is CORS-open and cached for two minutes. If you need more than that, write to kevin@champlinenterprises.com rather than working around it.
Endpoints
GET/api/v1/stories
Current stories, newest and widest-covered first.
topic | One of us-politics, world, courts-justice, money, tech-ai, health, climate |
outlet | Only stories this outlet covered, e.g. Reuters |
min_outlets | At least this many outlets. Use 3+ to drop single-outlet items |
since | ISO date or datetime |
has_video | true to require video coverage |
include_opinion | true to include opinion outlets (off by default) |
limit | 1 to 100, default 25 |
GET/api/v1/stories/{id}
One event with every outlet version attached, in filing order.
GET/api/v1/sources
Every outlet we read, with its format class and country.
GET/api/v1/topics
Topics and how many current stories each holds.
GET/story/{id}/{slug}
The human page. Returns JSON with Accept: application/json.
GET/feed.json
The raw ingest output, if you would rather do your own grouping.
What a story looks like
{
"id": "c_89b02bef06",
"title": "Networks suspend pool coverage after White House bars CNN",
"url": "https://crossfiled.com/story/c_89b02bef06/...",
"outlet_count": 13,
"outlets": ["BBC News", "CNN", "NPR", "..."],
"video_count": 7,
"article_count": 21,
"first_filed": "2026-09-19T14:02:11Z",
"last_filed": "2026-09-21T18:44:02Z"
}
outlet_count is the one worth paying attention to. It is a
measure of how widely an event is being reported, and on a typical day only about 25 of
500 stories are carried by more than one newsroom.
MCP server
An assistant can query Crossfiled directly rather than scraping it.
Stateless JSON-RPC 2.0 at POST /mcp, no auth.
{
"mcpServers": {
"crossfiled": { "type": "http", "url": "https://crossfiled.com/mcp" }
}
}
search_stories | Filter by topic, outlet, breadth of coverage, video, date |
get_story | Every outlet's version of one event, in filing order |
list_sources | Every outlet, with its format class |
coverage_spread | Which outlets covered an event and which did not |
coverage_spread is the one no single outlet can answer.
Read a silence as an observation and not a verdict: an outlet may be working a different
angle, filing later, or simply not serving that beat.