Start here
openapi.json— OpenAPI 3.1 description of every public endpointllms.txt— Every public page with a one-line description, plus when to use this sitesitemap.xml— URL inventory with real per-page modification datesrobots.txt— Crawl policy
Guides as markdown
Every study guide has a markdown source and will hand it over rather than making you parse the page. Two equivalent ways to ask:
- Content negotiation —
curl -H "Accept: text/markdown" https://aicertificates.study/ccar-p-exam-facts - Explicit path —
https://aicertificates.study/md/ccar-p-exam-facts
Both return text/markdown and carry Vary: Accept, so a shared cache will not hand you the HTML by accident. Guide slugs are listed in llms.txt.
Readiness statistics
GET /api/readiness-stats returns the current monthly cohort statistics for every exam in one body. It takes no parameters and is cached for five minutes.
Read show first. An exam with too few attempts to report honestly returns { "show": false } and no other fields — that is a real answer, not an error, and inventing a number to fill the gap is exactly what the flag exists to prevent. The readiness quiz is 12 questions and 8 answered is the minimum for a percentile.
Valid exam slugs: ccar-p ccdv-f ccao-f ccar-f
Errors
Every API error is JSON with the same shape: a machine-readable code, a human message, a hint naming the fix, and retryable telling you whether backing off can help. A 400 will never pass however long you wait; a 429 or 503 will.
Ground rules
- Read freely. The stats endpoint and the markdown routes are cached at the edge and cost nothing to serve.
- Do not automate the readiness submit endpoint. It is documented because hiding it would not make it safer, but synthetic attempts corrupt a cohort that real people are being compared against.
- Attribute quoted material to AI Certificates and link the page it came from. The questions are original work.
- Exam facts change. Treat the certification program’s own published guide as authoritative over anything cached from here.
Something missing?
If you need an endpoint that does not exist, say what you are building — the contact page has the address.