pediatric-ai-scribe-v3/docs/api-reference.md
Daniel 869fa14a77 v6.1: Turnstile bot protection, LiteLLM provider, PPTX tables, audio backup fixes, docs
- Add Cloudflare Turnstile to login, register, and password reset forms
- Switch AI provider to LiteLLM, transcription to OpenAI Whisper
- Change domain to scribe.pedshub.com
- Fix PPTX export: add tables, bold/italic, numbered lists, code blocks, blockquotes
- Fix announcement banner close button (CSP was blocking inline onclick)
- Fix auth middleware: empty Bearer token now falls through to cookie auth
- Fix audio backups: only save on transcription failure, stop auto-deleting on success
- Soften AI correction injection to prevent model hallucination from correction history
- Fix LiteLLM TTS model name handling (no incorrect openai/ prefix)
- Expand AI instructions textarea in Learning Hub CMS
- Update README for v6 with all features and providers
- Add comprehensive docs/: architecture, API reference, database schema,
  authentication, AI providers, speech, learning hub, configuration, deployment
2026-04-04 22:56:24 +02:00

2144 lines
38 KiB
Markdown

# API Reference
Complete endpoint reference for the PedAI application. All endpoints are prefixed with the application base URL. Unless noted otherwise, authenticated endpoints require a valid JWT token passed via cookie or `Authorization: Bearer <token>` header.
---
## Table of Contents
- [Authentication](#authentication)
- [OIDC / SSO](#oidc--sso)
- [AI Generation](#ai-generation)
- [Transcription](#transcription)
- [Text-to-Speech](#text-to-speech)
- [Models](#models)
- [Encounters](#encounters)
- [Memories](#memories)
- [Audio Backups](#audio-backups)
- [Documents](#documents)
- [User Preferences](#user-preferences)
- [Nextcloud Integration](#nextcloud-integration)
- [Learning Hub (Public)](#learning-hub-public)
- [Learning Hub CMS (Moderator+)](#learning-hub-cms-moderator)
- [Admin - Users](#admin---users)
- [Admin - Configuration](#admin---configuration)
- [Logs](#logs)
- [Milestones (Admin)](#milestones-admin)
- [Health](#health)
---
## Authentication
Base path: `/api/auth/`
### POST /api/auth/register
Register a new user account. The first user to register is automatically assigned the admin role. Requires Cloudflare Turnstile verification. A verification email is sent on success.
- **Auth required:** No
- **Request body:**
```json
{
"name": "string",
"email": "string",
"password": "string",
"turnstileToken": "string"
}
```
- **Response:**
```json
{
"success": true,
"message": "Registration successful. Please check your email to verify your account."
}
```
---
### GET /api/auth/verify-email
Verify a user's email address via the link sent during registration.
- **Auth required:** No
- **Query parameters:**
| Parameter | Type | Description |
|-----------|--------|--------------------------------------|
| `token` | string | Email verification token from the link |
- **Response:** Redirects to the login page with a success or error message.
---
### POST /api/auth/resend-verification
Resend the email verification link.
- **Auth required:** No
- **Request body:**
```json
{
"email": "string"
}
```
- **Response:**
```json
{
"success": true,
"message": "Verification email sent."
}
```
---
### POST /api/auth/login
Authenticate a user. Supports optional TOTP two-factor authentication. On success, sets an HTTP-only JWT cookie and returns user data.
- **Auth required:** No
- **Request body:**
```json
{
"email": "string",
"password": "string",
"totpCode": "string (optional, required if 2FA is enabled)",
"turnstileToken": "string"
}
```
- **Response:**
```json
{
"success": true,
"token": "jwt-string",
"user": {
"id": "number",
"name": "string",
"email": "string",
"role": "admin | moderator | user"
}
}
```
If 2FA is enabled but `totpCode` is not provided:
```json
{
"requires2FA": true
}
```
---
### POST /api/auth/setup-2fa
Generate a TOTP secret and QR code for setting up two-factor authentication.
- **Auth required:** Yes
- **Request body:** None
- **Response:**
```json
{
"secret": "string",
"qrCode": "string (data URI)"
}
```
---
### POST /api/auth/verify-2fa
Verify a TOTP code and enable two-factor authentication for the user.
- **Auth required:** Yes
- **Request body:**
```json
{
"code": "string"
}
```
- **Response:**
```json
{
"success": true,
"message": "2FA enabled successfully."
}
```
---
### POST /api/auth/disable-2fa
Disable two-factor authentication. Requires password confirmation.
- **Auth required:** Yes
- **Request body:**
```json
{
"password": "string"
}
```
- **Response:**
```json
{
"success": true,
"message": "2FA disabled successfully."
}
```
---
### POST /api/auth/forgot-password
Initiate password reset. Sends a reset link to the user's email.
- **Auth required:** No
- **Request body:**
```json
{
"email": "string",
"turnstileToken": "string"
}
```
- **Response:**
```json
{
"success": true,
"message": "If an account exists with that email, a reset link has been sent."
}
```
---
### POST /api/auth/reset-password
Reset the user's password using a valid reset token.
- **Auth required:** No
- **Request body:**
```json
{
"token": "string",
"password": "string"
}
```
- **Response:**
```json
{
"success": true,
"message": "Password reset successfully."
}
```
---
### POST /api/auth/logout
Log out the current user by clearing the JWT cookie.
- **Auth required:** No
- **Request body:** None
- **Response:**
```json
{
"success": true,
"message": "Logged out."
}
```
---
### GET /api/auth/me
Retrieve the currently authenticated user's profile.
- **Auth required:** Yes
- **Response:**
```json
{
"id": "number",
"name": "string",
"email": "string",
"role": "admin | moderator | user",
"twoFactorEnabled": "boolean"
}
```
---
### GET /api/auth/registration-status
Check whether new user registration is enabled on this instance.
- **Auth required:** No
- **Response:**
```json
{
"enabled": true
}
```
---
## OIDC / SSO
Base path: `/api/auth/`
### GET /api/auth/oidc-status
Check whether OIDC single sign-on is configured and enabled.
- **Auth required:** No
- **Response:**
```json
{
"oidcEnabled": true,
"disableLocalAuth": false,
"buttonLabel": "Sign in with SSO"
}
```
---
### GET /api/auth/oidc
Initiates the OIDC login flow. Redirects the user to the configured identity provider.
- **Auth required:** No
- **Response:** HTTP 302 redirect to the IdP authorization endpoint.
---
### GET /api/auth/oidc/callback
Handles the callback from the identity provider after authentication. Processes the authorization code and creates/logs in the user.
- **Auth required:** No
- **Query parameters:** Standard OIDC callback parameters (`code`, `state`).
- **Response:** Redirects to the application with a session cookie set.
---
## AI Generation
All generation endpoints require authentication and stream or return AI-generated clinical text. Each accepts a `model` parameter to select the LLM.
### POST /api/generate-hpi-encounter
Generate a History of Present Illness note from a patient encounter transcript.
- **Auth required:** Yes
- **Request body:**
```json
{
"transcript": "string",
"patientAge": "string",
"patientGender": "string",
"model": "string",
"setting": "string",
"physicianMemories": "string (optional)"
}
```
- **Response:** Streamed text (text/event-stream) or JSON with the generated HPI note.
---
### POST /api/generate-hpi-dictation
Generate an HPI note from a physician's dictated summary (same parameters as encounter).
- **Auth required:** Yes
- **Request body:**
```json
{
"transcript": "string",
"patientAge": "string",
"patientGender": "string",
"model": "string",
"setting": "string",
"physicianMemories": "string (optional)"
}
```
- **Response:** Streamed text (text/event-stream) or JSON with the generated HPI note.
---
### POST /api/generate-soap
Generate a SOAP note from a patient encounter transcript.
- **Auth required:** Yes
- **Request body:**
```json
{
"transcript": "string",
"patientAge": "string",
"patientGender": "string",
"model": "string",
"type": "string",
"additionalInstructions": "string (optional)",
"physicianMemories": "string (optional)"
}
```
- **Response:** Streamed text (text/event-stream) or JSON with the generated SOAP note.
---
### POST /api/generate-chart-review
Generate a chart review summary from clinical notes.
- **Auth required:** Yes
- **Request body:**
```json
{
"notes": "string",
"visitType": "string",
"model": "string"
}
```
- **Response:** Streamed text or JSON with the chart review.
---
### POST /api/generate-hospital-course
Generate a hospital course summary from clinical notes.
- **Auth required:** Yes
- **Request body:**
```json
{
"notes": "string",
"patientAge": "string",
"patientGender": "string",
"model": "string",
"format": "string",
"physicianMemories": "string (optional)"
}
```
- **Response:** Streamed text or JSON with the hospital course summary.
---
### POST /api/well-visit/shadess
Generate a SHADESS (Strengths, Home, Activities, Drugs, Emotions, Sexuality, Safety) assessment from well-visit responses.
- **Auth required:** Yes
- **Request body:**
```json
{
"responses": "object",
"patientAge": "string",
"model": "string"
}
```
- **Response:** Streamed text or JSON with the SHADESS assessment.
---
### POST /api/generate-sick-visit
Generate a sick visit note from a transcript, incorporating diagnosis information.
- **Auth required:** Yes
- **Request body:**
```json
{
"transcript": "string",
"patientAge": "string",
"patientGender": "string",
"model": "string",
"diagnoses": "string | array",
"physicianMemories": "string (optional)"
}
```
- **Response:** Streamed text or JSON with the sick visit note.
---
### POST /api/generate-milestone-narrative
Generate a developmental milestone narrative from milestone data.
- **Auth required:** Yes
- **Request body:**
```json
{
"milestones": "object | array",
"patientAge": "string",
"patientGender": "string",
"model": "string"
}
```
- **Response:** Streamed text or JSON with the milestone narrative.
---
### POST /api/generate-milestone-summary
Generate a concise summary from a previously generated milestone narrative.
- **Auth required:** Yes
- **Request body:**
```json
{
"narrative": "string",
"model": "string"
}
```
- **Response:** Streamed text or JSON with the milestone summary.
---
### POST /api/refine
Refine existing clinical text according to provided instructions.
- **Auth required:** Yes
- **Request body:**
```json
{
"text": "string",
"instructions": "string",
"model": "string"
}
```
- **Response:** Streamed text or JSON with the refined text.
---
### POST /api/shorten
Shorten a block of clinical text while preserving key information.
- **Auth required:** Yes
- **Request body:**
```json
{
"text": "string",
"model": "string"
}
```
- **Response:** Streamed text or JSON with the shortened text.
---
### POST /api/clarify
Improve clarity and readability of clinical text.
- **Auth required:** Yes
- **Request body:**
```json
{
"text": "string",
"model": "string"
}
```
- **Response:** Streamed text or JSON with the clarified text.
---
## Transcription
### GET /api/transcribe/status
Check whether speech-to-text transcription is available and which provider is configured.
- **Auth required:** Yes
- **Response:**
```json
{
"available": true,
"provider": "whisper | deepgram | browser"
}
```
---
### POST /api/transcribe
Transcribe an audio file to text. Accepts multipart form data with the audio file.
- **Auth required:** Yes
- **Content-Type:** `multipart/form-data`
- **File size limit:** 25 MB
- **Form fields:**
| Field | Type | Description |
|---------|------|--------------------|
| `audio` | file | Audio file to transcribe |
- **Response:**
```json
{
"success": true,
"text": "string",
"provider": "string",
"duration": "number (seconds)"
}
```
---
## Text-to-Speech
### POST /api/text-to-speech
Convert text to speech. Returns an audio stream.
- **Auth required:** Yes
- **Request body:**
```json
{
"text": "string",
"voice": "string (optional)"
}
```
- **Response:** Audio stream (`audio/mpeg`).
- **Response headers:**
| Header | Description |
|------------------|------------------------------------|
| `X-TTS-Provider` | The TTS provider used for synthesis |
---
## Models
### GET /api/models
List available AI models for the current instance.
- **Auth required:** Yes
- **Response:**
```json
{
"provider": "string",
"models": [
{
"id": "string",
"name": "string",
"cost": "string",
"category": "string"
}
],
"defaultModel": "string"
}
```
---
## Encounters
### GET /api/encounters/saved
List all saved encounters for the authenticated user.
- **Auth required:** Yes
- **Response:**
```json
[
{
"id": "number",
"label": "string",
"enc_type": "string",
"created_at": "string (ISO 8601)",
"updated_at": "string (ISO 8601)"
}
]
```
---
### GET /api/encounters/saved/:id
Retrieve a single saved encounter with full data.
- **Auth required:** Yes
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|-----------------|
| `id` | number | Encounter ID |
- **Response:**
```json
{
"id": "number",
"label": "string",
"enc_type": "string",
"transcript": "string",
"generated_note": "string",
"partial_data": "object | null",
"created_at": "string (ISO 8601)",
"updated_at": "string (ISO 8601)"
}
```
---
### POST /api/encounters/saved
Create or update a saved encounter. Uses `idempotency_key` to prevent duplicates.
- **Auth required:** Yes
- **Request body:**
```json
{
"label": "string",
"enc_type": "string",
"transcript": "string",
"generated_note": "string",
"partial_data": "object (optional)",
"idempotency_key": "string (optional)"
}
```
- **Response:**
```json
{
"success": true,
"id": "number"
}
```
---
### DELETE /api/encounters/saved/:id
Delete a saved encounter.
- **Auth required:** Yes
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|-----------------|
| `id` | number | Encounter ID |
- **Response:**
```json
{
"success": true
}
```
---
## Memories
Physician memories are reusable context snippets (preferences, style corrections, common instructions) injected into AI generation prompts.
### GET /api/memories
List all memories for the authenticated user. Returns up to 200 entries.
- **Auth required:** Yes
- **Response:**
```json
[
{
"id": "number",
"category": "string",
"name": "string",
"content": "string",
"created_at": "string (ISO 8601)"
}
]
```
---
### POST /api/memories
Create a new memory.
- **Auth required:** Yes
- **Request body:**
```json
{
"category": "string",
"name": "string",
"content": "string"
}
```
- **Response:**
```json
{
"success": true,
"id": "number"
}
```
---
### PUT /api/memories/:id
Update an existing memory.
- **Auth required:** Yes
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|-------------|
| `id` | number | Memory ID |
- **Request body:**
```json
{
"category": "string",
"name": "string",
"content": "string"
}
```
- **Response:**
```json
{
"success": true
}
```
---
### DELETE /api/memories/:id
Delete a memory.
- **Auth required:** Yes
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|-------------|
| `id` | number | Memory ID |
- **Response:**
```json
{
"success": true
}
```
---
### GET /api/memories/context
Retrieve all memories formatted for injection into AI generation prompts.
- **Auth required:** Yes
- **Response:**
```json
{
"context": "string"
}
```
---
### POST /api/memories/correction
Automatically save a style correction as a memory. Used when the physician corrects AI output.
- **Auth required:** Yes
- **Request body:**
```json
{
"section": "string",
"original_snippet": "string",
"corrected_snippet": "string"
}
```
- **Response:**
```json
{
"success": true,
"id": "number"
}
```
---
## Audio Backups
Temporary audio backup storage with automatic 24-hour expiry.
### POST /api/audio-backups
Upload an audio backup. The file is gzip-compressed on the server.
- **Auth required:** Yes
- **Content-Type:** `multipart/form-data`
- **Form fields:**
| Field | Type | Description |
|---------|------|------------------------|
| `audio` | file | Audio file to back up |
- **Response:**
```json
{
"success": true,
"id": "number"
}
```
---
### GET /api/audio-backups
List all audio backups for the authenticated user.
- **Auth required:** Yes
- **Response:**
```json
[
{
"id": "number",
"filename": "string",
"created_at": "string (ISO 8601)",
"expires_at": "string (ISO 8601)"
}
]
```
---
### GET /api/audio-backups/:id/audio
Download a decompressed audio backup.
- **Auth required:** Yes
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|-------------------|
| `id` | number | Audio backup ID |
- **Response:** Binary audio stream with appropriate content-type header.
---
### DELETE /api/audio-backups/:id
Delete an audio backup.
- **Auth required:** Yes
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|-------------------|
| `id` | number | Audio backup ID |
- **Response:**
```json
{
"success": true
}
```
---
## Documents
S3-backed document storage for clinical files.
### GET /api/documents
List all documents for the authenticated user.
- **Auth required:** Yes
- **Response:**
```json
[
{
"id": "number",
"filename": "string",
"mimetype": "string",
"size": "number",
"created_at": "string (ISO 8601)"
}
]
```
---
### POST /api/documents/upload
Upload a document to S3 storage.
- **Auth required:** Yes
- **Content-Type:** `multipart/form-data`
- **File size limit:** 10 MB
- **Allowed types:** PDF, images (JPEG, PNG, GIF, WebP), Word documents (.doc, .docx), plain text (.txt), CSV (.csv)
- **Form fields:**
| Field | Type | Description |
|--------|------|---------------------|
| `file` | file | Document to upload |
- **Response:**
```json
{
"success": true,
"id": "number",
"filename": "string"
}
```
---
### GET /api/documents/:id/download
Download a document.
- **Auth required:** Yes
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|---------------|
| `id` | number | Document ID |
- **Response:** Binary file stream with appropriate content-type and content-disposition headers.
---
### DELETE /api/documents/:id
Delete a document from S3 storage.
- **Auth required:** Yes
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|---------------|
| `id` | number | Document ID |
- **Response:**
```json
{
"success": true
}
```
---
## User Preferences
### GET /api/user/preferences
Get the authenticated user's preferences.
- **Auth required:** Yes
- **Response:**
```json
{
"stt_model": "string",
"tts_voice": "string"
}
```
---
### POST /api/user/preferences
Save user preferences.
- **Auth required:** Yes
- **Request body:**
```json
{
"stt_model": "string",
"tts_voice": "string"
}
```
- **Response:**
```json
{
"success": true
}
```
---
### GET /api/user/preferences/options
List available STT models and TTS voices that the user can choose from.
- **Auth required:** Yes
- **Response:**
```json
{
"sttModels": [
{ "id": "string", "name": "string" }
],
"ttsVoices": [
{ "id": "string", "name": "string" }
]
}
```
---
### POST /api/user/webdav-path
Save the user's preferred WebDAV learning content path.
- **Auth required:** Yes
- **Request body:**
```json
{
"path": "string"
}
```
- **Response:**
```json
{
"success": true
}
```
---
## Nextcloud Integration
### POST /api/nextcloud/connect
Connect the user's account to a Nextcloud instance via WebDAV.
- **Auth required:** Yes
- **Request body:**
```json
{
"url": "string",
"username": "string",
"password": "string"
}
```
- **Response:**
```json
{
"success": true,
"message": "Connected to Nextcloud."
}
```
---
### POST /api/nextcloud/export
Export text content to the connected Nextcloud instance.
- **Auth required:** Yes
- **Request body:**
```json
{
"text": "string",
"title": "string"
}
```
- **Response:**
```json
{
"success": true,
"path": "string"
}
```
---
### POST /api/nextcloud/disconnect
Disconnect the user's Nextcloud integration.
- **Auth required:** Yes
- **Request body:** None
- **Response:**
```json
{
"success": true,
"message": "Disconnected from Nextcloud."
}
```
---
## Learning Hub (Public)
Public-facing learning content endpoints. Authentication is required to track progress and submit quizzes.
### GET /api/learning/categories
List all learning content categories.
- **Auth required:** Yes
- **Response:**
```json
[
{
"id": "number",
"name": "string",
"slug": "string",
"description": "string"
}
]
```
---
### GET /api/learning/feed
Get a paginated feed of learning content.
- **Auth required:** Yes
- **Query parameters:**
| Parameter | Type | Default | Description |
|-----------|--------|---------|-----------------------|
| `limit` | number | 20 | Items per page |
| `offset` | number | 0 | Pagination offset |
- **Response:**
```json
[
{
"id": "number",
"title": "string",
"slug": "string",
"summary": "string",
"category": "string",
"created_at": "string (ISO 8601)"
}
]
```
---
### GET /api/learning/category/:slug
Get all learning content within a specific category.
- **Auth required:** Yes
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|----------------|
| `slug` | string | Category slug |
- **Response:** Array of content items in the category.
---
### GET /api/learning/content/:slug
Get a single piece of learning content, including quiz questions, answer options, and the user's progress.
- **Auth required:** Yes
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|---------------|
| `slug` | string | Content slug |
- **Response:**
```json
{
"id": "number",
"title": "string",
"slug": "string",
"body": "string (markdown)",
"category": "object",
"questions": [
{
"id": "number",
"text": "string",
"options": [
{
"id": "number",
"text": "string"
}
]
}
],
"progress": {
"completed": "boolean",
"score": "number | null"
}
}
```
---
### GET /api/learning/content/:slug/slides
Render Marp-formatted markdown content as HTML presentation slides.
- **Auth required:** Yes
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|---------------|
| `slug` | string | Content slug |
- **Response:** HTML presentation content.
---
### POST /api/learning/submit-quiz
Submit quiz answers for a piece of learning content.
- **Auth required:** Yes
- **Request body:**
```json
{
"contentId": "number",
"answers": [
{
"questionId": "number",
"optionIds": ["number"]
}
]
}
```
- **Response:**
```json
{
"success": true,
"score": "number",
"total": "number",
"results": [
{
"questionId": "number",
"correct": "boolean"
}
]
}
```
---
### GET /api/learning/search
Keyword-based search across learning content.
- **Auth required:** Yes
- **Query parameters:**
| Parameter | Type | Description |
|-----------|--------|-----------------|
| `q` | string | Search query |
- **Response:** Array of matching content items.
---
### GET /api/learning/search/semantic
Semantic (vector-based) search across learning content using embeddings.
- **Auth required:** Yes
- **Query parameters:**
| Parameter | Type | Description |
|-----------|--------|-----------------|
| `q` | string | Search query |
- **Response:** Array of matching content items ranked by semantic similarity.
---
### GET /api/learning/search/hybrid
Combined keyword and semantic search for best-of-both-worlds results.
- **Auth required:** Yes
- **Query parameters:**
| Parameter | Type | Description |
|-----------|--------|-----------------|
| `q` | string | Search query |
- **Response:** Array of matching content items with combined ranking.
---
## Learning Hub CMS (Moderator+)
Content management endpoints for learning content. Requires moderator or admin role.
### GET /api/admin/learning/categories
List all learning categories (admin view).
- **Auth required:** Yes (moderator+)
- **Response:** Array of category objects.
---
### POST /api/admin/learning/categories
Create a new learning category.
- **Auth required:** Yes (moderator+)
- **Request body:**
```json
{
"name": "string",
"slug": "string",
"description": "string"
}
```
- **Response:**
```json
{
"success": true,
"id": "number"
}
```
---
### PUT /api/admin/learning/categories/:id
Update a learning category.
- **Auth required:** Yes (moderator+)
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|---------------|
| `id` | number | Category ID |
- **Request body:**
```json
{
"name": "string",
"slug": "string",
"description": "string"
}
```
- **Response:**
```json
{
"success": true
}
```
---
### DELETE /api/admin/learning/categories/:id
Delete a learning category.
- **Auth required:** Yes (moderator+)
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|---------------|
| `id` | number | Category ID |
- **Response:**
```json
{
"success": true
}
```
---
### GET /api/admin/learning/content
List all learning content (admin view, includes unpublished).
- **Auth required:** Yes (moderator+)
- **Response:** Array of content objects.
---
### POST /api/admin/learning/content
Create new learning content.
- **Auth required:** Yes (moderator+)
- **Request body:**
```json
{
"title": "string",
"slug": "string",
"body": "string (markdown)",
"categoryId": "number",
"questions": "array (optional)"
}
```
- **Response:**
```json
{
"success": true,
"id": "number"
}
```
---
### GET /api/admin/learning/content/:id
Get a single content item for editing.
- **Auth required:** Yes (moderator+)
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|--------------|
| `id` | number | Content ID |
- **Response:** Full content object with questions and metadata.
---
### PUT /api/admin/learning/content/:id
Update existing learning content.
- **Auth required:** Yes (moderator+)
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|--------------|
| `id` | number | Content ID |
- **Request body:**
```json
{
"title": "string",
"slug": "string",
"body": "string (markdown)",
"categoryId": "number",
"questions": "array (optional)"
}
```
- **Response:**
```json
{
"success": true
}
```
---
### DELETE /api/admin/learning/content/:id
Delete learning content.
- **Auth required:** Yes (moderator+)
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|--------------|
| `id` | number | Content ID |
- **Response:**
```json
{
"success": true
}
```
---
### POST /api/admin/learning/ai-generate
Generate learning content or presentations using AI. Accepts either multipart form data (with file uploads) or JSON.
- **Auth required:** Yes (moderator+)
- **Content-Type:** `multipart/form-data` or `application/json`
- **Request body (JSON):**
```json
{
"topic": "string",
"type": "article | presentation",
"model": "string"
}
```
- **Request body (multipart):** Same fields plus uploaded reference files.
- **Response:**
```json
{
"success": true,
"content": "string (markdown)"
}
```
---
### POST /api/admin/learning/ai-refine
Refine learning content body text using AI.
- **Auth required:** Yes (moderator+)
- **Request body:**
```json
{
"body": "string",
"instructions": "string",
"model": "string"
}
```
- **Response:**
```json
{
"success": true,
"content": "string"
}
```
---
### POST /api/admin/learning/preview-slides
Preview Marp-formatted markdown as rendered presentation slides.
- **Auth required:** Yes (moderator+)
- **Request body:**
```json
{
"markdown": "string"
}
```
- **Response:**
```json
{
"css": "string",
"slides": ["string (HTML)"]
}
```
---
### POST /api/admin/learning/generate-pptx
Generate a PowerPoint file from Marp markdown.
- **Auth required:** Yes (moderator+)
- **Request body:**
```json
{
"markdown": "string",
"title": "string"
}
```
- **Response:** Binary `.pptx` file download.
---
### GET /api/admin/learning/webdav-browse
Browse files on the connected WebDAV/Nextcloud server.
- **Auth required:** Yes (moderator+)
- **Query parameters:**
| Parameter | Type | Description |
|-----------|--------|------------------------------|
| `path` | string | Directory path to browse |
- **Response:** Array of file/directory entries.
---
### GET /api/admin/learning/stats
Get learning hub statistics (content counts, quiz completion rates, etc.).
- **Auth required:** Yes (moderator+)
- **Response:**
```json
{
"totalContent": "number",
"totalCategories": "number",
"totalQuizSubmissions": "number",
"averageScore": "number"
}
```
---
## Admin - Users
Requires admin role.
### GET /api/admin/users
List all registered users.
- **Auth required:** Yes (admin)
- **Response:**
```json
[
{
"id": "number",
"name": "string",
"email": "string",
"role": "string",
"verified": "boolean",
"disabled": "boolean",
"created_at": "string (ISO 8601)"
}
]
```
---
### GET /api/admin/users/:id
Get detailed information and usage statistics for a specific user.
- **Auth required:** Yes (admin)
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|-------------|
| `id` | number | User ID |
- **Response:**
```json
{
"id": "number",
"name": "string",
"email": "string",
"role": "string",
"verified": "boolean",
"disabled": "boolean",
"stats": {
"totalGenerations": "number",
"totalTranscriptions": "number",
"lastActive": "string (ISO 8601)"
}
}
```
---
### POST /api/admin/users/:id/verify
Manually verify a user's email address (bypass email verification).
- **Auth required:** Yes (admin)
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|-------------|
| `id` | number | User ID |
- **Response:**
```json
{
"success": true
}
```
---
### POST /api/admin/users/:id/disable
Disable a user account, preventing login.
- **Auth required:** Yes (admin)
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|-------------|
| `id` | number | User ID |
- **Response:**
```json
{
"success": true
}
```
---
### POST /api/admin/users/:id/enable
Re-enable a previously disabled user account.
- **Auth required:** Yes (admin)
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|-------------|
| `id` | number | User ID |
- **Response:**
```json
{
"success": true
}
```
---
## Admin - Configuration
Requires admin role unless noted otherwise.
### GET /api/admin/config/announcement
Get the current announcement banner. This endpoint is public and does not require authentication.
- **Auth required:** No
- **Response:**
```json
{
"announcement": "string | null"
}
```
---
### GET /api/admin/config
Get all application configuration settings.
- **Auth required:** Yes (admin)
- **Response:** Object containing all configuration key-value pairs.
---
### POST /api/admin/config
Update application configuration settings.
- **Auth required:** Yes (admin)
- **Request body:** Object with configuration key-value pairs to update.
- **Response:**
```json
{
"success": true
}
```
---
### POST /api/admin/config/test-email
Send a test email to verify SMTP configuration.
- **Auth required:** Yes (admin)
- **Request body:**
```json
{
"to": "string (email address)"
}
```
- **Response:**
```json
{
"success": true,
"message": "Test email sent."
}
```
---
### GET /api/admin/config/prompts
Get all AI prompt templates, including any admin overrides.
- **Auth required:** Yes (admin)
- **Response:** Object mapping prompt keys to their current values.
---
### POST /api/admin/config/prompts
Save AI prompt template overrides.
- **Auth required:** Yes (admin)
- **Request body:** Object mapping prompt keys to new values.
- **Response:**
```json
{
"success": true
}
```
---
### POST /api/admin/config/prompts/:key/reset
Reset a specific AI prompt template back to its default value.
- **Auth required:** Yes (admin)
- **Path parameters:**
| Parameter | Type | Description |
|-----------|--------|---------------------|
| `key` | string | Prompt template key |
- **Response:**
```json
{
"success": true
}
```
---
### POST /api/admin/config/reset-defaults
Reset all configuration settings to their default values.
- **Auth required:** Yes (admin)
- **Response:**
```json
{
"success": true
}
```
---
### GET /api/admin/config/smtp/status
Check the current SMTP configuration status.
- **Auth required:** Yes (admin)
- **Response:**
```json
{
"configured": "boolean",
"host": "string",
"port": "number"
}
```
---
### POST /api/admin/config/smtp/update
Update SMTP email configuration.
- **Auth required:** Yes (admin)
- **Request body:**
```json
{
"host": "string",
"port": "number",
"username": "string",
"password": "string",
"from": "string"
}
```
- **Response:**
```json
{
"success": true
}
```
---
### POST /api/admin/config/registration
Update registration settings (enable/disable new registrations).
- **Auth required:** Yes (admin)
- **Request body:**
```json
{
"enabled": "boolean"
}
```
- **Response:**
```json
{
"success": true
}
```
---
### GET /api/admin/config/oidc
Get the current OIDC/SSO configuration.
- **Auth required:** Yes (admin)
- **Response:**
```json
{
"enabled": "boolean",
"clientId": "string",
"issuerUrl": "string",
"buttonLabel": "string",
"disableLocalAuth": "boolean"
}
```
---
### POST /api/admin/config/oidc
Update the OIDC/SSO configuration.
- **Auth required:** Yes (admin)
- **Request body:**
```json
{
"enabled": "boolean",
"clientId": "string",
"clientSecret": "string",
"issuerUrl": "string",
"buttonLabel": "string",
"disableLocalAuth": "boolean"
}
```
- **Response:**
```json
{
"success": true
}
```
---
### GET /api/admin/config/models
List all AI models with their enabled/disabled status.
- **Auth required:** Yes (admin)
- **Response:**
```json
[
{
"id": "string",
"name": "string",
"enabled": "boolean",
"isDefault": "boolean",
"category": "string"
}
]
```
---
### PUT /api/admin/config/models/toggle
Enable or disable a specific AI model.
- **Auth required:** Yes (admin)
- **Request body:**
```json
{
"modelId": "string",
"enabled": "boolean"
}
```
- **Response:**
```json
{
"success": true
}
```
---
### PUT /api/admin/config/models/default
Set the default AI model for all users.
- **Auth required:** Yes (admin)
- **Request body:**
```json
{
"modelId": "string"
}
```
- **Response:**
```json
{
"success": true
}
```
---
### POST /api/admin/config/models/custom
Add a custom AI model definition.
- **Auth required:** Yes (admin)
- **Request body:**
```json
{
"id": "string",
"name": "string",
"category": "string"
}
```
- **Response:**
```json
{
"success": true
}
```
---
### GET /api/admin/config/models/discover
Discover available models from the configured AI provider.
- **Auth required:** Yes (admin)
- **Response:**
```json
{
"models": [
{
"id": "string",
"name": "string"
}
]
}
```
---
## Logs
Requires admin role.
### GET /api/logs/usage
Get a 30-day usage summary broken down by model and endpoint.
- **Auth required:** Yes (admin)
- **Response:**
```json
{
"byModel": [
{
"model": "string",
"count": "number",
"tokens": "number"
}
],
"byEndpoint": [
{
"endpoint": "string",
"count": "number"
}
]
}
```
---
### GET /api/logs/audit
Get the audit log of user actions (login, settings changes, etc.).
- **Auth required:** Yes (admin)
- **Response:** Array of audit log entries with timestamps, user IDs, and action descriptions.
---
### GET /api/logs/api
Get API call metrics (request counts, latency, error rates).
- **Auth required:** Yes (admin)
- **Response:** Array of API metric entries.
---
### GET /api/logs/access
Get user access history (login times, IP addresses).
- **Auth required:** Yes (admin)
- **Response:** Array of access log entries.
---
## Milestones (Admin)
Developmental milestones management. Requires admin role.
### GET /api/admin/milestones
List all developmental milestones in the database.
- **Auth required:** Yes (admin)
- **Response:** Array of milestone objects organized by age group and domain.
---
### POST /api/admin/milestones/seed
Seed the database with the default set of developmental milestones.
- **Auth required:** Yes (admin)
- **Request body:** None
- **Response:**
```json
{
"success": true,
"count": "number"
}
```
---
## Health
### GET /api/health
Application health check endpoint.
- **Auth required:** No
- **Response:**
```json
{
"status": "ok",
"provider": "string",
"uptime": "number (seconds)"
}
```