EduPrompt API

Integration Guide

Generate curriculum-aligned, African-context lesson plans on demand from your own LMS, app, or website. One authenticated endpoint, no OAuth dance.

How This Works

1
You already have your API key

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.

2
Store it on your server, not in your website's code

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.

3
Your backend calls EduPrompt when a teacher requests a lesson

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.

4
Show the result to your user

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.

💡 No custom backend of your own? If your website or LMS is built entirely on a no-code platform with no way to run server-side code, you'll need a small bridge — even a single serverless function (e.g. a Cloudflare Worker, Vercel/Netlify function, or AWS Lambda) that holds the key and forwards requests. This keeps the key off the public internet while still letting your front-end trigger a generation. Reach out if you're unsure how to set this up for your specific platform — we're happy to help.

Base URL & Authentication

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.

Keep your key server-side only. Call these endpoints from your own backend, never from browser JavaScript — anyone who sees the key in client code can use your quota.

Limits: 100 requests/day per key, resetting at midnight server time.

Generate a Lesson Plan

POST/api/generate-auth

Request fields

FieldRequiredNotes
subjectYese.g. "Mathematics"
gradeYese.g. "Grade 7"
topicNoOmit to let the model pick a suitable topic (max 200 chars)
languageNoDefault "English". The entire lesson — headings, examples, everything — generates in this language. French, Swahili, Yoruba, Hausa, Arabic, Portuguese, and more all work.
curriculumNoDefault "All African Curricula (Hybrid)". e.g. "NERDC", "CBC", "NaCCA", "CAPS", "Cambridge", "IB"
contextNoClassroom context/constraints, max 300 chars — e.g. "rural school, no electricity, 60 students"
styleNoOne of activity, visual, quiz, exam, mapping — adds a themed extra section
classSizeNoDefault "~40 students"
detailNoOne of short (≤300 words), standard (default), detailed (full plan with rubric)

Response

{
  "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

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"
  }'

Node.js / TypeScript

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 }>;
}

Python

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"])

Check Usage / Plan Status

GET/api/v1/status

Same 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..." }
}

Error Responses

StatusMeaningBody
400Missing subject/grade, or a field over its length limit{ "error": "..." }
401Missing or invalid x-api-key{ "error": "Invalid API key." }
429Daily limit (100/day) reached for this key{ "error": "Daily limit reached (100/day)." }
503All 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.

Notes

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.