CodeTrain / Developers
CodeTrain developer API
A public, read-only HTTP API over the CodeTrain course catalog, changelog and
roadmap. No account, no key, no signup. Base URL https://api.codetrain.ai.
Quickstart
$ curl -s https://api.codetrain.ai/v1/catalog
That is the whole setup. Every endpoint below is a GET, returns
JSON, and needs no credentials. If you would rather read prose than JSON, every page on this site
also serves markdown: ask for it with Accept: text/markdown.
$ curl -s -H "Accept: text/markdown" https://codetrain.ai/learn/
Endpoints
| Method | Path | Returns |
|---|---|---|
GET | /v1/health | Liveness and the current API version. |
GET | /v1/catalog | Every published course, its classes and their lessons. |
GET | /v1/courses/{course_id} | One course with its live classes. |
GET | /v1/lessons/{lesson_id} | Metadata for one curated lesson: title, blurb, language and step count. Never the step content, because writing the steps is what the learner is here to do. |
GET | /v1/changelog | What shipped, newest first. The same entries as /changelog/. |
GET | /v1/roadmap | Roadmap items grouped by stage. The same data as /roadmap/. |
GET | /v1/referrals/{code} | Whether a Conductor Network referral code belongs to somebody. A bare boolean and nothing else: no name, no id. |
Each endpoint in full
GET /v1/health
Liveness and the current API version.
$ curl -s https://api.codetrain.ai/v1/health
{"status": "ok", "version": "v1"}
GET /v1/catalog
Every published course, its classes and their lessons.
$ curl -s https://api.codetrain.ai/v1/catalog
{"courses": [{"id": "python-intro", "title": "...", "classes": [...]}]}
GET /v1/courses/{course_id}
One course with its live classes.
$ curl -s https://api.codetrain.ai/v1/courses/python-intro
{"id": "python-intro", "title": "...", "classes": [...]}
GET /v1/lessons/{lesson_id}
Metadata for one curated lesson: title, blurb, language and step count. Never the step content, because writing the steps is what the learner is here to do.
$ curl -s https://api.codetrain.ai/v1/lessons/python-basics
{"id": "python-basics", "title": "...", "lang": "python", "steps": 4}
GET /v1/changelog
What shipped, newest first. The same entries as /changelog/.
$ curl -s https://api.codetrain.ai/v1/changelog
{"entries": [{"id": "tutor-examples-2026-08-28", "date": "2026-08-28", "kind": "feature"}]}
GET /v1/roadmap
Roadmap items grouped by stage. The same data as /roadmap/.
$ curl -s https://api.codetrain.ai/v1/roadmap
{"stages": [{"key": "shipped", "label": "Shipped", "items": [...]}]}
GET /v1/referrals/{code}
Whether a Conductor Network referral code belongs to somebody. A bare boolean and nothing else: no name, no id.
$ curl -s https://api.codetrain.ai/v1/referrals/ada
{"valid": true}
Authentication
The /v1 endpoints listed above need none. Everything they return is
already published as a web page on this domain, so putting a key in front of it would protect
nothing and stop an agent reading it.
CodeTrain does have an authenticated API behind the dashboard and the CLI, and it
is not part of this public contract. It is versioned separately, changes without
notice, and is not documented here on purpose: it is an implementation detail of our own clients
rather than an integration surface. If you need something from it, write to
[email protected] and tell us the job you are trying
to do, and we will either add it to /v1 or explain why not.
Rate limits
Read endpoints allow 120 requests per minute per IP address. The referral lookup allows 60 per hour per IP address, because it answers a question about real people to a stranger.
Every response carries the current state of your budget, so a client can slow down before it is refused rather than after:
| Header | Meaning |
|---|---|
RateLimit-Limit | Requests allowed in the current window. |
RateLimit-Remaining | Requests left in the current window. |
RateLimit-Reset | Seconds until the window resets. |
RateLimit-Policy | The window itself, for example
120;w=60. |
Retry-After | Sent only with a 429. Seconds to wait.
Honour this one and you will not see another 429. |
Versioning and deprecation
- The major version is in the path.
/v1is the only version today. - Additive changes ship without a version bump. New endpoints and new fields on an existing response can appear at any time, so parse defensively and ignore what you do not recognise.
- Nothing is removed or renamed inside a version. A breaking change means
/v2, and/v1keeps working. - When an endpoint is on its way out it answers with a
Deprecationheader and aSunsetheader giving the date it stops. The gap is at least 90 days, and the same notice goes in the changelog. - Errors are JSON with a
detailstring and a real HTTP status. A missing course or lesson is a404, never a200with an empty body.
Command line
The CodeTrain CLI runs the tutor locally and serves its own interface on
127.0.0.1. Install it either way round:
$ pip install codetrain-cli
$ curl -fsSL https://codetrain.ai/install.sh | sh
Both put the agent in the same place and install the same launcher, so it does not matter which you pick, and using both does no harm. It keeps itself current: once a day it checks whether the published bundle changed and replaces its own copy if it did. There is nothing to reinstall to get a newer agent.
Four commands need no account at all, which makes them safe for a script to call before anything is set up:
$ codetrain doctor # is the service up, is this install healthy. --json, exit 0 or 1
$ codetrain version # installed agent bundle against the published one
$ codetrain catalog # the curated courses
$ codetrain update # fetch the newest bundle now
The installer checks the bundle against a published SHA-256 before it unpacks
anything. The bundle and its checksum are at
/dist/codetrain-agent.tar.gz. The CLI needs Python and
nothing else, and it talks to https://api.codetrain.ai by default.
It keeps itself current. Once a day it checks whether the published bundle has
changed, and replaces its own copy if it has, verifying the checksum the same way the installer
does. To force it, run codetrain update. To switch it off, set
CODETRAIN_NO_UPDATE=1 and update by hand.
Machine-readable
- OpenAPI 3.1 document for the public API.
- Interactive reference, generated from the same document.
- /llms.txt, which says when to reach for CodeTrain and links every page in markdown.
- /llms-full.txt, the whole public site as one markdown file.
- /sitemap.xml for the canonical URL list.