ahnifySchnittstellen
REST-API

Eine Schnittstelle, kein Geheimnis.

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).

Grundlagen

Base-URL & Formate

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.

WasWo
API-Basishttps://<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
Zugang

Authentifizierung

JWT Bearer-Token. Fast jeder Endpunkt verlangt einen gültigen Token im Authorization-Header — Ausnahmen sind Login, Gast-Login, Passwort-Reset und der Healthcheck.

Request
POST /api/v1/auth/login
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "…"
}
Response (ohne 2FA)
{
  "access_token": "eyJhbGci...",
  "token_type": "bearer"
}

Der Token wandert danach in jeden weiteren Request:

GET /api/v1/persons?limit=20
Authorization: Bearer eyJhbGci...
Zwei-Faktor: Ist TOTP aktiv, liefert /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.
Gast-Zugang: Ist 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" }
Autorisierung

Rollen & Capabilities

Zwei Ebenen, serverseitig durchgesetzt — nicht nur im Frontend versteckt:

Ein 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")
Übersicht

Ressourcen

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).

RessourceBasis-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": "…" }, ... ]
}
Schutzmaßnahmen

Rate-Limiting & CORS