Zum Inhalt springen

REST-API Überblick

Die REST-API unter /api/v1/ erlaubt Integrationen und Tools (inklusive des Obsidian-Plugins), Dokumente und Sammlungen über eine stabile JSON-Schnittstelle zu verwalten. Diese Seite erklärt Verhalten, das für alle Endpunkte gilt. Felder und Request-Bodies pro Operation sind in der OpenAPI-Referenz dokumentiert.

Verwende dieselbe Origin wie deine deployte Orimora-Instanz:

  • Produktion: https://your-domain.example.com
  • Lokal (Vite): http://localhost:5173
  • Docker Compose (App-Service): http://localhost:3000, sofern du den Port nicht ummappst

Alle Pfade in diesem Dokument sind relativ zu dieser Basis (z. B. GET /api/v1/documents).

  1. Gehe in der Web-App zu Einstellungen → Entwickler und erstelle einen API-Schlüssel.
  2. Schlüssel werden einmalig angezeigt und haben das Präfix kb_.
  3. Sende den Schlüssel als Bearer-Token:
GET /api/v1/documents HTTP/1.1
Host: your-domain.example.com
Authorization: Bearer kb_your_key_here

Der Server ordnet den Schlüssel einem Nutzer und einem Team zu. Routen, die requireUser() verwenden, akzeptieren entweder eine normale Browser-Session oder dieses Bearer-Token.

Jeder Schlüssel hat einen oder mehrere Scopes:

ScopeTypische Nutzung
readDokumente und Sammlungen listen und abrufen
writeRessourcen anlegen und aktualisieren
adminOperationen, die Team-weite Einstellungen ändern (sofern bereitgestellt)

Standard für neue Schlüssel ist read + write. Gestalte Integrationen so, dass sie den kleinstmöglichen notwendigen Scope verwenden.

BereichLimit (Orientierung)Hinweise
Alle /api/*-Routen100 Anfragen pro IP oder Nutzer pro 60 SekundenGlobaler Guard in der Request-Pipeline; übersprungen für GET /api/health
Auth-EndpunkteStrenger (z. B. Magic Link / OAuth)Schützt vor Missbrauch; exakte Keys siehe Implementierung

Bei Begrenzung ist die Antwort 429 Too Many Requests mit JSON ähnlich zu:

{
"error": "Too many requests",
"retryAfterSeconds": 60
}

Erfolgreiche Antworten können enthalten:

  • X-RateLimit-Limit — maximale Anfragen pro Fenster
  • X-RateLimit-Remaining — verbleibend im aktuellen Fenster
  • Retry-After — vorhanden bei 429

Behandle 429 in Automation mit exponentiellem Backoff.

Ohne updatedSince enthalten Listen-Antworten:

FeldBedeutung
dataArray von Dokumenten
totalGesamtzeilen, die zu den Filtern passen (nicht nur diese Seite)
limitSeitengröße (begrenzt, Default 25, max 100)
offsetSkip-Offset

Filtere die Liste mit diesen Query-Parametern:

ParameterBedeutung
collectionIdAuf eine Sammlung beschränken
parentDocumentIdAuf direkte Unterdokumente eines Dokuments beschränken
titleExakter Titel-Match, case-insensitiv — für gezielte Existenzprüfungen (vom Plugin genutzt)
statuspublished oder draft
tagAuf Dokumente mit diesem Tag beschränken (per Name, case-insensitiv). Den Parameter wiederholen (?tag=a&tag=b) für einen Mehrfach-Tag-UND-Filter — es passen nur Dokumente, die alle genannten Tags tragen
limit / offsetSeitengröße (Default 25, max 100) und Skip-Offset

Für Tools, die nur geänderte Dokumente seit einem Zeitpunkt benötigen:

  • Übergib updatedSince als ISO-8601-Zeitstempel (z. B. 2026-04-01T12:00:00.000Z).
  • Die Antwortform unterscheidet sich: Es gibt keine total/offset-Pagination in derselben Weise; der Server verwendet ein höheres effektives Limit für das Sync-Fenster.
  • Füge format=markdown zusammen mit updatedSince hinzu, um pro Dokument ein markdownText-Feld für Klartext-Sync zu erhalten (vom Obsidian Selective Pull genutzt).

Details siehe die Operation OpenAPI /api/v1/documents GET.

  • text: Markdown-String — der Server wandelt ihn intern in TipTap-/ProseMirror-JSON um.
  • content: rohes TipTap-JSON, falls du bereits strukturierten Inhalt hast (fortgeschrittene Integrationen).

Du verwendest beim Anlegen oder Aktualisieren von Body-Inhalt typischerweise das eine oder das andere, nicht beides.

POST /api/v1/documents und PATCH /api/v1/documents/:id akzeptieren ein optionales Feld tags: string[] mit flachen Tag-Namen. Semantik:

  • Tags werden per normalisiertem (trim + lowercase) Namen innerhalb des Teams angelegt-oder-wiederverwendet.
  • Die Liste ersetzt die unrestricted Tags des Dokuments; lass das Feld weg, um die Tags unangetastet zu lassen.
  • Restricted Tags (solche mit einer Permission-ACL) werden über die API nie gesetzt oder zurückgegeben — sie bleiben UI-verwaltet.

Jedes Dokument-Objekt in Antworten (GET, POST, PATCH sowie die Listen-/updatedSince-Endpunkte) enthält:

  • tags — die unrestricted Tag-Namen des Dokuments
  • revision — ein monotoner Revisionszähler (das exakte Drift-Signal, das das Obsidian-Plugin nutzt)

Erfolgs-Payloads sehen meist so aus:

{
"data": {
/* resource */
}
}

Listen-Endpunkte liefern { "data": [ … ] } plus Pagination-Felder, wie pro Route dokumentiert.

Fehler verwenden JSON mit einem error-String (und HTTP 4xx/5xx):

{ "error": "Document not found" }
HTTPTypische Ursache
401Fehlender oder ungültiger API-Schlüssel / Session
403Authentifiziert, aber nicht erlaubt (z. B. Onboarding unvollständig)
404Ressource nicht gefunden oder falsches Team
429Rate-Limit
400Validierung / ungültiges JSON

Dokument-Lifecycle-Events können in der Workspace konfigurierte Webhooks auslösen. Webhook-Zustellung, -Signierung und -Retries sind nicht Teil der /api/v1/-CRUD-Oberfläche; konfiguriere sie in der App-UI. Automation sollte trotzdem idempotente Handler verwenden und Signaturen verifizieren, wenn sie bereitgestellt werden.

Dieselben Operationen sind als OpenAPI 3.1 für Codegeneratoren und die Starlight-UI verfügbar:

Erzeuge die gebündelte Spec neu mit:

Terminal-Fenster
cd docs && yarn generate:openapi

(Läuft automatisch als Teil von yarn build im docs-Paket.)