API Documentation

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.

REST
JSON API
4+
Countries
13
Endpoints
99%
Uptime

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.

Your API key is domain-locked. Requests are only accepted from the domain you registered. Keep your key secret — never expose it in client-side code or public repositories.

Authorization Header (Recommended)

HTTP Header
Authorization: Bearer sk_live_89d2dd9c288fc69d33cf43ba0c235705b273eb979af72c87

Alternative Header

HTTP Header
X-API-Key: sk_live_89d2dd9c288fc69d33cf43ba0c235705b273eb979af72c87
API keys follow the format 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:

https://api.tendersoko.africa/api/v1

Example Full Request URL

URL
https://api.tendersoko.africa/api/v1/countries/KE/tenders?days=30&category=5
All responses are JSON with 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

Response

      

Tender Endpoints

Access tender listings, details, and real-time data.

GET /countries List all available countries

Returns a list of all countries with available tender data.

cURL
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" }
  ]
}
GET /countries/{CC}/tenders Tenders by country

Retrieve tender listings for a specific country with optional filters.

Path Parameters

ParameterTypeRequiredDescription
CCstringRequiredISO 3166-1 alpha-2 country code: KE, UG, TZ, RW

Query Parameters

ParameterTypeRequiredDescription
daysintegerOptionalTenders closing within N days (e.g. 30)
categoryintegerOptionalFilter by category ID
sectorintegerOptionalFilter by sector ID
countyintegerOptionalFilter by county/region ID
statusintegerOptionalFilter by status ID
cURL
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"
    }
  ]
}
GET /tenders All tenders (all countries)

Returns tenders from all countries your subscription allows. Accepts the same filter parameters as the country endpoint.

cURL
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.tendersoko.africa/api/v1/tenders?days=14"
GET /tenders/{id} Single tender details

Returns full details of a single tender including description, documents list, and organisation info.

Path Parameters

ParameterTypeRequiredDescription
idintegerRequiredTender ID
cURL
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"
  }
}
GET /today Tenders published today

Returns tenders published today across all subscribed countries. Useful for real-time feeds and daily digests.

cURL
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.tendersoko.africa/api/v1/today"
GET /closing Closing soon tenders

Returns tenders that are closing soon. Great for deadline reminder widgets.

cURL
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.tendersoko.africa/api/v1/closing"

Document Endpoints

Download tender documents and attachments.

GET /tenders/{id}/documents List tender documents

Returns all documents attached to a tender. Use the document IDs with the download endpoint.

cURL
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" }
  ]
}
GET /documents/{id}/download Download document (binary)

Streams the document file (PDF, DOCX, etc.) directly. Returns binary content with appropriate Content-Type headers.

This endpoint returns a binary file, not JSON. Use it as an <a href> download link with your API key passed via header.
cURL (save to file)
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.tendersoko.africa/api/v1/documents/789/download" \
  --output tender-doc.pdf
GET /advert_doc/{id} Tender advert document

Returns the main advertisement document for a tender. Binary stream response.

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

GET /categories List all categories
cURL
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" }
  ]
}
GET /sectors List all sectors
cURL
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.tendersoko.africa/api/v1/sectors"
GET /statuses List tender statuses
cURL
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.tendersoko.africa/api/v1/statuses"
GET /counties List counties/regions
cURL
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.tendersoko.africa/api/v1/counties"

Media Endpoints

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"
}
400

Bad Request

Invalid endpoint or missing required parameters.

401

Unauthorized

API key is missing, invalid format, or does not exist in the database.

403

Forbidden

API key is valid but the request is from an unauthorized domain (domain lock), or the country is not in your subscription.

404

Not Found

The requested tender or document does not exist.

429

Rate Limited

You have exceeded your daily request quota. Upgrade your plan for higher limits.

503

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

JavaScript
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

Python
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']}")