SdashAPI Reference
A REST API for Nigerian past exam questions (UTME, WASSCE, 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.
JavaScript / TypeScript SDK
Official Node.js and TypeScript SDK for SdashAPI. Give your developers instant access to thousands of past exam questions.
Installation
npm install @sdashapis/sdk # or yarn add @sdashapis/sdk # or pnpm add @sdashapis/sdk
Quick Start
import { SdashAPI } from '@sdashapis/sdk';
// 1. Initialize the client
const api = new SdashAPI({
apiKey: 'YOUR_ACCESS_TOKEN', // Get your token from sdashapi.com/dashboard
});
async function main() {
try {
// 2. Fetch a random chemistry UTME question from 2022
const question = await api.getQuestions({
subject: 'chemistry',
type: 'utme',
year: 2022
});
console.log(question);
/* Output:
{
id: 4821,
question: "Which of the following is the chemical formula for table salt?",
option: { a: "NaCl", b: "KCl", c: "CaCO3", d: "NaOH" },
answer: "a",
...
} */
// 3. Fetch 10 random questions
const questionsList = await api.getQuestions({ limit: 10 });
console.log(`Fetched ${Array.isArray(questionsList) ? questionsList.length : 1} questions`);
} catch (error) {
console.error("Failed to fetch questions:", error.message);
}
}
main();Endpoints Supported
getQuestions(params): Fetch past questions with filters.getSubjects(): List available subjects (Biology, Chemistry, etc.).getExams(): List supported exams (UTME, WASSCE, NECO, etc.).getYears(): List available years.reportQuestion(params): Report issues with questions (typos, wrong answers).
Python SDK
Official Python SDK for SdashAPI - Access Nigerian past exam questions (UTME, WASSCE, NECO, Post-UTME).
Installation
In a virtualenv (see these instructions if you need to create one):
pip3 install sdashapis-sdk
Dependencies & Links
- Dependencies: requests
- PyPI page: pypi.org/project/sdashapis-sdk
- Project JSON: piwheels.org/project/sdashapis-sdk/json
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: utme, wassce, neco, post-utme, university. |
| year | string | optional | 4-digit year e.g. 2020. Coverage: 2001–2026. Get valid years from /v1/years. |
| university | string | optional | Filter questions by university slug/name e.g. unilag. Primarily used for Post-UTME. |
| 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. "UTME", "WASSCE", "NECO", "Post-UTME", "University". |
| examyear | string | 4-digit year as a string e.g. "2023". |
| university | string | null | The university name, if applicable. |
Example 1 — 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",
"university": null
}
}Example 2 — WASSCE (Mathematics)
Specify type=wassce to retrieve WASSCE 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",
"university": null
}
}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",
"university": "UNILAG"
}
}Example — 10 random questions (mixed)
GET /api/v1/q?limit=10 AccessToken: sdash_xxxxxxxxxxxx
V2 API: Metadata & Taxonomy
Use /api/v2/q to receive additional metadata (topics, difficulty, tags, passage text).
{
"id": 8931,
"question": "...",
"metadata": {
"topic": "Organic Chemistry",
"subtopic": "Alkanes",
"difficulty": "medium",
"type": "MCQ",
"skill": "Recall",
"tags": ["hydrocarbons", "covalent"],
"passage": null
}
}V3 API: Explanations
Use /api/v3/q to receive everything in V2 plus a detailed AI-generated or expert explanation block.
{
"id": 8931,
"question": "...",
"metadata": { ... },
"explanation": {
"summary": "Quick summary of the answer.",
"detailed": "Detailed step-by-step reasoning...",
"steps": ["Step 1...", "Step 2..."],
"why_correct": "Option B is correct because...",
"why_others_wrong": {"a": "Incorrect because...", "c": "..."}
}
}V4 API: Intelligence (Similar Questions)
Use /api/v4/q for the main questions. In addition, V4 introduces /api/v4/similar?id=123&limit=5 to fetch questions related to a specific question.
{
"status": 200,
"data": [
{
"id": 8932,
"relationship_type": "similar_concept",
"score": 0.95,
"question": "...",
"answer": "c",
"image": null,
"examtype": "UTME",
"examyear": "2022",
"university": null
}
]
}List Novels (V4)
Returns a list of all literature novels with their basic information and cover image URLs. Supports pagination via page and limit parameters.
{
"status": 200,
"data": [
{
"id": 1,
"title": "Things Fall Apart",
"author": "Chinua Achebe",
"description": "A classic African novel...",
"cover_image": "https://...",
"has_practice_questions": true
}
],
"pagination": {
"total": 12,
"per_page": 10,
"current_page": 1,
"total_pages": 2,
"has_more": true
}
}Novel Details (V4)
Returns the deep JSON structure for a specific novel, including themes, characters, and chapter summaries.
{
"status": 200,
"data": {
"id": 1,
"title": "Things Fall Apart",
"themes": ["Tradition vs. Change", "Masculinity"],
"characters": ["Okonkwo", "Nwoye"],
"chapter_summaries": [
{
"title": "Chapter 1",
"content": "Okonkwo is introduced as a strong wrestler..."
}
]
}
}Novel Practice Questions (V4)
Fetch dedicated practice questions for a specific novel. Supports pagination.
Query parameters
| Param | Type | Description | |
|---|---|---|---|
| novel_id | integer | required | The ID of the novel. |
| page | integer | optional | The page number to fetch. Default: 1. |
| limit | integer | optional | Number of questions per page (maximum 50). Default: 20. |
{
"status": 200,
"data": [
{
"id": 9050,
"question": "What is Okonkwo's greatest fear?",
"option": {
"a": "Failure and weakness",
"b": "The white man",
"c": "The gods",
"d": "His wives"
},
"answer": "a"
}
],
"pagination": {
"total": 50,
"per_page": 20,
"current_page": 1,
"total_pages": 3,
"has_more": true
}
}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.