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 here
- 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.
SDKs
CompassNG provides official client libraries so you can integrate the API in your language of choice. Each SDK handles authentication, request building, and response typing out of the box.
TypeScript
@compassng/sdk
npm install @compassng/sdkimport { CompassNG } from "@compassng/sdk";
const client = new CompassNG("YOUR_API_KEY");
const articles = await client.articles.list({ page: 1, perPage: 10 });
console.log(articles.data);Python
compassng
pip install compassngfrom compassng import CompassNG
client = CompassNG("YOUR_API_KEY")
articles = client.articles.list(page=1, per_page=10)
print(articles.data)More Coming Soon
Official SDKs for additional languages are in development. In the meantime, you can use the REST API directly from any HTTP client.
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
{
"success": true,
"message": "Articles retrieved successfully",
"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
{
"success": true,
"message": "Article retrieved successfully",
"data": {
"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
{
"success": true,
"message": "Search results retrieved successfully",
"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
{
"success": true,
"message": "Trending topics retrieved successfully",
"data": [
{
"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
{
"success": true,
"message": "Sources retrieved successfully",
"data": [
{
"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
{
"success": true,
"message": "Entity articles retrieved successfully",
"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
}