QUICKSTART
Your first request in five minutes.
SukuuData is a REST API for Ghana's education data: schools across all 16 regions, the 2026 GES placement register, and the CSSPS selection rules. It works from any language that can make an HTTPS request. This guide takes you from no account to real data.
1. Get an API key
- Create a free account. The free plan includes 1,000 requests a month.
- In your dashboard, create a key. It starts with
sukuu_live_and is shown only once, so copy it somewhere safe. - Store it as an environment variable, for example
SUKUUDATA_KEY, rather than in your code.
2. Make a request
Send the key in the X-API-Key header. This example finds boarding schools in Ashanti that offer General Science (programme 502):
curl "https://api.sukuudata.com/api/v1/secondary-schools?programme=502&residential=BOARDING®ion=ashanti" \
-H "X-API-Key: YOUR_KEY"// Node 18+ (run this on your server, not in the browser)
const res = await fetch(
"https://api.sukuudata.com/api/v1/secondary-schools?programme=502&residential=BOARDING®ion=ashanti",
{ headers: { "X-API-Key": process.env.SUKUUDATA_KEY } },
);
const body = await res.json();
if (!body.success) throw new Error(`${body.code}: ${body.error}`);
for (const school of body.data) {
console.log(school.secondary.csspsCode, school.name, school.secondary.category);
}import os
import requests
res = requests.get(
"https://api.sukuudata.com/api/v1/secondary-schools",
params={"programme": "502", "residential": "BOARDING", "region": "ashanti"},
headers={"X-API-Key": os.environ["SUKUUDATA_KEY"]},
timeout=15,
)
body = res.json()
if not body["success"]:
raise RuntimeError(f"{body['code']}: {body['error']}")
for school in body["data"]:
print(school["secondary"]["csspsCode"], school["name"], school["secondary"]["category"])<?php
$ch = curl_init("https://api.sukuudata.com/api/v1/secondary-schools?programme=502&residential=BOARDING®ion=ashanti");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["X-API-Key: " . getenv("SUKUUDATA_KEY")],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);
if (!$body["success"]) {
throw new Exception($body["code"] . ": " . $body["error"]);
}
foreach ($body["data"] as $school) {
echo $school["secondary"]["csspsCode"] . " " . $school["name"] . PHP_EOL;
}import 'dart:convert';
import 'package:http/http.dart' as http;
// In a real app, call your own backend, which adds the key (see "Keep your key secret").
Future<void> main() async {
final uri = Uri.https('api.sukuudata.com', '/api/v1/secondary-schools', {
'programme': '502',
'residential': 'BOARDING',
'region': 'ashanti',
});
final res = await http.get(uri, headers: {'X-API-Key': 'YOUR_KEY'});
final body = jsonDecode(res.body) as Map<String, dynamic>;
if (body['success'] != true) throw Exception('${body['code']}: ${body['error']}');
for (final school in body['data']) {
print('${school['secondary']['csspsCode']} ${school['name']}');
}
}3. Read the response
Every response is JSON with a success flag. Lists come with pagination; ask for more with page and limit (up to 100). Here is a trimmed real response:
{
"success": true,
"data": [
{
"id": "gh-way-785317414",
"name": "Achinakrom Senior High School",
"level": "SHS",
"type": "Public",
"region": "Ashanti",
"district": "Ejisu Municipal",
"town": "Achinakrom",
"latitude": 6.6598,
"longitude": -1.4650,
"secondary": {
"csspsCode": "0051606",
"category": "C",
"institutionType": "SHS",
"gender": "MIXED",
"offersDay": true,
"offersBoarding": true,
"programmes": [
{ "code": "502", "name": "General Science", "kind": "GENERAL" }
],
"registerYear": 2026
}
}
],
"pagination": { "page": 1, "limit": 20, "total": 107, "totalPages": 6 }
}Schools in the placement register carry a secondary object with their 7-digit CSSPS code, category (A, B, C or PILOT_PRIVATE), programmes and day or boarding options. registerYear says which GES register the data comes from.
Handle errors
Errors look like { "success": false, "error": "…", "code": "…" }. Branch on code; the error message is for people and may change.
| Status | Code | What to do |
|---|---|---|
| 400 | VALIDATION_ERROR, UNKNOWN_REGION, UNKNOWN_DISTRICT, UNKNOWN_PROGRAMME | Fix the request; the message names the parameter. |
| 401 | MISSING_API_KEY, INVALID_API_KEY | Send a valid key in X-API-Key. |
| 404 | NOT_FOUND | No record with that id or code. |
| 429 | RATE_LIMIT_EXCEEDED | Monthly quota used up. Wait for the reset or move to a bigger plan. |
| 500 | INTERNAL_ERROR | Our fault. Retry later and quote the X-Request-Id header if you contact us. |
Quotas and rate limits
Each response includes X-RateLimit-Limit (your monthly quota), X-RateLimit-Remaining and X-RateLimit-Reset (when the quota resets, as a Unix timestamp). Cache responses where you can: school data changes weekly at most, and the placement register once a year.
Keep your key secret
Anyone who sees your key can use your quota. The API allows browser requests, but for a public website or mobile app, call SukuuData from your own server and pass the results to your frontend. Never commit the key to Git.
Next steps
- Build a school-selection tool with the placement register and choice validation.
- Browse every endpoint and try requests in the interactive API reference.
- Try every request in Postman: open the SukuuData Postman collection, or import the OpenAPI specification to generate a typed client.
- Use the official libraries:
npm install sukuudataorpip install sukuudata(source on GitHub).