Core endpoints¶
Endpoints not registered by a plugin: users, projects, settings, i18n, health.
Health¶
i18n catalog¶
Returns the full nested catalog for the requested language.
Falls back to EN if {lang} isn't registered.
{
"common": {"save": "Save", "cancel": "Cancel"},
"settings": {"title": "Settings", "section_language": "Language", ...},
...
}
Users¶
Body:
Response (201):
{
"id": "abc-123",
"name": "Asterios",
"email": "ar@example.com",
"language": "de",
"created_at": "2026-05-19T12:00:00+00:00",
"updated_at": "2026-05-19T12:00:00+00:00"
}
Returns the user. 404 if not found.
Body: any subset of {name, email, language}. Returns the
updated row.
Projects (user-scoped)¶
POST body:
{
"topic": "Spanish grammar",
"goal": "Pass B2 exam",
"timeframe": "6 weeks",
"daily_minutes": 30,
"current_problem": "Tenses",
"active": true
}
Response (201):
{
"id": "p1",
"user_id": "abc-123",
"topic": "Spanish grammar",
"goal": "Pass B2 exam",
"timeframe": "6 weeks",
"daily_minutes": 30,
"current_problem": "Tenses",
"active": true,
"created_at": "2026-05-19T12:00:00+00:00",
"updated_at": "2026-05-19T12:00:00+00:00"
}
Projects (direct)¶
PATCH body: any subset of {topic, goal, timeframe,
daily_minutes, current_problem, active}. Returns the updated
row.
Settings¶
Returns UserSettings with API-key fields as booleans (the backend never sends cleartext keys back):
{
"id": "s1",
"user_id": "abc-123",
"language": "de",
"active_provider": "anthropic",
"has_anthropic_key": true,
"has_openai_key": false,
"has_gemini_key": false,
"model_override_anthropic": "claude-sonnet-4-20250514",
"model_override_openai": null,
"model_override_gemini": null,
"created_at": "2026-05-19T12:00:00+00:00",
"updated_at": "2026-05-19T12:00:00+00:00"
}
Body: any subset of {active_provider, language,
model_override_anthropic, model_override_openai,
model_override_gemini}. Empty string clears an override;
omitting a field leaves it alone.
API keys¶
Body:
Encrypts with Fernet and stores. Returns updated UserSettings
with has_<provider>_key: true.
Clears the key. Returns updated UserSettings with
has_<provider>_key: false.
Curriculum¶
GET /api/users/{user_id}/curricula
POST /api/users/{user_id}/curricula
GET /api/curricula/{curriculum_id}
PATCH /api/curricula/{curriculum_id}
DELETE /api/curricula/{curriculum_id}
Curriculum POST body:
GET /api/curricula/{curriculum_id}/topics
POST /api/curricula/{curriculum_id}/topics
GET /api/topics/{topic_id}
PATCH /api/topics/{topic_id}
DELETE /api/topics/{topic_id}
Topic POST body:
GET /api/curricula/{curriculum_id}/lessons
POST /api/curricula/{curriculum_id}/lessons
GET /api/lessons/{lesson_id}
PATCH /api/lessons/{lesson_id}
DELETE /api/lessons/{lesson_id}
Lesson POST body: