Developer Documentation
West African News API
The West African News API provides structured, rights-aware access to published news for media organisations, researchers, applications, broadcasters and other authorised clients.
https://news-api.scanafrik.orgQuick start
All public news requests require an API key. Store the key on your server and send it using the HTTP Authorization header.
curl -sS \
-H "Authorization: Bearer wan_live_YOUR_API_KEY" \
"https://news-api.scanafrik.org/v1/news?region=west-africa&language=en&limit=20"Authentication
API customers authenticate with bearer credentials beginning with wan_live_.
Authorization: Bearer wan_live_YOUR_API_KEYProduction API keys must be stored on a server or secure secrets platform. Do not embed them in browser JavaScript, public repositories, mobile application bundles or shared documents.
The API stores a cryptographic digest of the credential rather than the original API key.
Primary endpoint
GET /v1/news
Returns published or corrected news that satisfies the requested filters, active content rights and the caller's product entitlement.
GET https://news-api.scanafrik.org/v1/newsExample: Sierra Leone
curl -sS \
-H "Authorization: Bearer $NEWS_API_KEY" \
"https://news-api.scanafrik.org/v1/news?country=SL&language=en&limit=20"Example: West Africa
curl -sS \
-H "Authorization: Bearer $NEWS_API_KEY" \
"https://news-api.scanafrik.org/v1/news?region=west-africa&language=en&limit=20"Example: topic
curl -sS \
-H "Authorization: Bearer $NEWS_API_KEY" \
"https://news-api.scanafrik.org/v1/news?topic=technology&language=en&limit=20"Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
country | string | No | ISO 3166-1 alpha-2 country code, for example SL, LR, GN, GH or NG. |
region | string | No | Regional filter: west-africa, central-africa, east-africa, southern-africa or north-africa. |
topic | string | No | Topic identifier such as governance, development, technology or education. Maximum 64 characters. |
language | string | No | Requested language code. Defaults to en. Access may depend on account entitlements. |
cursor | string | No | Opaque pagination cursor returned by the previous response. Do not modify or decode it. |
limit | integer | No | Number of records to return. Minimum 1, maximum 100, default 20. |
Clients should normally use either country or region. If both are supplied, the country filter takes precedence.
Supported region values
west-africa
central-africa
east-africa
southern-africa
north-africaResponse format
Responses use JSON. Dates and timestamps use ISO 8601 UTC representations.
{
"data": [
{
"id": "00000000-0000-0000-0000-000000000000",
"slug": "example-west-african-news-story",
"headline": "Example West African News Headline",
"summary": "An illustrative summary returned by the API.",
"body": "Full text is returned only for authorised full-text products.",
"language": "en",
"countries": ["SL"],
"topics": ["development", "technology"],
"eventAt": null,
"publishedAt": "2026-09-17T00:00:00.000Z",
"updatedAt": "2026-09-17T00:00:00.000Z",
"source": {
"name": "Salone Redeemer",
"url": "https://saloneredeemer.com/news"
},
"rights": {
"representation": "full_text",
"attributionRequired": true
}
}
],
"nextCursor": null
}Response fields
| Field | Description |
|---|---|
id | Unique article UUID. |
slug | Stable human-readable article identifier. |
headline | Published article headline. |
summary | Summary when permitted by the API product entitlement. |
body | Full article body when the API key has full_text entitlement. |
language | Language code of the returned revision. |
countries | Country codes associated with the article. |
topics | Editorial topic classifications. |
eventAt | Event timestamp where available. May be null. |
publishedAt | Publication timestamp in ISO 8601 UTC format. |
updatedAt | Timestamp of the most recent article update. |
source.name | Original or publishing source name. |
source.url | Source or attribution URL. |
rights.representation | Representation supplied to the caller: metadata, summary or full_text. |
rights.attributionRequired | Whether attribution must accompany reuse of the returned content. |
Rights-aware representations
The API evaluates product entitlement and active content rights before returning content. A successful request can therefore contain different representations for different API customers.
Metadata
Article identity, headline, taxonomy, publication dates, source information and rights metadata.
Summary
Metadata plus the editorial summary when the account has summary access.
Full text
Metadata, summary and article body when full-text redistribution is authorised.
When rights.attributionRequired is true, clients must preserve the supplied source name and source URL when displaying or redistributing the content.
Cursor pagination
List requests use cursor pagination rather than offset pagination. The API returns nextCursor when more results are available.
{
"data": [ ... ],
"nextCursor": "OPAQUE_CURSOR_VALUE"
}Pass that value unchanged into the next request:
GET /v1/news?region=west-africa&language=en&limit=20&cursor=OPAQUE_CURSOR_VALUEA value of null means there is no additional page in the current result set.
Errors
Error responses use JSON. Most errors also contain arequestId that can be used for diagnostics.
{
"error": "Missing or invalid credential",
"requestId": "75046a30-cdfe-4c15-99de-0842f411648e"
}| Status | Meaning | Typical cause |
|---|---|---|
400 | Invalid request | A query parameter, cursor or request value is invalid. |
401 | Unauthorized | API key is missing, malformed, revoked or invalid. |
403 | Forbidden | The requested language or territory is not included in the subscription. |
429 | Quota exceeded | The API key has reached its monthly request quota. |
500 | Server error | An internal error occurred. Retain the request ID when reporting it. |
Usage and quotas
Successful news-list requests are metered against the API key. Each credential has a monthly request limit. When the monthly quota is exhausted, the API responds with HTTP 429.
Clients should implement normal retry and backoff handling for temporary failures, but should not repeatedly retry a monthly quota error.
Health checks
Health endpoints do not require a customer API credential.
Liveness
GET https://news-api.scanafrik.org/health/liveReadiness
GET https://news-api.scanafrik.org/health/readyA healthy readiness response is:
{
"ok": true
}The readiness check also verifies database connectivity.
Request IDs
Every API response includes an x-request-id HTTP header. Clients may also supply their ownx-request-id value for end-to-end tracing.
x-request-id: 75046a30-cdfe-4c15-99de-0842f411648eClient examples
JavaScript / TypeScript
const url = new URL(
"https://news-api.scanafrik.org/v1/news"
);
url.searchParams.set("region", "west-africa");
url.searchParams.set("language", "en");
url.searchParams.set("limit", "20");
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${process.env.NEWS_API_KEY}`,
Accept: "application/json"
}
});
if (!response.ok) {
throw new Error(
`News API request failed: ${response.status}`
);
}
const page = await response.json();
console.log(page.data);
console.log(page.nextCursor);Python
import os
import requests
response = requests.get(
"https://news-api.scanafrik.org/v1/news",
headers={
"Authorization": f"Bearer {os.environ['NEWS_API_KEY']}",
"Accept": "application/json",
},
params={
"country": "SL",
"language": "en",
"limit": 20,
},
timeout=10,
)
response.raise_for_status()
page = response.json()
print(page["data"])
print(page["nextCursor"])Security guidance
The API is intended primarily for server-to-server integrations. Browser access is restricted by CORS and API credentials must not be exposed to end users.
Store API keys in environment variables, a secrets manager or another protected server-side credential store. Rotate credentials if they are accidentally exposed.
Versioning
The current public contract is versioned under/v1. Breaking API changes should be introduced under a new major version rather than silently altering the existing v1 contract.
Additive response fields may be introduced over time. Clients should ignore JSON fields they do not recognise.
Editorial API
Contributor, editorial review, rights-management and publication endpoints belong to the protected ScanAfrik newsroom environment and are not part of the public customer API documented on this page.
Editorial users should use newsroom.scanafrik.org.