- 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
38 KiB
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
- OIDC / SSO
- AI Generation
- Transcription
- Text-to-Speech
- Models
- Encounters
- Memories
- Audio Backups
- Documents
- User Preferences
- Nextcloud Integration
- Learning Hub (Public)
- Learning Hub CMS (Moderator+)
- Admin - Users
- Admin - Configuration
- Logs
- Milestones (Admin)
- 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:
{ "name": "string", "email": "string", "password": "string", "turnstileToken": "string" } - Response:
{ "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 tokenstring 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:
{ "email": "string" } - Response:
{ "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:
{ "email": "string", "password": "string", "totpCode": "string (optional, required if 2FA is enabled)", "turnstileToken": "string" } - Response:
If 2FA is enabled but{ "success": true, "token": "jwt-string", "user": { "id": "number", "name": "string", "email": "string", "role": "admin | moderator | user" } }totpCodeis not provided:{ "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:
{ "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:
{ "code": "string" } - Response:
{ "success": true, "message": "2FA enabled successfully." }
POST /api/auth/disable-2fa
Disable two-factor authentication. Requires password confirmation.
- Auth required: Yes
- Request body:
{ "password": "string" } - Response:
{ "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:
{ "email": "string", "turnstileToken": "string" } - Response:
{ "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:
{ "token": "string", "password": "string" } - Response:
{ "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:
{ "success": true, "message": "Logged out." }
GET /api/auth/me
Retrieve the currently authenticated user's profile.
- Auth required: Yes
- Response:
{ "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:
{ "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:
{ "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:
{ "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:
{ "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:
{ "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:
{ "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:
{ "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:
{ "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:
{ "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:
{ "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:
{ "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:
{ "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:
{ "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:
{ "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:
{ "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 audiofile Audio file to transcribe - Response:
{ "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:
{ "text": "string", "voice": "string (optional)" } - Response: Audio stream (
audio/mpeg). - Response headers:
Header Description X-TTS-ProviderThe TTS provider used for synthesis
Models
GET /api/models
List available AI models for the current instance.
- Auth required: Yes
- Response:
{ "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:
[ { "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 idnumber Encounter ID - Response:
{ "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:
{ "label": "string", "enc_type": "string", "transcript": "string", "generated_note": "string", "partial_data": "object (optional)", "idempotency_key": "string (optional)" } - Response:
{ "success": true, "id": "number" }
DELETE /api/encounters/saved/:id
Delete a saved encounter.
- Auth required: Yes
- Path parameters:
Parameter Type Description idnumber Encounter ID - Response:
{ "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:
[ { "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:
{ "category": "string", "name": "string", "content": "string" } - Response:
{ "success": true, "id": "number" }
PUT /api/memories/:id
Update an existing memory.
- Auth required: Yes
- Path parameters:
Parameter Type Description idnumber Memory ID - Request body:
{ "category": "string", "name": "string", "content": "string" } - Response:
{ "success": true }
DELETE /api/memories/:id
Delete a memory.
- Auth required: Yes
- Path parameters:
Parameter Type Description idnumber Memory ID - Response:
{ "success": true }
GET /api/memories/context
Retrieve all memories formatted for injection into AI generation prompts.
- Auth required: Yes
- Response:
{ "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:
{ "section": "string", "original_snippet": "string", "corrected_snippet": "string" } - Response:
{ "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 audiofile Audio file to back up - Response:
{ "success": true, "id": "number" }
GET /api/audio-backups
List all audio backups for the authenticated user.
- Auth required: Yes
- Response:
[ { "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 idnumber 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 idnumber Audio backup ID - Response:
{ "success": true }
Documents
S3-backed document storage for clinical files.
GET /api/documents
List all documents for the authenticated user.
- Auth required: Yes
- Response:
[ { "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 filefile Document to upload - Response:
{ "success": true, "id": "number", "filename": "string" }
GET /api/documents/:id/download
Download a document.
- Auth required: Yes
- Path parameters:
Parameter Type Description idnumber 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 idnumber Document ID - Response:
{ "success": true }
User Preferences
GET /api/user/preferences
Get the authenticated user's preferences.
- Auth required: Yes
- Response:
{ "stt_model": "string", "tts_voice": "string" }
POST /api/user/preferences
Save user preferences.
- Auth required: Yes
- Request body:
{ "stt_model": "string", "tts_voice": "string" } - Response:
{ "success": true }
GET /api/user/preferences/options
List available STT models and TTS voices that the user can choose from.
- Auth required: Yes
- Response:
{ "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:
{ "path": "string" } - Response:
{ "success": true }
Nextcloud Integration
POST /api/nextcloud/connect
Connect the user's account to a Nextcloud instance via WebDAV.
- Auth required: Yes
- Request body:
{ "url": "string", "username": "string", "password": "string" } - Response:
{ "success": true, "message": "Connected to Nextcloud." }
POST /api/nextcloud/export
Export text content to the connected Nextcloud instance.
- Auth required: Yes
- Request body:
{ "text": "string", "title": "string" } - Response:
{ "success": true, "path": "string" }
POST /api/nextcloud/disconnect
Disconnect the user's Nextcloud integration.
- Auth required: Yes
- Request body: None
- Response:
{ "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:
[ { "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 limitnumber 20 Items per page offsetnumber 0 Pagination offset - Response:
[ { "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 slugstring 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 slugstring Content slug - Response:
{ "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 slugstring 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:
{ "contentId": "number", "answers": [ { "questionId": "number", "optionIds": ["number"] } ] } - Response:
{ "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 qstring 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 qstring 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 qstring 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:
{ "name": "string", "slug": "string", "description": "string" } - Response:
{ "success": true, "id": "number" }
PUT /api/admin/learning/categories/:id
Update a learning category.
- Auth required: Yes (moderator+)
- Path parameters:
Parameter Type Description idnumber Category ID - Request body:
{ "name": "string", "slug": "string", "description": "string" } - Response:
{ "success": true }
DELETE /api/admin/learning/categories/:id
Delete a learning category.
- Auth required: Yes (moderator+)
- Path parameters:
Parameter Type Description idnumber Category ID - Response:
{ "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:
{ "title": "string", "slug": "string", "body": "string (markdown)", "categoryId": "number", "questions": "array (optional)" } - Response:
{ "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 idnumber 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 idnumber Content ID - Request body:
{ "title": "string", "slug": "string", "body": "string (markdown)", "categoryId": "number", "questions": "array (optional)" } - Response:
{ "success": true }
DELETE /api/admin/learning/content/:id
Delete learning content.
- Auth required: Yes (moderator+)
- Path parameters:
Parameter Type Description idnumber Content ID - Response:
{ "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-dataorapplication/json - Request body (JSON):
{ "topic": "string", "type": "article | presentation", "model": "string" } - Request body (multipart): Same fields plus uploaded reference files.
- Response:
{ "success": true, "content": "string (markdown)" }
POST /api/admin/learning/ai-refine
Refine learning content body text using AI.
- Auth required: Yes (moderator+)
- Request body:
{ "body": "string", "instructions": "string", "model": "string" } - Response:
{ "success": true, "content": "string" }
POST /api/admin/learning/preview-slides
Preview Marp-formatted markdown as rendered presentation slides.
- Auth required: Yes (moderator+)
- Request body:
{ "markdown": "string" } - Response:
{ "css": "string", "slides": ["string (HTML)"] }
POST /api/admin/learning/generate-pptx
Generate a PowerPoint file from Marp markdown.
- Auth required: Yes (moderator+)
- Request body:
{ "markdown": "string", "title": "string" } - Response: Binary
.pptxfile download.
GET /api/admin/learning/webdav-browse
Browse files on the connected WebDAV/Nextcloud server.
- Auth required: Yes (moderator+)
- Query parameters:
Parameter Type Description pathstring 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:
{ "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:
[ { "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 idnumber User ID - Response:
{ "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 idnumber User ID - Response:
{ "success": true }
POST /api/admin/users/:id/disable
Disable a user account, preventing login.
- Auth required: Yes (admin)
- Path parameters:
Parameter Type Description idnumber User ID - Response:
{ "success": true }
POST /api/admin/users/:id/enable
Re-enable a previously disabled user account.
- Auth required: Yes (admin)
- Path parameters:
Parameter Type Description idnumber User ID - Response:
{ "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:
{ "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:
{ "success": true }
POST /api/admin/config/test-email
Send a test email to verify SMTP configuration.
- Auth required: Yes (admin)
- Request body:
{ "to": "string (email address)" } - Response:
{ "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:
{ "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 keystring Prompt template key - Response:
{ "success": true }
POST /api/admin/config/reset-defaults
Reset all configuration settings to their default values.
- Auth required: Yes (admin)
- Response:
{ "success": true }
GET /api/admin/config/smtp/status
Check the current SMTP configuration status.
- Auth required: Yes (admin)
- Response:
{ "configured": "boolean", "host": "string", "port": "number" }
POST /api/admin/config/smtp/update
Update SMTP email configuration.
- Auth required: Yes (admin)
- Request body:
{ "host": "string", "port": "number", "username": "string", "password": "string", "from": "string" } - Response:
{ "success": true }
POST /api/admin/config/registration
Update registration settings (enable/disable new registrations).
- Auth required: Yes (admin)
- Request body:
{ "enabled": "boolean" } - Response:
{ "success": true }
GET /api/admin/config/oidc
Get the current OIDC/SSO configuration.
- Auth required: Yes (admin)
- Response:
{ "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:
{ "enabled": "boolean", "clientId": "string", "clientSecret": "string", "issuerUrl": "string", "buttonLabel": "string", "disableLocalAuth": "boolean" } - Response:
{ "success": true }
GET /api/admin/config/models
List all AI models with their enabled/disabled status.
- Auth required: Yes (admin)
- Response:
[ { "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:
{ "modelId": "string", "enabled": "boolean" } - Response:
{ "success": true }
PUT /api/admin/config/models/default
Set the default AI model for all users.
- Auth required: Yes (admin)
- Request body:
{ "modelId": "string" } - Response:
{ "success": true }
POST /api/admin/config/models/custom
Add a custom AI model definition.
- Auth required: Yes (admin)
- Request body:
{ "id": "string", "name": "string", "category": "string" } - Response:
{ "success": true }
GET /api/admin/config/models/discover
Discover available models from the configured AI provider.
- Auth required: Yes (admin)
- Response:
{ "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:
{ "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:
{ "success": true, "count": "number" }
Health
GET /api/health
Application health check endpoint.
- Auth required: No
- Response:
{ "status": "ok", "provider": "string", "uptime": "number (seconds)" }