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/ticketskb_articles→/api/v1/kb_articlestime_records→/api/v1/time_records
Standard-Verben
| Methode | Pfad | Operation |
|---|---|---|
GET | /api/v1/<resource> | Liste, paginiert + filterbar |
GET | /api/v1/<resource>/:id | Einzelne Entity |
POST | /api/v1/<resource> | Neue Entity anlegen |
PATCH | /api/v1/<resource>/:id | Teil-Update mit Optimistic Locking |
PUT | /api/v1/<resource>/:id | Voll-Replace (selten gebraucht) |
DELETE | /api/v1/<resource>/:id | Soft-Delete |
GET | /api/v1/<resource>/:id/timeline | Audit-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:
| Feld | Bedeutung |
|---|---|
id | UUIDv7, vergibt der Server |
tenantId | Aus dem Header, nie aus dem Body |
version | Inkrementiert pro Update |
createdAt | Erstell-Zeitpunkt |
createdBy | User-ID, die das Anlegen ausgelöst hat |
deletedAt | Soft-Delete-Zeitpunkt |
deletedBy | Soft-Delete-Akteur |
number | Sequenznummer (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:
| Status | Häufigster Fall |
|---|---|
| 400 | X-Tenant-Id fehlt; ungültige Query-Parameter |
| 401 | Nicht angemeldet / Session abgelaufen |
| 402 | Lizenz-Gate (Modul nicht für Tenant freigeschaltet) |
| 403 | Permission fehlt oder Datenscope greift nicht |
| 404 | Resource existiert nicht (oder ist soft-deleted) |
| 409 | Version-Konflikt (Optimistic Locking) |
| 422 | Validierungsfehler — siehe errors[] |
| 429 | Rate-Limit oder Quota-Überschreitung |
Permissions & Datenscopes
Jede Resource hat einen Permission-Präfix (z. B. ticket → ticket_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
- Entity-Registry — alle 282 Resources auf einen Blick
- Auth-Scopes —
/api/v1vs. Public/Support/Agent/Internal - Plattform-Garantien — die Verträge im Detail