SdashAPI Reference
A REST API for Nigerian past exam questions (UTME, WAEC, NECO, Post-UTME) with answers and solutions.
Introduction
SdashAPI returns JSON. Base URL:
All responses have a top-level status field (HTTP status code) and either a data field (success) or a message field (error).
Authentication & Making Requests
To securely access the API, you must include your unique AccessToken in the HTTP headers of every request. You can locate your Access Token on your dashboard.
Here are examples of how to make your first API call using different programming languages:
curl "https://sdashapi.com/api/v1/q?subject=biology" \ -H "AccessToken: YOUR_ACCESS_TOKEN"
fetch("https://sdashapi.com/api/v1/q?subject=biology", {
headers: {
"AccessToken": "YOUR_ACCESS_TOKEN"
}
})
.then(response => response.json())
.then(data => console.log(data));<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://sdashapi.com/api/v1/q?subject=biology");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"AccessToken: YOUR_ACCESS_TOKEN"
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>import requests
url = "https://sdashapi.com/api/v1/q?subject=biology"
headers = {"AccessToken": "YOUR_ACCESS_TOKEN"}
response = requests.get(url, headers=headers)
print(response.json())Note: You can also pass the token as a URL query parameter (?token=YOUR_TOKEN) for quick browser testing, but using the HTTP header is strongly recommended for security in production applications.
Don't have a token yet? Create a free account to generate one.
Fetch questions
Returns one or more past-exam questions from our bank (2001–2026). By default returns one random question. Use query parameters to filter by subject, exam type and year.
Query parameters
| Param | Type | Description | |
|---|---|---|---|
| subject | string | optional | Subject slug e.g. chemistry, mathematics. Get slugs from /v1/subjects. |
| type | string | optional | Exam type slug (Note: use utme for JAMB): utme, wassce, neco, post-utme, university. |
| year | string | optional | 4-digit year e.g. 2020. Coverage: 2001–2026. Get valid years from /v1/years. |
| id | integer | optional | Fetch a specific question by its ID. |
| limit | integer | optional | Number of questions to return (maximum 50 per request). Default: 1. When limit=1 the response data is an object; limit>1 returns an array. |
Response object schema
| Field | Type | Description |
|---|---|---|
| id | integer | Unique question ID. |
| question | string | The question text. |
| section | string | null | Optional shared passage or instruction block for a group of questions. |
| option | object | Nested object with keys a, b, c, d (and optionally e) containing the option texts. |
| answer | string | The correct option key e.g. "b". |
| solution | string | null | Worked solution or explanation. |
| image | string | null | URL to an image associated with the question, if any. |
| examtype | string | Exam name e.g. "JAMB", "WAEC", "NECO", "Post-UTME", "University". |
| examyear | string | 4-digit year as a string e.g. "2023". |
Example 1 — JAMB / UTME (Chemistry)
GET /api/v1/q?subject=chemistry&type=utme&year=2022 AccessToken: YOUR_ACCESS_TOKEN
{
"status": 200,
"data": {
"id": 4821,
"question": "Which of the following is the chemical formula for table salt?",
"section": null,
"option": {
"a": "NaCl",
"b": "KCl",
"c": "CaCO3",
"d": "NaOH"
},
"answer": "a",
"solution": "NaCl is sodium chloride...",
"image": null,
"examtype": "UTME",
"examyear": "2022"
}
}Example 2 — WASSCE / WAEC (Mathematics)
Specify type=wassce to retrieve WAEC past questions.
GET /api/v1/q?subject=mathematics&type=wassce&limit=1 AccessToken: YOUR_ACCESS_TOKEN
{
"status": 200,
"data": {
"id": 5102,
"question": "Solve for x: 2x + 5 = 15",
"section": null,
"option": {
"a": "2",
"b": "5",
"c": "10",
"d": "20"
},
"answer": "b",
"solution": "Subtract 5 from both sides: 2x = 10. Divide by 2: x = 5.",
"image": null,
"examtype": "WASSCE",
"examyear": "2021"
}
}Example 3 — Post-UTME (English Language)
Specify type=post-utme for university screening questions.
GET /api/v1/q?subject=english&type=post-utme&limit=1 AccessToken: YOUR_ACCESS_TOKEN
{
"status": 200,
"data": {
"id": 8931,
"question": "Choose the word nearest in meaning to the italicized word: His behavior was rather erratic.",
"section": null,
"option": {
"a": "predictable",
"b": "inconsistent",
"c": "polite",
"d": "dangerous"
},
"answer": "b",
"solution": "Erratic means not even or regular in pattern or movement; unpredictable or inconsistent.",
"image": null,
"examtype": "Post-UTME",
"examyear": "2019"
}
}Example — 10 random questions (mixed)
GET /api/v1/q?limit=10 AccessToken: sdash_xxxxxxxxxxxx
List subjects
Returns all available subjects and their slugs (use the slug as the subject filter).
Available Subjects
You can also use any of the following slugs directly in your API requests:
{
"status": 200,
"data": [
{ "id": 1, "name": "Biology", "slug": "biology" },
{ "id": 2, "name": "Chemistry", "slug": "chemistry" },
...
]
}List exam types
Returns all exam types and their slugs (use as the type filter).
List years
Returns a list of available years as integers, newest first.
Report a question
Lets your users flag a question that has a wrong answer, typo, or other issue. Send JSON body:
| Field | Type | Description | |
|---|---|---|---|
| question_id | integer | required | The id from the question object. |
| report_type | string | optional | One of: wrong_answer, typo, unclear, other. Default: wrong_answer. |
| message | string | optional | Extra detail from the user. |
POST /api/v1/report
AccessToken: sdash_xxxxxxxxxxxx
Content-Type: application/json
{
"question_id": 4821,
"report_type": "wrong_answer",
"message": "Option B should be the correct answer."
}{
"status": 200,
"message": "Report submitted. Thank you!"
}Error codes
| Status | Meaning |
|---|---|
| 200 | Request succeeded. |
| 400 | Bad request — check your parameters. |
| 401 | Missing or invalid AccessToken. |
| 403 | Account suspended. |
| 404 | No questions matched your filters, or unknown endpoint. |
| 405 | Wrong HTTP method. |
| 429 | Monthly quota exceeded — upgrade your plan. |
Rate limits & quotas
API calls are unlimited for all our paid plans as detailed on our Pricing page.
Need a custom enterprise solution? Contact us.