Get a story with /v1/news/story/{article_id}
Pass an article ID to /v1/news/story/{article_id} to find other articles about the same event. Use it to compare coverage across publishers.
Each request costs 1 point.
Endpoint
GET /v1/news/story/{article_id}
POST /v1/news/story/{article_id}Base URL: https://api.apitube.io. The article ID goes in the path. Shared filters narrow the cluster it returns.
What counts as a story
A story is a group of articles about one event. It has no separate ID. Results depend on the starting article and its title:
- A short or vague starting title may return few matches or unrelated results. If the title cannot be used for matching, the API returns
404 ER0240. - Two starting articles about the same event may return different groups of related articles.
Use these results to measure coverage, compare reporting or keep one article per event in your feed.
Parameters
Filters apply within the cluster — for example language.code=en returns only the English coverage of that story.
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
article_id | string | Yes | Source article ID to find related stories for. |
See Filters for all shared search filters, sorting, pagination, field selection and other request options.
This endpoint does not accept prompt. Choose the starting article by ID.
Response format
Uses the shared Response format: related articles under results, each with the full article object described in API Response Structure.
Request examples
curl "https://api.apitube.io/v1/news/story/3036291250?per_page=20&api_key=YOUR_API_KEY"
import requests
article_id = "3036291250"
response = requests.get(
f"https://api.apitube.io/v1/news/story/{article_id}",
params={"per_page": 20},
headers={"X-API-Key": "YOUR_API_KEY"},
)
for article in response.json()["results"]:
print(article["source"]["domain"], "—", article["title"])
const articleId = '3036291250';
const response = await fetch(
`https://api.apitube.io/v1/news/story/${articleId}?per_page=20`,
{ headers: { 'X-API-Key': 'YOUR_API_KEY' } }
);
const data = await response.json();
console.log(`${data.results.length} outlets covered this story`);
$articleId = '3036291250';
$query = http_build_query(['per_page' => 20, 'api_key' => 'YOUR_API_KEY']);
$data = json_decode(file_get_contents("https://api.apitube.io/v1/news/story/$articleId?$query"), true);
echo count($data['results']), ' related articles', PHP_EOL;
How did coverage differ by sentiment?
curl "https://api.apitube.io/v1/news/story/3036291250?facet=1&facet.field=sentiment.overall.polarity&api_key=YOUR_API_KEY"Only high-authority coverage
curl "https://api.apitube.io/v1/news/story/3036291250?source.rank.opr.min=6&api_key=YOUR_API_KEY"Errors
| Code | Status | Meaning |
|---|---|---|
ER0231 | 400 | Article ID missing from the path |
ER0235 | 404 | No article with that ID |
ER0240 | 404 | The starting article's title contains no keywords that can be used to find related articles. |
ER0175 | 401 | API key is missing or invalid |
ER0176 | 402 | No points left on the account |
ER0203 | 429 | Rate limit exceeded |
See HTTP response codes for the full error list.
Related
- Get an article by ID — the seed article itself.
- Search articles — find a seed article to start from.
- Filters — syntax and examples for the shared filters.