Tendersoko Africa API
A professional REST API for accessing real-time public tender opportunities from Kenya, Uganda, Tanzania, Rwanda, and other East African countries. Integrate live tender data into your website or application with a single API key.
Authentication
All API requests require a valid API key. Pass your key using the Authorization header with the Bearer scheme, or as the X-API-Key header.
Authorization Header (Recommended)
Authorization: Bearer sk_live_89d2dd9c288fc69d33cf43ba0c235705b273eb979af72c87
Alternative Header
X-API-Key: sk_live_89d2dd9c288fc69d33cf43ba0c235705b273eb979af72c87
sk_live_ followed by 48 hexadecimal characters. Get your key from your dashboard.Base URL
All API endpoints are relative to the following base URL:
Example Full Request URL
https://api.tendersoko.africa/api/v1/countries/KE/tenders?days=30&category=5
Content-Type: application/json. Always check the status field — true means success.API Playground
Test the API directly in your browser. Enter your API key and select an endpoint to try it out.
Interactive Tester
Live requests against the production API — from your registered domain only
Tender Endpoints
Access tender listings, details, and real-time data.
Returns a list of all countries with available tender data.
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.tendersoko.africa/api/v1/countries"
Response
{
"status": true,
"countries": [
{ "id": 1, "name": "Kenya", "code": "KE" },
{ "id": 2, "name": "Uganda", "code": "UG" },
{ "id": 3, "name": "Tanzania", "code": "TZ" }
]
}
Retrieve tender listings for a specific country with optional filters.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
CC | string | Required | ISO 3166-1 alpha-2 country code: KE, UG, TZ, RW |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
days | integer | Optional | Tenders closing within N days (e.g. 30) |
category | integer | Optional | Filter by category ID |
sector | integer | Optional | Filter by sector ID |
county | integer | Optional | Filter by county/region ID |
status | integer | Optional | Filter by status ID |
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.tendersoko.africa/api/v1/countries/KE/tenders?days=30&category=5"
Response
{
"status": true,
"country": "KE",
"tenders": [
{
"id": 12345,
"title": "Supply of Medical Equipment",
"description": "…",
"category": "Medical Supplies",
"closingDate": "2025-04-15",
"organisation": "Ministry of Health",
"companyLogo": "https://api.tendersoko.africa/api/v1/company_logo/42"
}
]
}
Returns tenders from all countries your subscription allows. Accepts the same filter parameters as the country endpoint.
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.tendersoko.africa/api/v1/tenders?days=14"
Returns full details of a single tender including description, documents list, and organisation info.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | integer | Required | Tender ID |
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.tendersoko.africa/api/v1/tenders/12345"
Response
{
"status": true,
"tender": {
"id": 12345,
"title": "Supply of Medical Equipment",
"description": "Full tender description…",
"category": "Medical Supplies",
"sector": "Health",
"closingDate": "2025-04-15",
"openingDate": "2025-03-01",
"organisation": "Ministry of Health",
"companyLogo": "https://api.tendersoko.africa/api/v1/company_logo/42",
"country": "KE"
}
}
Returns tenders published today across all subscribed countries. Useful for real-time feeds and daily digests.
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.tendersoko.africa/api/v1/today"
Returns tenders that are closing soon. Great for deadline reminder widgets.
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.tendersoko.africa/api/v1/closing"
Document Endpoints
Download tender documents and attachments.
Returns all documents attached to a tender. Use the document IDs with the download endpoint.
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.tendersoko.africa/api/v1/tenders/12345/documents"
Response
{
"status": true,
"documents": [
{ "id": 789, "name": "Tender Notice.pdf", "size": "245 KB" },
{ "id": 790, "name": "Specifications.pdf", "size": "1.2 MB" }
]
}
Streams the document file (PDF, DOCX, etc.) directly. Returns binary content with appropriate Content-Type headers.
<a href> download link with your API key passed via header.curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.tendersoko.africa/api/v1/documents/789/download" \ --output tender-doc.pdf
Returns the main advertisement document for a tender. Binary stream response.
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.tendersoko.africa/api/v1/advert_doc/12345" \ --output advert.pdf
Reference Data
Lookup endpoints for categories, sectors, statuses and counties. Use these IDs in tender filter queries.
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.tendersoko.africa/api/v1/categories"
Response
{
"status": true,
"categories": [
{ "id": 1, "name": "Goods" },
{ "id": 2, "name": "Works" },
{ "id": 3, "name": "Services" }
]
}
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.tendersoko.africa/api/v1/sectors"
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.tendersoko.africa/api/v1/statuses"
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.tendersoko.africa/api/v1/counties"
Media Endpoints
Returns the organisation's logo image. The URL is automatically embedded in tender responses as the companyLogo field — use it directly in <img> tags. Falls back to a default briefcase icon if no logo is available.
<img src="https://api.tendersoko.africa/api/v1/company_logo/42"
alt="Company Logo" style="width:48px;height:48px;object-fit:contain">
Error Codes
All errors return JSON with a status: false field and a message explaining the issue.
{
"status": false,
"message": "Invalid API key",
"code": "INVALID_API_KEY"
}
Bad Request
Invalid endpoint or missing required parameters.
Unauthorized
API key is missing, invalid format, or does not exist in the database.
Forbidden
API key is valid but the request is from an unauthorized domain (domain lock), or the country is not in your subscription.
Not Found
The requested tender or document does not exist.
Rate Limited
You have exceeded your daily request quota. Upgrade your plan for higher limits.
Service Unavailable
The upstream data source is temporarily unavailable. Retry after a few seconds.
Code Examples
Complete working examples in popular languages.
PHP — Display Kenya Tenders
<?php $apiKey = 'sk_live_YOUR_API_KEY'; $url = 'https://api.tendersoko.africa/api/v1/countries/KE/tenders?days=30'; $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30, CURLOPT_HTTPHEADER => ["Authorization: Bearer $apiKey"], ]); $response = curl_exec($ch); curl_close($ch); $data = json_decode($response, true); if ($data['status']) { foreach ($data['tenders'] as $tender) { echo '<h3>' . htmlspecialchars($tender['title']) . '</h3>'; echo '<p>Closes: ' . $tender['closingDate'] . '</p>'; echo '<img src="' . $tender['companyLogo'] . '">'; } }
JavaScript (Fetch) — Display Tenders
const API_KEY = 'sk_live_YOUR_API_KEY'; fetch('https://api.tendersoko.africa/api/v1/countries/KE/tenders', { headers: { 'Authorization': `Bearer ${API_KEY}` } }) .then(r => r.json()) .then(data => { if (!data.status) { console.error(data.message); return; } const container = document.getElementById('tenders'); data.tenders.forEach(t => { container.innerHTML += ` <div class="tender-card"> <img src="${t.companyLogo}" alt="logo"> <h3>${t.title}</h3> <p>Closes: ${t.closingDate}</p> <a href="/tender/${t.id}">View Details</a> </div>`; }); });
Python — Fetch & Print Tenders
import requests API_KEY = 'sk_live_YOUR_API_KEY' headers = {'Authorization': f'Bearer {API_KEY}'} resp = requests.get( 'https://api.tendersoko.africa/api/v1/countries/KE/tenders', headers=headers, params={'days': 30} ) data = resp.json() if data['status']: for tender in data['tenders']: print(f"{tender['title']} — closes {tender['closingDate']}")