Documentation

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:

https://sdashapi.com/api/

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 (Terminal)
curl "https://sdashapi.com/api/v1/q?subject=biology" \
  -H "AccessToken: YOUR_ACCESS_TOKEN"
JavaScript (Fetch)
fetch("https://sdashapi.com/api/v1/q?subject=biology", {
  headers: {
    "AccessToken": "YOUR_ACCESS_TOKEN"
  }
})
.then(response => response.json())
.then(data => console.log(data));
PHP (cURL)
<?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;
?>
Python (Requests)
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

GET /api/v1/q

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

ParamTypeDescription
subjectstringoptionalSubject slug e.g. chemistry, mathematics. Get slugs from /v1/subjects.
typestringoptionalExam type slug (Note: use utme for JAMB): utme, wassce, neco, post-utme, university.
yearstringoptional4-digit year e.g. 2020. Coverage: 2001–2026. Get valid years from /v1/years.
idintegeroptionalFetch a specific question by its ID.
limitintegeroptionalNumber 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

FieldTypeDescription
idintegerUnique question ID.
questionstringThe question text.
sectionstring | nullOptional shared passage or instruction block for a group of questions.
optionobjectNested object with keys a, b, c, d (and optionally e) containing the option texts.
answerstringThe correct option key e.g. "b".
solutionstring | nullWorked solution or explanation.
imagestring | nullURL to an image associated with the question, if any.
examtypestringExam name e.g. "JAMB", "WAEC", "NECO", "Post-UTME", "University".
examyearstring4-digit year as a string e.g. "2023".

Example 1 — JAMB / UTME (Chemistry)

Request
GET /api/v1/q?subject=chemistry&type=utme&year=2022
AccessToken: YOUR_ACCESS_TOKEN
Response
{
  "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.

Request
GET /api/v1/q?subject=mathematics&type=wassce&limit=1
AccessToken: YOUR_ACCESS_TOKEN
Response
{
  "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.

Request
GET /api/v1/q?subject=english&type=post-utme&limit=1
AccessToken: YOUR_ACCESS_TOKEN
Response
{
  "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

GET /api/v1/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:

Accounting
slug: accounting
Agriculture
slug: agriculture
Arabic Studies
slug: arabic
Biology
slug: biology
Chemistry
slug: chemistry
Civic Education
slug: civiledu
Commerce
slug: commerce
Computer Studies
slug: computer
CRK
slug: crk
Current Affairs
slug: currentaffairs
Economics
slug: economics
English Language
slug: english
English Literature
slug: englishlit
Fine Art
slug: fineart
Geography
slug: geography
Government
slug: government
Hausa
slug: hausa
History
slug: history
Igbo
slug: igbo
Insurance
slug: insurance
IRK
slug: irk
Mathematics
slug: mathematics
Physics
slug: physics
The Lekki Headmaster
slug: lekki
Yoruba
slug: yoruba
{
  "status": 200,
  "data": [
    { "id": 1, "name": "Biology", "slug": "biology" },
    { "id": 2, "name": "Chemistry", "slug": "chemistry" },
    ...
  ]
}

List exam types

GET /api/v1/exams

Returns all exam types and their slugs (use as the type filter).

List years

GET /api/v1/years

Returns a list of available years as integers, newest first.

Report a question

POST /api/v1/report

Lets your users flag a question that has a wrong answer, typo, or other issue. Send JSON body:

FieldTypeDescription
question_idintegerrequiredThe id from the question object.
report_typestringoptionalOne of: wrong_answer, typo, unclear, other. Default: wrong_answer.
messagestringoptionalExtra detail from the user.
Request
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."
}
Response
{
  "status": 200,
  "message": "Report submitted. Thank you!"
}

Error codes

StatusMeaning
200Request succeeded.
400Bad request — check your parameters.
401Missing or invalid AccessToken.
403Account suspended.
404No questions matched your filters, or unknown endpoint.
405Wrong HTTP method.
429Monthly 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.