Agent & API access
For AI assistants, scripts, and agent frameworks
Any signed-in Mathter account can create an API key at /account (admin and support accounts can't -- they are blocked from generating, and get a 403). Once you have one, an AI assistant or your own code can generate worksheet packs for you -- billed to your account under your existing plan, credits, and caps, exactly like generating from the website. Pick whichever of these three matches what you already use; you only need to read one.
Jump to: Claude Desktop, Cursor, or Claude Code · ChatGPT · Code, scripts, and agent frameworks
Claude Desktop, Cursor, or Claude Code
This is the fastest path to a worksheet pack, and the only one of the three that is genuinely zero-to-working in about two minutes: you ask in plain English, and the assistant does the rest. It uses mathter-mcp, a small Model Context Protocol server. You need Node 18 or newer and Git -- npx fetches and builds the server on demand, so there is nothing to install ahead of time. The first start takes a little longer than later ones.
Create a key at /account first (find API access, click Create a key). Once you have it, the reveal screen's Copy MCP config button gives you this block with your real key already filled in -- here is the shape it copies, with a placeholder key:
{
"mcpServers": {
"mathter": {
"command": "npx",
"args": [
"-y",
"github:gahrons/mathter-mcp#133cfe085897c194"
],
"env": {
"MATHTER_API_KEY": "mk_live_YOUR_KEY"
}
}
}
}Claude Desktop -- open Settings → Developer → Edit Config and add the mathter entry to the mcpServers section (or merge this block into your config file). If the file already holds other settings, such as preferences, mcpServers goes next to them at the top level, not inside them -- inside preferences it is silently ignored. Then fully quit Claude Desktop (right-click its icon in the system tray and choose Quit; closing the window leaves it running in the background) and open it again. (The file itself lives at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS and %APPDATA%\Claude\claude_desktop_config.json on Windows, if you would rather edit it directly.)
Claude Code -- one command:
claude mcp add mathter --env MATHTER_API_KEY=mk_live_YOUR_KEY -- npx -y github:gahrons/mathter-mcp#133cfe085897c194Cursor, Windsurf, and similar tools use the same JSON block as Claude Desktop, in whatever file that app uses for MCP servers. Some editors (Zed, for instance) wrap the entry differently, so check their MCP docs for the exact shape -- the command, arguments, and MATHTER_API_KEY are the same everywhere.
Then just ask: “Make me a grade 4 times-tables pack for Friday” or “What math skills can Mathter do for grade 3?” The assistant checks the live skill list itself before generating, so it never has to guess a skill name, and it hands back a PDF file path rather than anything you need to interpret.
ChatGPT
A plain ChatGPT (or Claude) chat window cannot call this API on its own -- its browsing tool fetches pages, it cannot send an authenticated request and receive a PDF back. The one way a ChatGPT user can actually reach it is a custom GPT with an Action, which is honest to set up but not instant: it needs a paid ChatGPT tier (Plus, Team, or Enterprise) and a few minutes of one-time configuration.
- In ChatGPT, create a new GPT (Explore GPTs → Create, or My GPTs → Create a GPT).
- Open Configure, scroll to Actions, and choose Create new action.
- Set Authentication to API Key, Auth Type Bearer, and paste your Mathter key (create one at /account if you haven't).
- Import the schema from a URL:
https://mathter.ca/api/openapi.json - Save, then ask your GPT for a worksheet pack. It calls
GET /api/skillsitself before generating.
Code, scripts, and agent frameworks
Two endpoints, bearer-token auth, and a full machine-readable description at GET https://mathter.ca/api/openapi.json (OpenAPI 3.1 -- the same document the ChatGPT Action above imports).
GET https://mathter.ca/api/skills-- public, no key needed. The live, current list of validskillvalues and which grades each one teaches. This changes over time (an admin can hide a skill), so it is intentionally not repeated here -- read it instead of hardcoding a list.POST https://mathter.ca/api/generate-- generates the pack. SendAuthorization: Bearer mk_live_YOUR_KEYand a JSON body. There is no separate “create job, poll status” step: on success, the response body IS the PDF (Content-Type: application/pdf) -- raw bytes, not JSON. A non-200 response is JSON:{ error, code? }.
curl https://mathter.ca/api/generate \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"skill": "fractions",
"grade": 5,
"theme": "teal",
"style": "modern",
"title": "Friday Fractions",
"difficulty": "medium",
"worksheetCount": 10,
"includeCover": true,
"includeLesson": true,
"workedSolutions": true
}' \
-o pack.pdfThe example uses modern, which every plan includes. Asking for a style your plan doesn't have (for instance classic on a Basic account) is rejected with a 402 and code: "pro_style".
The common options
| Field | Type | Notes |
|---|---|---|
skill | string, required | One of the key values from GET /api/skills, taught at the chosen grade. |
grade | integer, required | 0–12, and must be a grade the chosen skill teaches. |
theme | string, required | One of: teal, tangerine, ocean, plum, berry, forest, slate, crimson, grape, cocoa. Ungated -- every plan has all 10. |
style | string, default modern | One of: modern, classic, studio, notebook, ledger, blueprint. Gated by plan -- see the table below. A style your plan doesn't include is rejected outright, never silently swapped. |
difficulty | string, default medium | One of: easy, medium, hard. Ungated. |
worksheetCount | integer, default 10 | Sheets in the pack, capped by plan -- see the table below. |
title | string, default “Math Lesson” | Printed on the pack. Truncated to 80 characters. |
There are a dozen more optional fields -- a single-number drill, a timed mode, geometry diagrams, a fixed random seed, and more -- each with its own default and gating. The full, current list lives in the OpenAPI document above rather than repeated here, so it can never drift out of sync with what the route actually accepts.
What your plan allows
| Plan | Styles | Worksheets per pack | Credits per month |
|---|---|---|---|
| Basic | modern | 2 | 2 |
| Standard | modern, classic, notebook | 10 | 50 |
| Premium | modern, classic, studio, notebook, ledger, blueprint | 25 | 150 |
Error codes
| Status | When | Message |
|---|---|---|
| 400 | Unknown/mismatched/hidden skill, or a theme outside the list. Checked after the over-quota 402 and the per-account short-window and daily 429s, and before the style 402 (pro_style) and the concurrent-packs 429 -- a caller already over quota or rate-limited sees those first, even with a bad skill. | Invalid configuration. |
| 401 | Missing, malformed, or revoked key. | Sign in required. |
| 402 | Monthly credit quota used up (code: "over_limit"). The message names your plan and quota and suggests the next tier. | varies by plan |
| 402 | Requested style isn't in your plan (code: "pro_style"). | That style is a Premium feature. |
| 403 | Key belongs to an admin account (support-only, cannot generate). | Admin accounts can't generate or purchase. |
| 403 | Your organization's access changed and you have no independent entitlement. | Your organization's Mathter access has changed. Ask your admin for access. |
| 429 | Rate limited -- one of several independent limiters (per-key, short per-account window, daily per-account cap, or too many packs generating at once). Always carries a Retry-After header. | Too many requests, please wait a moment. (wording differs by which limiter tripped) |
| 500 | Unexpected render failure. Safe to retry. | Could not generate PDF. Try again. |
| 503 | Render queue is full (backpressure, not a fault). Carries a Retry-After header. | varies |
A starting point for an agent that already has HTTP
If you're wiring Mathter into your own agent, script, or framework, this paragraph works well as a starting system/instruction message -- it already tells the model to check GET /api/skills first instead of guessing, and that the success response is raw PDF bytes, not JSON. The same text is one click away as Copy prompt on the key reveal screen at /account.
The prompt deliberately contains no key. It tells the agent to read the environment variable MATHTER_API_KEY, so set that variable where your agent runs first (export MATHTER_API_KEY=mk_live_… on macOS and Linux, setx MATHTER_API_KEY mk_live_… on Windows, then open a new terminal). Never paste the key itself into a chat: it would sit in the provider's logs and in any shared or exported conversation.
I have a Mathter account, and my API key is stored in the environment variable MATHTER_API_KEY. Please use it to generate real, printable math worksheet packs for me whenever I ask for worksheets. (This only works if you can run commands or make your own HTTP requests -- it will not work pasted into a plain ChatGPT or Claude chat window, since those can't issue an authenticated request like this one.)
How to call it:
1. Check which skills exist right now: GET https://mathter.ca/api/skills (no key needed). It lists the valid "skill" values and which grades each one teaches -- use this instead of guessing a skill name, since the list changes over time.
2. Generate a pack: POST https://mathter.ca/api/generate with the header "Authorization: Bearer $MATHTER_API_KEY" (let the shell or your HTTP client read the variable -- do not look the value up and write it into anything) and a JSON body containing at least "skill" (one of the keys from step 1), "grade" (0-12), and "theme" (a colour palette -- "teal" is a safe default if I don't say). Ask me for anything else you need, like difficulty or how many worksheets.
3. On success, the response body IS the worksheet pack -- raw PDF bytes, not JSON -- billed to my Mathter account under my existing plan and limits. Save it as a .pdf file; a non-200 response is a JSON error instead.
About the key: it is not in this message on purpose. If MATHTER_API_KEY is not set, stop and tell me -- never ask me to paste the key into this conversation, and never print it back. If a string starting with mk_live_ ever appears in this conversation, it was pasted by mistake: tell me, and I'll revoke it at https://mathter.ca/account and make a new one.Questions this page didn't answer: contact us.