Skip to content

API Reference

Every server-side endpoint in the ecosystem. All are Cloudflare Pages Functions (file = route) unless noted. Conventions shared by all: JSON in/out, CORS handled, GET on the AI routes is a health check that reports the resolved provider chain without leaking key values, and every AI route degrades to a clearly labelled [echo provider] stub when no key is configured — an honest failure, never a fake answer.

AI grading & tutoring

POST /ai-code-review — four modes in one route

modePurposeKey request fieldsResponse
helphint for the problem being solvedquestion, code, language{ reply } (markdown)
chatfollow-up turns on a help threadmessages[], problem context{ reply }
askthe general tutor (AskAiPopover)subject, topic, messages[{role,text}]{ reply }
optimizecomplexity/critique of a submissioncode, language, question{ reply } (structured markdown)

History is clipped (last N turns, long messages truncated) before prompting; replies are coerced to JSON via coerceJson/firstBalanced because free models love decorating JSON with prose.

POST /grade-concept

Grades a free-text CS-fundamentals answer against its authored rubric. Body: { question, answer, expected, rubric? }{ verdict, score, feedback }. The system prompt forbids quoting the model answer verbatim in feedback (it would leak the answer into the UI). SQL-flavoured concept questions are judged as text — this route never executes SQL.

POST /evaluate-aptitude

AI coaching layer for aptitude: correctness is decided deterministically client-side (aptitudeEval.js); this route only explains. Body: { question, expected, rubric?, solution?, userAnswer }{ feedback }.

POST /grade-sql-practice

Grades SQL practice answers: result-set comparison happens client-side in sql.js; the AI layer reviews query quality/approach. → { verdict, feedback }.

All four import the shared chain from functions/_ai-providers.js — see AI Pipeline.

Code execution

POST /run-code

Judge0 proxy. Body: { language_id, source_code, stdin?, expected_output?, … } (base64 round-tripped). Applies server-side hard caps regardless of what the client asks for:

EnvDefault
JUDGE0_MAX_CPU_TIME_LIMIT15 s
JUDGE0_MAX_WALL_TIME_LIMIT20 s
JUDGE0_MAX_MEMORY_LIMIT512000 KB
JUDGE0_MAX_STACK_LIMIT128000 KB

Plus JUDGE0_URL, JUDGE0_AUTH_TOKEN. Returns Judge0's verdict payload (status, stdout, time, memory) normalized by the client's judgeRunner.

Content proxies

GET /list-notes?path=… / GET /get-notes?path=…

Proxy GitHub's Contents API into the private Docy repo using server-side GITHUB_TOKEN — directory listing and file body respectively. Exists so the token never ships to the client and Docy can stay private. Missing token → explicit 500 with a "token missing" message, not a silent empty state.

GET /cf-profile?handle=… / GET /cf-status?handle=…

Codeforces proxy (CF has no CORS). cf-profile merges user.info + rating history into one dashboard payload; cf-status returns recent submissions, which CP solve verification scans for OK verdicts. Both back off politely on CF rate limits.

This docs portal

POST /api/ask-docs (lives in this repo, not the website)

The retrieval-grounded docs assistant. Body: { messages[{role,text}], page? }{ reply, sources[{title,path}] }. Ranks the prebuilt index (/ai/docs-map.json), stuffs the top pages as context, answers only from documentation, and returns real source paths (filtered against the index — the model can't invent links). GET = health with the resolved fallback chain. Architecture in AI Pipeline.

Not Functions

Background OA judging and reminder emails are standalone Workers with cron triggers, not request/response endpoints — documented in Cloudflare Workers.

Ediky Workflow — internal engineering documentation.