Download OpenAPI specification:
Verified African exam content & timed mock-exam engine.
The MirrorMingo Exam API is the public, developer-facing surface for MirrorMingo's verified exam-prep platform. It exposes:
All content is curriculum-grounded and verified against official exam-board sources. This API never returns AI-fabricated questions.
Every request must include a MirrorMingo API key as a bearer token:
Authorization: Bearer mirrormingo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Create and manage keys from the Developer dashboard. Keys are shown only once at creation time — store them securely and never embed them in client-side code.
The API is versioned in the path (/v1). Breaking changes ship under a new
major version; additive changes (new fields, new endpoints) may appear
within v1 without notice, so clients should ignore unknown fields.
Requests are rate limited per API key. The current allowance is returned on
every response via the RateLimit-* headers. On exhaustion the API responds
with 429 Too Many Requests and a Retry-After header.
Returns the catalog of exams MirrorMingo supports, optionally filtered by country. Each entry carries enough metadata to render a picker.
| country | string Full country name to prioritise locally relevant exams (e.g. |
| country_code | string = 2 characters ISO 3166-1 alpha-2 country code (e.g. |
{- "exams": [
- {
- "exam_key": "jamb",
- "name": "Joint Admissions and Matriculation Board",
- "category": "university_admission",
- "country": "Nigeria",
- "duration_min": 120
}
]
}Full specification for one exam — sections, timing, question types and scoring.
| exam_key required | string non-empty The exam identifier (e.g. |
{- "exam_key": "string",
- "name": "string",
- "category": "string",
- "country": "string",
- "duration_min": 0,
- "sections": [
- {
- "name": "string",
- "duration_min": 0,
- "questions": 0,
- "question_types": [
- "string"
], - "skills": [
- "string"
]
}
], - "scoring": { }
}Official exam-board sites and verified past-question sources for the exam.
| exam_key required | string non-empty The exam identifier (e.g. |
{- "exam_key": "string",
}A suggested week-by-week study path for the exam.
| exam_key required | string non-empty The exam identifier (e.g. |
{- "exam_key": "string",
- "study_weeks": 0,
- "study_hours_total": 0,
- "study_path": [
- { }
]
}Lists the verified past-question papers available for an exam, grouped
by year. Use a paper_id from this response to open a mock attempt.
| exam_key required | string non-empty The exam identifier (e.g. |
{- "exam_key": "string",
- "total_papers": 0,
- "years": [
- {
- "year": 2023,
- "papers": [
- {
- "paper_id": "jamb-mathematics-2023",
- "title": "JAMB Mathematics 2023",
- "subject": "Mathematics",
- "year": 0,
- "question_count": 0
}
]
}
]
}Opens a verified paper into a new timed mock-exam attempt and returns the
first page of questions. The returned attempt_id is used to page through
questions and to submit answers.
| exam_key required | string non-empty The exam identifier (e.g. |
| paper_id required | string [ 6 .. 160 ] characters A |
| question_offset | integer >= 0 Default: 0 |
| question_limit | integer [ 1 .. 20 ] Default: 9 |
{- "paper_id": "string",
- "question_offset": 0,
- "question_limit": 9
}{- "attempt_id": "string",
- "paper_id": "string",
- "question_count": 0,
- "questions": [
- {
- "question_number": 0,
- "prompt": "string",
- "options": {
- "A": "12",
- "B": "14",
- "C": "16",
- "D": "18"
}, - "page": 0,
- "has_visual": true
}
]
}Loads one page of questions for a paper, for paging through long papers.
| exam_key required | string non-empty The exam identifier (e.g. |
| paper_id required | string [ 6 .. 160 ] characters |
| question_offset | integer >= 0 Default: 0 |
| question_limit | integer [ 1 .. 20 ] Default: 9 |
{- "paper_id": "string",
- "question_offset": 0,
- "question_limit": 9
}{- "questions": [
- {
- "question_number": 0,
- "prompt": "string",
- "options": {
- "A": "12",
- "B": "14",
- "C": "16",
- "D": "18"
}, - "page": 0,
- "has_visual": true
}
], - "total": 0
}Submits learner answers for an attempt and returns scored feedback.
| exam_key required | string non-empty The exam identifier (e.g. |
| attempt_id required | string [ 6 .. 160 ] characters |
required | object Map of question number (as string) to chosen option letter. |
| status | string Default: "submitted" Enum: "submitted" "expired" "abandoned" |
{- "attempt_id": "string",
- "answers": {
- "1": "C",
- "2": "A",
- "3": "D"
}, - "status": "submitted"
}{- "success": true,
- "feedback": { }
}Lists prior mock-exam attempts for the authenticated key, newest first.
| exam_key required | string non-empty The exam identifier (e.g. |
| limit | integer [ 1 .. 50 ] Default: 10 |
| offset | integer >= 0 Default: 0 |
{- "attempts": [
- {
- "attempt_id": "string",
- "paper_id": "string",
- "score": 0,
- "submitted_at": "2019-08-24T14:15:22Z"
}
], - "total": 0
}