API · v1 · stabil
CODEMETA OS Developer Center
Konsole öffnen
Foundation

Konventionen

Codemeta OS hat ein generisches CRUD-Fundament. 282 Entitäten teilen sich denselben Endpoint-Bauplan: List/Get/Create/Update/Delete + Timeline. Diese Seite erklärt diesen Bauplan einmal, anstatt ihn pro Resource zu wiederholen.

Welche Resources es gibt und unter welchem Pfad sie laufen, sehen Sie in der Entity-Registry.

Ressource-Pfad

Jede Entity ist unter dem Pfad ihrer Collection erreichbar:

/api/v1/<collection-name-plural>

Beispiele:

  • tickets/api/v1/tickets
  • kb_articles/api/v1/kb_articles
  • time_records/api/v1/time_records

Standard-Verben

MethodePfadOperation
GET/api/v1/<resource>Liste, paginiert + filterbar
GET/api/v1/<resource>/:idEinzelne Entity
POST/api/v1/<resource>Neue Entity anlegen
PATCH/api/v1/<resource>/:idTeil-Update mit Optimistic Locking
PUT/api/v1/<resource>/:idVoll-Replace (selten gebraucht)
DELETE/api/v1/<resource>/:idSoft-Delete
GET/api/v1/<resource>/:id/timelineAudit-Historie + Aktivitäten

Listen-Endpoints

Pagination

Listen sind cursor-paginiert:

curl "https://os.codemeta.de/api/v1/tickets?limit=50&cursor=<opaque>" \
  -H "X-Tenant-Id: $TENANT" \
  -b cookies.txt

Antwort:

{
  "data": [  ],
  "pagination": {
    "nextCursor": "0192f2c0-…",
    "hasMore": true
  }
}

nextCursor ist opak — bauen Sie keine Annahmen über sein Format.

Sortierung

sortBy + sortOrder als Query-Parameter:

?sortBy=createdAt&sortOrder=desc

Erlaubte Felder hängen von der Entity ab. Default ist meist createdAt:desc.

Filtern

Beliebige Felder lassen sich gleich-filtern:

?status=open&priority=high

Für komplexere Filter gibt es pro-Entity-spezifische Query-Parameter — sehen Sie auf der jeweiligen Feature-Seite nach. Volltextsuche typischerweise als ?q=<text>.

Soft-Delete-Filter

Standardmäßig sind Listen frei von gelöschten Datensätzen. Mit ?includeDeleted=true (sofern erlaubt) bekommen Sie sie zurück.

Schreiben

Idempotenz beim Anlegen

POST akzeptiert den Header X-Idempotency-Key:

curl -X POST https://os.codemeta.de/api/v1/tickets \
  -H "X-Tenant-Id: $TENANT" \
  -H "X-Idempotency-Key: 6b6e9b37-8a72-4d5b-8b2c-9a3d2c1e5f64" \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{"title":"…"}'

Wiederholte Requests mit demselben Key + Body liefern dieselbe Antwort, ohne einen zweiten Datensatz anzulegen.

Optimistic Locking beim Update

PATCH verlangt das version-Feld im Body. Stimmt die Version nicht mehr mit dem Server überein, bekommen Sie 409 Conflict.

{ "version": 7, "priority": "high" }

Strategie: erneut lesen, Felder mergen, mit neuer Version retry. Mehr unter Optimistic Locking.

Soft-Delete

DELETE setzt deletedAt und deletedBy. Daten bleiben physisch erhalten, sind aber in normalen Listen unsichtbar. Restore über einen Admin-Endpoint mit PATCH { deletedAt: null }. Mehr unter Soft-Deletion.

Geschützte Felder

Diese Felder steuert der Server — Body-Werte werden ignoriert oder mit 422 abgelehnt:

FeldBedeutung
idUUIDv7, vergibt der Server
tenantIdAus dem Header, nie aus dem Body
versionInkrementiert pro Update
createdAtErstell-Zeitpunkt
createdByUser-ID, die das Anlegen ausgelöst hat
deletedAtSoft-Delete-Zeitpunkt
deletedBySoft-Delete-Akteur
numberSequenznummer (siehe Konzept)

Audit-Historie

Jede Mutation legt einen RFC-6902-JSON-Patch im Audit-Trail ab. Pro Entity abrufbar:

curl "https://os.codemeta.de/api/v1/tickets/<id>/timeline?filter=history" \
  -H "X-Tenant-Id: $TENANT" \
  -b cookies.txt

filter=history gibt nur Audit-Einträge; ohne Filter kommen auch Kommentare, Status-Wechsel etc. zurück. Mehr unter Audit-Historie.

Fehlerformat

Alle Fehler folgen RFC 7807:

{
  "type": "https://codemeta-os.de/probs/<slug>",
  "title": "Kurzbeschreibung",
  "status": 422,
  "detail": "Optionaler längerer Text.",
  "errors": [
    { "path": "/email", "message": "Pflichtfeld" }
  ]
}

Häufige Codes:

StatusHäufigster Fall
400X-Tenant-Id fehlt; ungültige Query-Parameter
401Nicht angemeldet / Session abgelaufen
402Lizenz-Gate (Modul nicht für Tenant freigeschaltet)
403Permission fehlt oder Datenscope greift nicht
404Resource existiert nicht (oder ist soft-deleted)
409Version-Konflikt (Optimistic Locking)
422Validierungsfehler — siehe errors[]
429Rate-Limit oder Quota-Überschreitung

Permissions & Datenscopes

Jede Resource hat einen Permission-Präfix (z. B. ticketticket_view, ticket_create, ticket_update, ticket_delete). Die Entity-Registry listet den Präfix pro Resource.

Datenscopes (all, assigned_to, team_member, customer_contact, created_by) bestimmen pro Account, welche Datensätze überhaupt sichtbar sind. Mehr unter Berechtigungen & Scopes.

Verwandt

Suche