All endpoints require JWT authentication via the Authorization: Bearer <token> header unless noted otherwise.
Register a new user with an invite token.
Body:
{
"email": "user@example.com",
"password": "secret",
"name": "Jane Doe",
"invite_token": "abc123"
}Returns a JWT access token.
Body:
{
"email": "user@example.com",
"password": "secret"
}Response:
{
"access_token": "eyJ...",
"token_type": "bearer"
}Returns the authenticated user's profile.
Update the current user's preferences.
Body (all fields optional):
{
"language_preference": "es"
}Check whether the system needs initial setup (no users exist). No authentication required.
Response:
{
"needs_setup": true
}Create a new project. If description fields are provided, triggers an automatic risk evaluation.
Body:
{
"name": "My AI System",
"description": "An AI-powered recommendation engine",
"intended_purpose": "Product recommendations for e-commerce",
"intended_users": "End consumers",
"deployment_context": "EU market, B2C web application"
}List all projects owned by the current user.
Get a single project by ID.
Update project fields. If any risk-relevant field is changed (description, intended_purpose, intended_users, deployment_context, questionnaire_answers), an LLM-based risk evaluation runs automatically and the response includes the updated risk_classification.
Body (all fields optional):
{
"name": "Updated name",
"description": "Updated description",
"questionnaire_answers": {
"q1": "yes",
"q2": "yes",
"q3": ["none"]
}
}Manually trigger a risk re-evaluation. No request body required.
Response: The full project object with updated risk_classification.
Delete a project and all associated data (documents, chat sessions, reporting evidence).
List all required documents for a project. Documents are automatically created based on framework document definitions if they don't exist yet.
Response:
[
{
"id": "uuid",
"project_id": "uuid",
"definition_id": "uuid",
"name": "Technical Documentation",
"description": "Must be compiled before market entry...",
"article": "Annex IV",
"framework_name": "EU AI Act",
"framework_id": "uuid",
"uploaded": false,
"file_name": null,
"summary": null,
"uploaded_at": null
}
]Upload a file for a framework document. Accepts multipart/form-data with a file field. After upload, the file is sent to the Pipelines service for text extraction and LLM summary generation.
Supported file types: PDF, Markdown, TXT, CSV, JSON, XML, HTML.
Remove an uploaded file from a framework document. Clears the file path, file name, summary, and upload timestamp. The document placeholder remains.
Free-form document uploads not tied to any framework definition. Custom document summaries are included in the chat agent and reporting suggestion context.
List all custom documents for a project, ordered by upload date (newest first).
Response:
[
{
"id": "uuid",
"project_id": "uuid",
"file_name": "policy.pdf",
"summary": "LLM-generated summary or null",
"uploaded_at": "2026-05-25T10:00:00"
}
]Upload a custom PDF document. Accepts multipart/form-data with a file field. Only .pdf files are accepted. After upload, the file is sent to the Pipelines service for processing.
Delete a custom document (removes the database record and file from disk).
List all reporting evidence entries for a project. Each entry includes the comment text and, when available, the LLM validation result (covered, feedback).
Bulk upsert reporting evidence. Creates or updates entries by item_key. Accepts optional covered and feedback fields to persist validation results alongside comments.
Body:
{
"items": [
{
"item_key": "data-governance",
"comment": "Data governance policy documented in Confluence",
"covered": true,
"feedback": "Provides a concrete reference to the governance policy location."
},
{
"item_key": "risk-management",
"comment": "Risk register maintained in JIRA",
"covered": false,
"feedback": "Does not describe how risks are identified or mitigated."
}
]
}Generate an AI-suggested comment for a reporting checklist item. Uses project context, uploaded document summaries, existing evidence, and framework knowledge to produce a concise suggestion.
Body:
{
"question": "[Data Governance — DG-01 Data Management] How is training data quality assured?",
"current_comment": "Optional existing comment to improve"
}Response:
{
"suggestion": "Training data quality is assured through automated validation pipelines and manual review."
}Validate whether an answer sufficiently addresses a compliance question. Uses project context and documents to evaluate the response against a strict auditor standard.
Body:
{
"question": "[Data Governance — DG-01 Data Management] How is training data quality assured?",
"answer": "We use automated validation pipelines.",
"framework_id": "optional-framework-uuid"
}Response:
{
"covered": false,
"feedback": "Does not specify what validation checks are performed or how failures are handled."
}List all active compliance frameworks.
Get a single framework by ID, including its full content.
List frameworks from the built-in catalogue that are not yet active. Used to populate the "Add Framework" dialog.
Response:
[
{
"name": "Environmental Impact Framework",
"description": "Structured approach to measuring AI environmental footprint.",
"category": "Internal"
}
]Add a framework from the built-in catalogue. Creates the framework and its document definitions.
Body:
{
"name": "Environmental Impact Framework"
}Returns 404 if the name is not in the catalogue, 409 if it already exists.
Remove a framework and its associated documents. The EU AI Act framework is protected and cannot be deleted (returns 403).
Create a new chat session for a project. The system prompt is assembled at creation time from the project's current state (frameworks, questionnaire answers, uploaded document summaries, reporting evidence, codebase analysis).
Body:
{
"project_id": "uuid"
}List all chat sessions for a project.
Get a chat session with its full message history.
Send a message and receive the complete assistant response.
Body:
{
"content": "What documents do I need for a high-risk AI system?"
}Send a message and receive the assistant response as a Server-Sent Events stream. Each event contains a text chunk:
data: Here is the first part...
data: of the response.
data: [DONE]
Fetch the assembled context for a project, optionally filtered by section. Used by the debug context viewer.
Query parameters:
project_id(required) — project UUIDsection(optional, defaultfull) — one offull,overview,frameworks,documents,reporting,github
Response:
{
"context": "## Current Project Context\n..."
}Returns {"context": null} if the requested section has no content.
Get the integration configuration for a project. Returns 404 if no integration is configured.
Response:
{
"id": "uuid",
"project_id": "uuid",
"provider": "github",
"repo_owner": "org",
"repo_name": "repo",
"github_project_number": 1,
"summary": "LLM-generated summary or null",
"architecture_mermaid": "graph TD\n...",
"sync_status": "idle",
"last_synced_at": "2026-05-27T10:00:00"
}Create a new integration for a project.
Body:
{
"provider": "github",
"github_pat": "ghp_...",
"repo_owner": "org",
"repo_name": "repo",
"github_project_number": 1
}Update integration configuration. All fields are optional.
Remove the integration and all associated data (tasks, repo files). Returns 204.
Trigger a repository sync. Fetches the repo tree, file contents, issues, and project items from GitHub, then generates an LLM summary and architecture diagram. The sync runs asynchronously; poll the sync status endpoint to check progress.
Response:
{
"status": "syncing"
}Check the current sync status.
Response:
{
"sync_status": "idle"
}Possible values: idle, syncing, error.
List GitHub tasks (issues and project items) for the integration. Supports optional query filters: status, assignee, label, milestone.
Get a single GitHub task by ID.
Get the integration's context file content (user-editable supplementary context).
Update the integration's context file content.
Body:
{
"content": "Additional context about the codebase..."
}Health check endpoint. No authentication required.
Response:
{
"status": "ok",
"debug": false
}Create an invite link (admin only).
Body:
{
"email": "newuser@example.com",
"role": "member"
}List all invites (admin only).
Delete an unused invite (admin only). Returns 400 if the invite has already been used.
Validate an invite token. No authentication required. Used by the registration page.
Response:
{
"valid": true,
"email": "newuser@example.com",
"role": "member"
}List all users (admin only).
Update a user's role or active status (admin only). Admins cannot demote or disable themselves.
Body (all fields optional):
{
"role": "admin",
"is_active": true
}Reset a user's password (admin only).
Body:
{
"new_password": "newSecret123"
}Delete a user (admin only). Admins cannot delete themselves.