API Reference
Here is all the info you need to pull data from NeuraFeed. We kept it super simple.
Test It Without Coding
You do not even need to write any code to test our API! Just click this link to open it in your browser and see the raw data output for yourself: https://feed.neuraspheres.com/api/latest-news.
Available Endpoints
GET /api/latest-news
Try itThis endpoint gives you the absolute newest article our system generated. You do not need any API keys or login to use this. Just make a request and get your data.
GET https://feed.neuraspheres.com/api/latest-newsWhat you get back (200 OK)
{
"success": true,
"article": {
"id": "firestoreDocumentId",
"title": "Article headline",
"summary": "2 to 3 sentence executive summary.",
"article": "<h2>Subtopic</h2><p>Content with inline citation.<sup>[1]</sup></p>...",
"whyItMatters": "2 to 3 sentences explaining significance.",
"tags": ["AI", "OpenAI", "GPT-4"],
"sources": [
"[1] TechCrunch: https://techcrunch.com/...",
"[2] The Verge: https://www.theverge.com/..."
],
"sourceDetails": [
{ "id": "source-1", "number": 1, "title": "TechCrunch", "url": "https://techcrunch.com/...", "domain": "techcrunch.com" }
],
"citations": [
{ "id": "citation-1", "text": "A supported sentence.", "marker": "[1]", "sourceIds": ["source-1"], "sourceNumbers": [1] }
],
"topic": "Detected trending topic name",
"category": "technology",
"coverImage": "https://cdn.vox-cdn.com/uploads/chorus_image/image/12345/hero.jpg",
"imageSource": "theverge.com",
"imageSourceUrl": "https://www.theverge.com/2026/4/26/article-slug",
"embedMedia": {
"type": "youtube",
"id": "dQw4w9WgXcQ",
"title": "Video title from YouTube",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
},
"media": [
{ "id": "media-abc", "type": "image", "url": "https://cdn.example.com/image.jpg", "caption": "Related reporting image", "sourceName": "theverge.com", "sourceUrl": "https://www.theverge.com/...", "afterSection": 1 }
],
"contentVersion": 2,
"createdAt": "2026-04-26T03:00:00.000Z"
}
}GET /api/recent-news
Try itIf you want to build a feed or show more than one article, use this endpoint. It returns an array of the latest articles. Like the other one, it is completely open and needs no authentication.
You can add a limit parameter to the URL to choose how many articles you want. If you do not pass one, you get the 20 most recent. You can ask for up to 100 at a time.
GET https://feed.neuraspheres.com/api/recent-news
GET https://feed.neuraspheres.com/api/recent-news?limit=5
GET https://feed.neuraspheres.com/api/recent-news?limit=50What you get back (200 OK)
{
"success": true,
"articles": [
{
"id": "firestoreDocumentId1",
"title": "Most recent article",
"summary": "...",
"article": "...",
"whyItMatters": "...",
"tags": ["..."],
"sources": ["..."],
"sourceDetails": [{ "id": "source-1", "number": 1, "title": "...", "url": "...", "domain": "..." }],
"citations": [{ "id": "citation-1", "text": "...", "marker": "[1]", "sourceIds": ["source-1"], "sourceNumbers": [1] }],
"topic": "...",
"category": "politics",
"coverImage": "https://cdn.vox-cdn.com/uploads/chorus_image/image/12345/hero.jpg",
"imageSource": "theverge.com",
"imageSourceUrl": "https://www.theverge.com/2026/4/26/article-slug",
"embedMedia": {
"type": "youtube",
"id": "dQw4w9WgXcQ",
"title": "Video title from YouTube",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
},
"media": [{ "id": "media-abc", "type": "image", "url": "...", "caption": "...", "sourceName": "...", "sourceUrl": "...", "afterSection": 1 }],
"contentVersion": 2,
"createdAt": "2026-04-26T03:00:00.000Z"
},
{
"id": "firestoreDocumentId2",
"title": "Older article with no media",
"summary": "...",
"article": "...",
"whyItMatters": "...",
"tags": ["..."],
"sources": ["..."],
"sourceDetails": [],
"citations": [],
"topic": "...",
"category": "technology",
"coverImage": null,
"imageSource": null,
"imageSourceUrl": null,
"embedMedia": null,
"media": [],
"contentVersion": 1,
"createdAt": "2026-04-25T03:00:00.000Z"
}
]
}GET /api/articles
Try itUse this one when you want to page through the whole archive rather than just the newest handful. It uses a cursor instead of an offset, so pages stay stable even when a new article publishes midway through your crawl.
Pass limit (default 12, max 50) and after, which is the id of the last article from the previous page. Leave after off for the first page.
GET https://feed.neuraspheres.com/api/articles
GET https://feed.neuraspheres.com/api/articles?limit=12
GET https://feed.neuraspheres.com/api/articles?limit=12&after=lastArticleIdFromPreviousPageWhat you get back (200 OK)
{
"success": true,
"articles": [ /* same article objects as the other endpoints */ ],
"nextCursor": "qK27BIMwsBJ0abc",
"hasMore": true
}Keep requesting while hasMore is true, passing the previous nextCursor as after.
// Walk the whole archive, one page at a time.
async function* allArticles(limit = 50) {
let after = null;
while (true) {
const url = new URL('https://feed.neuraspheres.com/api/articles');
url.searchParams.set('limit', limit);
if (after) url.searchParams.set('after', after);
const { articles, nextCursor, hasMore } = await fetch(url).then((r) => r.json());
yield* articles;
// Stop on hasMore, not on an empty page: nextCursor is the id of the last
// article you already received, so reusing it forever would loop.
if (!hasMore || !nextCursor) return;
after = nextCursor;
}
}Calling From a Browser
These endpoints do not send an Access-Control-Allow-Origin header, so a fetch() straight from browser JavaScript on your own domain will be blocked by CORS. This is deliberate rather than an oversight.
Call the API from your server instead: a Next.js server component, an API route, a serverless function, or any backend. If you genuinely need the data client-side, proxy it through a one-line route on your own origin and fetch that. There is an example in the Implementation Guide.
Categories
Every article belongs to one category, exposed as the category field. NeuraFeed leads with technology but is not limited to it: about half of all articles are technology and the remainder are spread across the other four.
| Value | Covers |
|---|---|
technology | AI, software, hardware, platforms, and the companies building them |
politics | Government, legislation, elections, regulation, and public policy |
economics | Markets, monetary policy, trade, labour, and corporate finance |
society | Public health, education, inequality, civil rights, and community impact |
world | International affairs, conflict, climate, energy, and global science |
There is no category filter on the endpoints yet, so filter client-side on the field.
Articles published before categories existed omit the key entirely rather than defaulting it, so article.category is undefined on older records. Read it defensively, for example article.category ?? "technology", since everything published before the feature was technology coverage.
Understanding the Data Fields
Every article object comes with a few standard fields. Here is a breakdown of what they are and how to use them.
| Field | Type | Description |
|---|---|---|
id | string | The unique database ID for the article. Good for React keys. |
title | string | The main headline. It is just plain text. |
summary | string | A quick text summary of the whole article. |
article | HTML string | This is the actual written content. It already has HTML tags like headings and paragraphs, so you have to render it as raw HTML. |
whyItMatters | string | A short text block that explains why this news is actually important. |
tags | array | A list of string tags so you can categorize the news. |
sources | array | The links we used to write the article. They come in a specific text format like [1] Name: URL. |
sourceDetails | array | Machine-friendly sources with stable id, number, title, url, and domain fields. |
citations | array | Structured cited passages. Each record links its text and marker to one or more sourceIds, matching the inline data-citation-id marker. |
topic | string | The specific story the AI researched, e.g. "Nvidia Q3 Earnings". This is the individual event, not the section. |
category | string | The section the article belongs to: technology, politics, economics, society, or world. Use this to group or filter; use topic for the headline subject. Absent on articles published before categories existed — treat a missing value as technology. |
coverImage | string | null | URL of the article cover image. Sourced from the og:image of one of the grounding pages. Can be a direct CDN link or a Cloudinary URL. Null if no image could be found. |
imageSource | string | null | The hostname of the page the cover image came from, e.g. theverge.com. Use this for attribution. Null when coverImage is null. |
imageSourceUrl | string | null | The full URL of the source article the image was taken from. Link this when showing the image to give proper credit. Null when coverImage is null. |
embedMedia | object | null | A related YouTube video when one is found. Contains type (youtube), id (the video ID), title, and url. Null when no video was found. |
media | array | Zero to three attributed inline assets. Types can be image, youtube, audio, or video. Use afterSection for placement and always show sourceName/sourceUrl. |
contentVersion | number | Schema version. Version 2 adds structured citations and rich media while keeping legacy fields. Older articles report 1 and have empty sourceDetails, citations, and media. |
generationMeta | object | null | Internal build info about the run (model used, token counts, settings snapshot). Exposed for transparency but not part of the stable contract — do not build on its shape. It also adds roughly 1.5 KB to every article, so strip it if you are caching large pages. |
createdAt | string | A standard timestamp showing exactly when we published the article. |
Just a Heads Up
- Most of the fields like title, summary, and whyItMatters are plain text. You can drop them right into your UI.
- The article field is full of HTML. Make sure you render it correctly or your users will just see a bunch of raw code tags.
- coverImage, imageSource, and imageSourceUrl can all be null. Not every article has an image, so always check before rendering.
- When you show a cover image, link it back to imageSourceUrl and label it with imageSource so the original publisher gets proper credit.
mediais the preferred rich-media field. It can be an empty array.embedMediaremains for backward compatibility with older consumers.- For custom footnotes, use
citationsplussourceDetails. You can keep the inline markers, turn them into popovers, or rebuild the source list without parsing source strings. - Expect far fewer inline markers than sources. An article typically carries 5 to 7
<sup>markers but 10 to 20 entries insourceDetails. That is intentional: attribution mostly lives in the prose ("according to Reuters") and markers are reserved for load-bearing claims. Do not assume every source has a matching marker, and do not hide a source just because it is not cited inline. - Browser JavaScript cannot call these endpoints cross-origin. Fetch from your server and pass the data to the client.
- New articles publish twice a day, around 00:17 and 12:17 UTC, give or take scheduling delay. Cache accordingly — polling more often than hourly gains you nothing.
- We do not rate-limit these endpoints, but please cache the responses on your end. The news does not update every single second.