Introduction
The CompassNG API provides programmatic access to structured news data from 50+ Nigerian publishers. Every article is enriched with NLP — sentiment analysis, named entity recognition, categorization, and version tracking.
Base URL
https://api.compassng.comQuick Start
- Create a free account at compassng.com/register
- Generate an API key from your dashboard
- Make your first request using the key as a Bearer token
- Explore endpoints in the interactive playground
Authentication
All data endpoints require an API key via the X-API-Key header. Create a key from your dashboard and include it in every request.
API Key Header
X-API-Key: YOUR_API_KEYGetting Your API Key
- Sign in to your CompassNG dashboard
- Navigate to API Keys in the sidebar
- Click "Create API Key" and choose Demo or Live
- Copy your key — you can view it again later from the dashboard
Example Request
curl -H "X-API-Key: YOUR_API_KEY" \
https://api.compassng.com/api/v1/articlesKeep your API key secret. Do not expose it in client-side code, public repositories, or browser requests. Use a server-side proxy for production applications.
List Articles
/api/v1/articlesRetrieve the latest articles feed with full NLP enrichment. Results are paginated and sorted by publication date (newest first).
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
page | integer | Optional | Page number (default: 1) |
per_page | integer | Optional | Results per page, max 100 (default: 20) |
Example Request
curl -H "X-API-Key: YOUR_API_KEY" \
"https://api.compassng.com/api/v1/articles?page=1&per_page=10"Example Response
{
"data": [
{
"id": "a1b2c3d4",
"title": "Federal Government Announces New Economic Policy",
"summary": "The Nigerian government unveiled a new set of economic reforms...",
"url": "https://example.com/article/12345",
"source": {
"id": "src_01",
"name": "Punch",
"domain": "punchng.com",
"type": "newspaper"
},
"authors": [
"Adewale Johnson"
],
"published_at": "2025-06-15T10:30:00Z",
"categories": [
"politics",
"economy"
],
"tags": [
"fiscal-policy",
"reform"
],
"language": "en",
"sentiment": {
"score": 0.25,
"label": "positive",
"confidence": 0.87
},
"entities": [
{
"text": "Federal Government",
"type": "ORG",
"salience": 0.92
},
{
"text": "Nigeria",
"type": "GPE",
"salience": 0.85
}
],
"word_count": 842
}
],
"meta": {
"total": 15420,
"page": 1,
"per_page": 10,
"total_pages": 1542
},
"links": {
"next": "/api/v1/articles?page=2&per_page=10",
"prev": null
}
}Get Article
/api/v1/articles/:idRetrieve a single article by ID with full enrichment including body text, entities, sentiment, and version history metadata.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | The unique article identifier |
Example Request
curl -H "X-API-Key: YOUR_API_KEY" \
"https://api.compassng.com/api/v1/articles/a1b2c3d4"Example Response
{
"id": "a1b2c3d4",
"title": "Federal Government Announces New Economic Policy",
"body": "The Nigerian government on Monday unveiled a comprehensive set of economic reforms aimed at stabilizing the naira and boosting foreign investment...",
"summary": "The Nigerian government unveiled a new set of economic reforms...",
"url": "https://example.com/article/12345",
"source": {
"id": "src_01",
"name": "Punch",
"domain": "punchng.com",
"logo_url": null,
"credibility_score": 85,
"state": "Lagos",
"type": "newspaper"
},
"authors": [
"Adewale Johnson"
],
"published_at": "2025-06-15T10:30:00Z",
"crawled_at": "2025-06-15T10:45:00Z",
"updated_at": "2025-06-15T14:00:00Z",
"categories": [
"politics",
"economy"
],
"tags": [
"fiscal-policy",
"reform"
],
"language": "en",
"entities": [
{
"text": "Federal Government",
"type": "ORG",
"salience": 0.92,
"wikipedia_url": null
},
{
"text": "Nigeria",
"type": "GPE",
"salience": 0.85,
"wikipedia_url": "https://en.wikipedia.org/wiki/Nigeria"
}
],
"sentiment": {
"score": 0.25,
"label": "positive",
"confidence": 0.87
},
"image_url": null,
"word_count": 842,
"cluster_id": "cl_econ_001",
"version_count": 2
}Search Articles
/api/v1/searchFull-text search across all articles with advanced filtering by source, category, language, sentiment, entity, and date range.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
q | string | Required | Search query string |
sources | string[] | Optional | Comma-separated source IDs to filter by |
categories | string[] | Optional | Comma-separated categories |
languages | string[] | Optional | Comma-separated language codes (en, pcm, ha, yo, ig) |
sentiment | string | Optional | Filter by sentiment: positive, negative, neutral, or mixed |
entities | string[] | Optional | Comma-separated entity names |
from_date | string | Optional | Start date in ISO 8601 format (YYYY-MM-DD) |
to_date | string | Optional | End date in ISO 8601 format (YYYY-MM-DD) |
sort_by | string | Optional | Sort field: published_at, relevance, or sentiment |
sort_order | string | Optional | Sort direction: asc or desc (default: desc) |
page | integer | Optional | Page number (default: 1) |
per_page | integer | Optional | Results per page, max 100 (default: 20) |
Example Request
curl -H "X-API-Key: YOUR_API_KEY" \
"https://api.compassng.com/api/v1/search?q=election+results&sentiment=positive&from_date=2025-01-01"Example Response
{
"data": [
{
"id": "x9y8z7w6",
"title": "INEC Announces Final Election Results for Governorship Race",
"summary": "The Independent National Electoral Commission released final results...",
"source": {
"id": "src_03",
"name": "The Guardian",
"domain": "guardian.ng",
"type": "newspaper"
},
"published_at": "2025-03-12T16:00:00Z",
"categories": [
"politics"
],
"sentiment": {
"score": 0.45,
"label": "positive",
"confidence": 0.91
},
"entities": [
{
"text": "INEC",
"type": "ORG",
"salience": 0.95
}
]
}
],
"meta": {
"total": 234,
"page": 1,
"per_page": 10,
"total_pages": 24
},
"links": {
"next": "/api/v1/search?q=election+results&page=2",
"prev": null
}
}Trending Topics
/api/v1/trendingGet currently trending topics and stories based on article volume, recency, and entity clustering. Updated every 15 minutes.
Example Request
curl -H "X-API-Key: YOUR_API_KEY" \
"https://api.compassng.com/api/v1/trending"Example Response
[
{
"topic": "Naira Exchange Rate",
"article_count": 47,
"sentiment_avg": -0.15,
"top_entities": [
{
"text": "CBN",
"type": "ORG",
"salience": 0.94
},
{
"text": "Naira",
"type": "PRODUCT",
"salience": 0.89
}
],
"sample_articles": [
{
"id": "art_001",
"title": "CBN Implements New Forex Policy to Stabilize Naira",
"source": {
"id": "src_01",
"name": "Punch"
},
"published_at": "2025-06-15T08:00:00Z"
}
]
}
]List Sources
/api/v1/sourcesList all available news sources covered by CompassNG with metadata including credibility scores, categories, and article counts.
Example Request
curl -H "X-API-Key: YOUR_API_KEY" \
"https://api.compassng.com/api/v1/sources"Example Response
[
{
"id": "src_01",
"name": "Punch",
"domain": "punchng.com",
"description": "Nigeria's most widely read newspaper",
"logo_url": null,
"country": "NG",
"state": "Lagos",
"language": [
"en"
],
"type": "newspaper",
"categories": [
"general",
"politics",
"business",
"sports"
],
"article_count": 24500,
"credibility_score": 85,
"is_active": true
},
{
"id": "src_02",
"name": "Vanguard",
"domain": "vanguardngr.com",
"description": "Towards a better life for the people",
"logo_url": null,
"country": "NG",
"state": "Lagos",
"language": [
"en"
],
"type": "newspaper",
"categories": [
"general",
"politics",
"business"
],
"article_count": 21300,
"credibility_score": 82,
"is_active": true
}
]Entity Lookup
/api/v1/entities/:nameFind all articles mentioning a specific named entity (person, organization, location, etc.). Useful for tracking media coverage of specific subjects.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
name | string | Required | The entity name to search for (URL-encoded) |
page | integer | Optional | Page number (default: 1) |
per_page | integer | Optional | Results per page, max 100 (default: 20) |
Example Request
curl -H "X-API-Key: YOUR_API_KEY" \
"https://api.compassng.com/api/v1/entities/Bola%20Tinubu"Example Response
{
"data": [
{
"id": "m3n4o5p6",
"title": "President Tinubu Addresses the Nation on Economic Reforms",
"summary": "In a national broadcast, President Bola Tinubu outlined...",
"source": {
"id": "src_05",
"name": "Channels TV",
"domain": "channelstv.com",
"type": "broadcast"
},
"published_at": "2025-06-14T20:00:00Z",
"sentiment": {
"score": 0.3,
"label": "positive",
"confidence": 0.82
}
}
],
"meta": {
"total": 1892,
"page": 1,
"per_page": 20,
"total_pages": 95
},
"links": {
"next": "/api/v1/entities/Bola%20Tinubu?page=2",
"prev": null
}
}Pagination
All list endpoints return paginated responses using a consistent envelope structure. Use the meta and links fields to navigate through results.
Response Envelope
{
"data": [
"... array of results ..."
],
"meta": {
"total": 15420,
"page": 1,
"per_page": 20,
"total_pages": 771
},
"links": {
"next": "/api/v1/articles?page=2&per_page=20",
"prev": null
}
}| Field | Description |
|---|---|
data | Array of result objects for the current page |
meta.total | Total number of matching results across all pages |
meta.page | Current page number (1-indexed) |
meta.per_page | Number of results per page |
meta.total_pages | Total number of available pages |
links.next | Relative URL for the next page, or null if on the last page |
links.prev | Relative URL for the previous page, or null if on the first page |
Errors
The API uses conventional HTTP status codes to indicate success or failure. Codes in the 2xx range indicate success, 4xx indicate a client error, and 5xx indicate a server error.
| Status | Meaning | Description |
|---|---|---|
200 | OK | Request succeeded |
201 | Created | Resource created successfully |
400 | Bad Request | The request was malformed or missing required parameters |
401 | Unauthorized | Missing or invalid API key |
403 | Forbidden | Valid API key but insufficient permissions |
404 | Not Found | The requested resource does not exist |
422 | Unprocessable Entity | Request validation failed — check field-level errors in the response |
429 | Too Many Requests | Rate limit exceeded — see Rate Limits section |
500 | Internal Server Error | Something went wrong on our end — retry or contact support |
Error Response Shape
{
"error": {
"status": 422,
"message": "Validation failed",
"details": {
"q": "Search query is required"
}
}
}Rate Limits
API requests are rate-limited based on your plan tier. When you exceed the limit, you will receive a 429 response with a Retry-After header indicating how many seconds to wait.
Rate Limit Headers
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed in the current window |
X-RateLimit-Remaining | Number of requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the rate limit window resets |
Retry-After | Seconds to wait before retrying (only present on 429 responses) |
Handling Rate Limits
When you receive a 429 response, wait for the number of seconds specified in the Retry-After header before making another request. Implement exponential backoff for production applications.
const response = await fetch(url, { headers });
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get("Retry-After") || "60", 10);
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
// Retry the request
}