Developer documentation

Server-side examples

Call the API from cURL, Node.js, or Python while keeping the bearer key off the client.

Audience
Backend developers
Before you start
An `OTMW_API_KEY` environment variable and Node.js 18+, Python 3, or cURL

cURL

The -i flag lets you inspect usage headers alongside the body.

curl -i -X POST "https://overthemathwall.com/api/public/v1/worksheets" \
  -H "Authorization: Bearer $OTMW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "seed": 20260720,
    "locale": "en",
    "entries": [
      {
        "id": "fractions-1",
        "grade": "grade5",
        "topic": "fractions",
        "difficulty": "medium",
        "count": 10
      }
    ]
  }'

Node.js / TypeScript

This example uses the built-in fetch in Node 18 or later. In production, add a timeout, Retry-After handling, and the ambiguous-outcome policy described in the errors guide.

const apiKey = process.env.OTMW_API_KEY;
if (!apiKey) throw new Error("OTMW_API_KEY is required");

const response = await fetch(
  "https://overthemathwall.com/api/public/v1/worksheets",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${apiKey}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      seed: 20260720,
      locale: "en",
      entries: [
        {
          id: "fractions-1",
          grade: "grade5",
          topic: "fractions",
          difficulty: "medium",
          count: 10,
        },
      ],
    }),
  },
);

const body = await response.json();
if (!response.ok) {
  throw new Error(`OTMW ${response.status}: ${body.error?.code}`);
}

console.log(body.data.entries[0].problems);

Python 3

The example uses only the standard library and treats HTTP error responses as JSON when possible.

import json
import os
import urllib.error
import urllib.request

api_key = os.environ["OTMW_API_KEY"]
payload = json.dumps({
    "seed": 20260720,
    "locale": "en",
    "entries": [{
        "id": "fractions-1",
        "grade": "grade5",
        "topic": "fractions",
        "difficulty": "medium",
        "count": 10,
    }],
}).encode("utf-8")

request = urllib.request.Request(
    "https://overthemathwall.com/api/public/v1/worksheets",
    data=payload,
    method="POST",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
    },
)

try:
    with urllib.request.urlopen(request, timeout=30) as response:
        body = json.load(response)
        print(body["data"]["entries"][0]["problems"])
except urllib.error.HTTPError as error:
    body = json.load(error)
    raise RuntimeError(
        f"OTMW {error.code}: {body.get('error', {}).get('code')}"
    ) from error

Exercise the other outputs

Download the Postman collection to run every route with an apiKey variable. For a realistic reference integration, use mock-partner: its browser talks to its Node server, and only that server adds the key.

git clone https://github.com/Omonimo/cautious-enigma.git
cd cautious-enigma/mock-partner
OTMW_API_KEY="$OTMW_API_KEY" \
OTMW_API_BASE="https://overthemathwall.com" \
node server.mjs
# Open http://localhost:4000