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.

API v1ProductionJSON / HTTPS
Base URLhttps://news-api.scanafrik.org

Quick 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_KEY
Keep API keys private.

Production 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/news

Example: 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

ParameterTypeRequiredDescription
countrystringNoISO 3166-1 alpha-2 country code, for example SL, LR, GN, GH or NG.
regionstringNoRegional filter: west-africa, central-africa, east-africa, southern-africa or north-africa.
topicstringNoTopic identifier such as governance, development, technology or education. Maximum 64 characters.
languagestringNoRequested language code. Defaults to en. Access may depend on account entitlements.
cursorstringNoOpaque pagination cursor returned by the previous response. Do not modify or decode it.
limitintegerNoNumber of records to return. Minimum 1, maximum 100, default 20.
Country and region

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-africa

Response 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

FieldDescription
idUnique article UUID.
slugStable human-readable article identifier.
headlinePublished article headline.
summarySummary when permitted by the API product entitlement.
bodyFull article body when the API key has full_text entitlement.
languageLanguage code of the returned revision.
countriesCountry codes associated with the article.
topicsEditorial topic classifications.
eventAtEvent timestamp where available. May be null.
publishedAtPublication timestamp in ISO 8601 UTC format.
updatedAtTimestamp of the most recent article update.
source.nameOriginal or publishing source name.
source.urlSource or attribution URL.
rights.representationRepresentation supplied to the caller: metadata, summary or full_text.
rights.attributionRequiredWhether 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.

Attribution

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_VALUE

A 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"
}
StatusMeaningTypical cause
400Invalid requestA query parameter, cursor or request value is invalid.
401UnauthorizedAPI key is missing, malformed, revoked or invalid.
403ForbiddenThe requested language or territory is not included in the subscription.
429Quota exceededThe API key has reached its monthly request quota.
500Server errorAn 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/live

Readiness

GET https://news-api.scanafrik.org/health/ready

A 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-0842f411648e

Client 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.

Recommended practice

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.