# info.summary
The learning graph over HTTP: topics, what comes before them, and what they open up.

# info.description
1,690 topics ordered by prerequisites. LightMySky tracks what a learner knows and brings a topic back before it is forgotten.

The catalog routes below are open: no key, no sign-up, no rate limit published.
Be reasonable, cache what you fetch, and name your agent in the User-Agent header.
Learner routes (mastery, sessions, reports) belong to one account and need
`Authorization: Bearer <api key>`; they are not listed here because a key is
issued per account. Every response is `{ "data": ... }`; a failure carries an
HTTP status and `{ "error": ..., "code": ..., "status": ... }`.

Every answer carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`:
600 requests a minute, counted against the API key when there is one and the caller
IP otherwise. Over it, the answer is `429` with `Retry-After`.

A write can carry `Idempotency-Key`. A repeat of the same key on the same path within
24 hours returns the first answer again, marked `Idempotency-Replayed: true`.

Versioning: the path carries the major version. A breaking change arrives as a new
one; the old version keeps answering and, once a retirement date exists, says so in a
`Sunset` header (RFC 8594) and a `Deprecation` header for at least six months first.

# info.license.name
Taxonomy under ODbL and CC BY-SA 4.0; lessons by LightMySky

# x-api-lifecycle.sunset_policy
A version that is going away carries Deprecation and Sunset headers (RFC 8594) naming the date, and keeps answering for at least six months after that first warning. Nothing is deprecated today.

# x-rate-limit-policy.partition
API key when there is one, caller IP otherwise

# x-rate-limit-policy.over_limit
429 with a Retry-After header and code rate_limited

# x-idempotency.note
A repeat of the same key on the same path returns the first answer with Idempotency-Replayed: true. Only answers under 400 are kept, so a request that failed can be fixed and sent again under the same key.

# paths./api/v1/topics.get.description
Free-text search with optional filters. Returns the matching topics.

# paths./api/v1/topics.get.parameters[].description
Free text. An empty value returns the first matches by relevance.

# paths./api/v1/topics.get.parameters[].description
Restrict to one subject, for example `Mathematics`.

# paths./api/v1/topics.get.parameters[].description
Opaque cursor from a previous answer's next_cursor. Absent means the first page.

# paths./api/v1/topics.get.responses.200.content.application/json.schema.properties.next_cursor.description
Pass back as ?cursor= for the next page; null on the last one.

# paths./api/v1/topics.get.responses.404.description
Something went wrong. The code says what, the message says it in English.

# paths./api/v1/topics/batch.get.description
Up to 100 ids at once. An id with no topic behind it comes back as null in place, so one bad id does not fail the batch.

# paths./api/v1/topics/batch.get.responses.200.description
One entry per id, in the order asked for.

# paths./api/v1/topics/batch.get.responses.400.description
Something went wrong. The code says what, the message says it in English.

# paths./api/v1/topics/batch.post.description
The same as the GET, for a list of ids too long for a query string.

# paths./api/v1/topics/batch.post.responses.200.description
One entry per id, in the order asked for.

# paths./api/v1/topics/batch.post.responses.400.description
Something went wrong. The code says what, the message says it in English.

# paths./api/v1/topics/{id}.get.description
Name, description, subject, area, age range and the evidence a learner shows.

# paths./api/v1/topics/{id}.get.parameters[].description
Topic id, for example `mt_uj95V0aLVS`. Ids are stable across renames.

# paths./api/v1/topics/{id}.get.responses.404.description
Something went wrong. The code says what, the message says it in English.

# paths./api/v1/topics/{id}/content.get.description
The lesson sections, worked solutions and practice questions, as JSON.

# paths./api/v1/topics/{id}/content.get.parameters[].description
Topic id, for example `mt_uj95V0aLVS`. Ids are stable across renames.

# paths./api/v1/topics/{id}/content.get.responses.404.description
Something went wrong. The code says what, the message says it in English.

# paths./api/v1/topics/{id}/prerequisites.get.description
The topics this one depends on, each with the strength of the link and the reason for it.

# paths./api/v1/topics/{id}/prerequisites.get.parameters[].description
Topic id, for example `mt_uj95V0aLVS`. Ids are stable across renames.

# paths./api/v1/topics/{id}/prerequisites.get.responses.200.content.application/json.schema.properties.next_cursor.description
Pass back as ?cursor= for the next page; null on the last one.

# paths./api/v1/topics/{id}/prerequisites.get.responses.404.description
Something went wrong. The code says what, the message says it in English.

# paths./api/v1/topics/{id}/unlocks.get.description
The topics that become reachable once this one is known.

# paths./api/v1/topics/{id}/unlocks.get.parameters[].description
Topic id, for example `mt_uj95V0aLVS`. Ids are stable across renames.

# paths./api/v1/topics/{id}/unlocks.get.responses.200.content.application/json.schema.properties.next_cursor.description
Pass back as ?cursor= for the next page; null on the last one.

# paths./api/v1/topics/{id}/unlocks.get.responses.404.description
Something went wrong. The code says what, the message says it in English.

# paths./api/v1/subjects.get.description
Each subject with its topic count and the ages it covers.

# paths./api/v1/subjects.get.responses.200.content.application/json.schema.properties.next_cursor.description
Pass back as ?cursor= for the next page; null on the last one.

# paths./api/v1/subjects.get.responses.404.description
Something went wrong. The code says what, the message says it in English.

# paths./api/v1/standards/{key}/topics.get.description
Which topics answer a given curriculum objective, across the frameworks that are mapped.

# paths./api/v1/standards/{key}/topics.get.parameters[].description
Curriculum code, for example a Common Core or national curriculum key.

# paths./api/v1/standards/{key}/topics.get.responses.200.content.application/json.schema.properties.next_cursor.description
Pass back as ?cursor= for the next page; null on the last one.

# paths./api/v1/standards/{key}/topics.get.responses.404.description
Something went wrong. The code says what, the message says it in English.

# paths./api/v1/packs/format.get.description
The JSON an author or an agent writes to add topics of its own.

# paths./api/v1/packs/format.get.responses.404.description
Something went wrong. The code says what, the message says it in English.

# paths./ask.get.description
An NLWeb /ask endpoint over the topic graph. Returns the topics that answer a natural-language question, each with its own schema.org LearningResource. Streams Server-Sent Events by default; pass streaming=false, or Accept: application/json, for one JSON body. No model runs here, so the same question always returns the same answer.

# paths./ask.get.parameters[].description
list (default), summarize, or generate. This site answers generate as summarize, because nothing is generated.

# paths./ask.get.parameters[].description
false or 0 for a single JSON body instead of Server-Sent Events.

# paths./ask.get.parameters[].description
Carried through to the answer; generated from the query when absent.

# paths./ask.get.parameters[].description
Accepted for protocol compatibility. This domain serves one site.

# paths./ask.get.responses.200.content.text/event-stream.schema.description
data: lines carrying message_type query_analysis, summary, result_batch and complete.

# paths./ask.get.responses.400.description
Something went wrong. The code says what, the message says it in English.

# components.schemas.Error.description
Every failure has this shape. Branch on `code`; show `error` to a person.

# components.schemas.Error.properties.documentation.description
Where to read about the endpoint, on a 404 under /api/v1.

# components.securitySchemes.bearerAuth.description
Needed only for learner routes. Keys are issued from the account that owns the learners.