ahnify spricht eine ganz normale REST/JSON-API — dieselbe, die auch das mitgelieferte
Frontend benutzt. Diese Seite erklärt Aufbau und Konventionen; die vollständige,
maschinenlesbare Referenz mit jedem Feld und jedem Response-Schema liefert auf der
eigenen Instanz die automatisch generierte OpenAPI-Doku (/api/docs,
standardmäßig deaktiviert — API_DOCS_ENABLED in backend/.env).
Alle Endpunkte liegen unter /api/v1/…, sprechen ausschließlich JSON und laufen auf demselben Host wie das Frontend — kein separater API-Server, keine separate Domain.
| Was | Wo |
|---|---|
| API-Basis | https://<dein-host>/api/v1/ |
| Interaktive Doku (Swagger UI) | /api/docs |
| Alternative Doku (ReDoc) | /api/redoc |
| OpenAPI-Schema (roh) | /api/openapi.json |
| Healthcheck (öffentlich) | GET /api/v1/health |
JWT Bearer-Token. Fast jeder Endpunkt verlangt einen gültigen Token im Authorization-Header — Ausnahmen sind Login, Gast-Login, Passwort-Reset und der Healthcheck.
POST /api/v1/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "…"
}
{
"access_token": "eyJhbGci...",
"token_type": "bearer"
}
Der Token wandert danach in jeden weiteren Request:
GET /api/v1/persons?limit=20 Authorization: Bearer eyJhbGci...
/auth/login statt eines Tokens
{"mfa_required": true, "mfa_token": "…"} — der zweite Schritt läuft über
POST /auth/login/mfa mit TOTP- oder Backup-Code. Ist 2FA erzwungen
(require_2fa) und noch nicht eingerichtet, kommt stattdessen
{"totp_setup_required": true, "setup_token": "…"}, gefolgt von
POST /auth/totp-setup/init und /confirm.
guest_access aktiv, liefert
POST /auth/guest einen zeitlich befristeten Token (24 h) ohne
Benutzerkonto — mit den Leserechten des Gast-Capability-Profils.
Fehlt der Token oder ist er ungültig/abgelaufen: 401 Unauthorized. Reicht die Rolle/das Capability-Profil nicht: 403 Forbidden. Beides im üblichen FastAPI-Fehlerformat:
{ "detail": "Keine Berechtigung für Quellen" }
Zwei Ebenen, serverseitig durchgesetzt — nicht nur im Frontend versteckt:
admin / editor / viewer / guest) steuert Schreibrechte über FastAPI-Dependencies wie require_editor, require_adminWHERE oder brechen mit 403 abEin Endpunkt, der beides zeigt (aus sources.py):
@router.get("")
def list_sources(..., _user: dict = Depends(require_viewer)):
if not _user.get("can_read_sources", True):
raise HTTPException(403, "Keine Berechtigung für Quellen")
Alle Ressourcen folgen denselben REST-Konventionen: GET Liste (mit limit/offset/q-Suche), GET /{id} Detail, POST anlegen, PUT /{id} ändern, DELETE /{id} löschen — dokumentiert bis auf Feldebene in der OpenAPI-Doku der eigenen Instanz, sofern API_DOCS_ENABLED dort aktiviert ist (Standard: aus).
| Ressource | Basis-Route |
|---|---|
| Auth (Login, 2FA, Reset, Registrierung) / App-Config | /api/v1/auth/… |
| Profil (Mein Konto, Passwort, 2FA) | /api/v1/profile/… |
| Admin (Einstellungen, Benutzer, Rollen, Anfragen, Branding) | /api/v1/admin/… |
| Personen | /api/v1/persons/… |
| Familien | /api/v1/families/… |
| Ereignisse, Beteiligte, Dokument-Links | /api/v1/events/… |
| Dokumente (inkl. Upload, grouped-Modus) | /api/v1/documents/… |
| Dokumentgruppen | /api/v1/document-groups/… |
| Orte | /api/v1/places/… |
Quellen (inkl. Hierarchie: /tree, /{id}/move, /reorder) & Verweise | /api/v1/sources/…, /api/v1/source-refs/… |
| Qualitätsprüfung | /api/v1/quality/… |
| KI-Pipeline | /api/v1/ai/… |
| GEDCOM-Export | /api/v1/export/gedcom |
| GEDCOM-Import (Staging/Review/Commit) | /api/v1/import/gedcom/… |
| JSON-Import (Staging/Review/Commit) | /api/v1/import/json/… |
| Audit-Log | /api/v1/audit/… |
Listen-Endpunkte antworten einheitlich paginiert:
{
"total": 132,
"limit": 50,
"offset": 0,
"items": [ { "id": 1, "title": "…" }, ... ]
}
slowapi begrenzt — typischerweise 5–10 Anfragen/Minute pro IP; Überschreiten liefert 429 Too Many RequestsCORS_ORIGINS in backend/.env konfigurierbar (kommagetrennt); ohne Konfiguration offen (*) — für Produktivbetrieb einschränkenfetch() ohne Content-Type: application/json — der geteilte api()-Helfer im Frontend setzt diesen Header sonst immer automatisch