Generate curriculum-aligned, African-context lesson plans on demand from your own LMS, app, or website. One authenticated endpoint, no OAuth dance.
It was in the email that approved your access — a string starting with ep_. That's your only credential; there's no separate sign-up or login flow.
Your LMS or website's backend needs to hold the key — as an environment variable or secret, the same way you'd store any other API credential. It must never appear in HTML, browser JavaScript, or anything a visitor's browser can see.
When someone on your platform clicks "generate a lesson plan," your server sends us the subject, grade, and any details (language, curriculum, topic) — we send back the finished plan in a couple of seconds.
The response is markdown text (headings, bullet points, tables). Render it directly if your platform supports markdown, or convert it to HTML/PDF first — whatever fits how your platform already displays content.
All requests go to https://eduprompt.learnscape.africa. Every request needs an x-api-key header — the key you received by email when your access was approved.
Limits: 100 requests/day per key, resetting at midnight server time.
/api/generate-auth| Field | Required | Notes |
|---|---|---|
subject | Yes | e.g. "Mathematics" |
grade | Yes | e.g. "Grade 7" |
topic | No | Omit to let the model pick a suitable topic (max 200 chars) |
language | No | Default "English". The entire lesson — headings, examples, everything — generates in this language. French, Swahili, Yoruba, Hausa, Arabic, Portuguese, and more all work. |
curriculum | No | Default "All African Curricula (Hybrid)". e.g. "NERDC", "CBC", "NaCCA", "CAPS", "Cambridge", "IB" |
context | No | Classroom context/constraints, max 300 chars — e.g. "rural school, no electricity, 60 students" |
style | No | One of activity, visual, quiz, exam, mapping — adds a themed extra section |
classSize | No | Default "~40 students" |
detail | No | One of short (≤300 words), standard (default), detailed (full plan with rubric) |
{
"lesson": "## Mathematics | Grade 7\n**Topic:** Fractions...",
"provider": "Claude (Anthropic)"
}
lesson is markdown text, ready to render or convert to HTML/PDF on your end. provider tells you which AI backend served the request — EduPrompt automatically fails over between providers, so you never need to handle that.
curl -X POST https://eduprompt.learnscape.africa/api/generate-auth \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"subject": "Mathematics",
"grade": "Grade 7",
"topic": "Fractions",
"curriculum": "NERDC",
"language": "English"
}'
async function generateLesson(params: {
subject: string; grade: string; topic?: string; language?: string;
curriculum?: string; style?: 'activity'|'visual'|'quiz'|'exam'|'mapping';
detail?: 'short'|'standard'|'detailed';
}) {
const res = await fetch('https://eduprompt.learnscape.africa/api/generate-auth', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': process.env.EDUPROMPT_API_KEY!,
},
body: JSON.stringify(params),
});
if (!res.ok) {
const { error } = await res.json();
throw new Error(`EduPrompt API error (${res.status}): ${error}`);
}
return res.json() as Promise<{ lesson: string; provider: string }>;
}
import requests
res = requests.post(
"https://eduprompt.learnscape.africa/api/generate-auth",
headers={"x-api-key": "YOUR_API_KEY"},
json={"subject": "Biology", "grade": "Grade 10", "curriculum": "NERDC"},
)
res.raise_for_status()
print(res.json()["lesson"])
/api/v1/statusSame x-api-key header. Useful for showing a "X requests remaining today" indicator, or backing off before hitting the daily limit.
{
"success": true,
"plan": "free",
"usage": { "requests_today": 12, "daily_limit": 100 },
"account": { "name": "Your Organisation", "created": "2026-08-01T..." }
}
| Status | Meaning | Body |
|---|---|---|
| 400 | Missing subject/grade, or a field over its length limit | { "error": "..." } |
| 401 | Missing or invalid x-api-key | { "error": "Invalid API key." } |
| 429 | Daily limit (100/day) reached for this key | { "error": "Daily limit reached (100/day)." } |
| 503 | All AI providers temporarily unavailable | { "error": "Our lesson planner is temporarily busy..." } |
Treat 503 as retryable (with backoff). Treat 429/401 as non-retryable — surface those to a human rather than looping.
There's also a slimmer POST /api/v1/generate (same auth, fewer fields: subject, grade, language, topic, context only, response wrapped as { success, lesson, provider, usage }). Prefer /api/generate-auth above unless you specifically want that simplified shape — the slim version doesn't support curriculum, style, classSize, or detail.