Öffentliche API
Der Helpdesk stellt eine öffentliche API bereit: einen GraphQL-Endpunkt. Jede Operation im Schema ist mit einem Personal Access Token (PAT) auch außerhalb des Browsers erreichbar.
Diese Seite ist der Vertrag — was stabil ist, wie Sie sich authentifizieren, was Scopes gewähren und wie Fehler aufgebaut sind. Die hdmx-CLI setzt darauf auf, und die API-Versionierung beschreibt, wie sich die Schnittstelle weiterentwickelt.
Der Endpunkt
POST https://<your-host>/backend/<subdomain>/api/<version>/graphql
<subdomain>identifiziert Ihr Konto (dasselbe Kürzel, mit dem Sie sich anmelden).<version>ist eine datierte API-Version wie2026-07— siehe API-Versionierung. Sie können das Versionssegment auch weglassen und…/backend/<subdomain>/graphqlaufrufen; die Anfrage wird dann von der ältesten unterstützten Version bedient, und jede Antwort nennt Ihnen die Version, die sie beantwortet hat.
Authentifizierung
Senden Sie einen Personal Access Token als Bearer-Credential:
Authorization: Bearer hdmx_<random>
Ein PAT ist langlebig (mit verpflichtendem Ablaufdatum), mit Scopes versehen, IP-beschränkt und widerrufbar. Er ist an ein Konto gebunden: Wird ein Token an der Subdomain eines anderen Kontos vorgelegt, wird er mit HTTP 401 abgelehnt.
Einen Token erstellen
Erstellen und verwalten Sie Tokens selbst in der Agenten-App unter Settings → API tokens:
- Klicken Sie auf New token.
- Geben Sie ihm einen Namen, den Sie später wiedererkennen.
- Wählen Sie ein Ablaufdatum (bis zu 365 Tage — ein „nie" gibt es nicht).
- Legen Sie eine Zugriffsrichtlinie fest — schalten Sie genau die Ressourcen frei, die dieser Token braucht, lesend oder lesend und schreibend. Standardmäßig besteht kein Zugriff.
- Fügen Sie mindestens eine IP-Adresse oder ein CIDR zur Allowlist hinzu (erforderlich — siehe IP-Allowlist). Das Formular kann Ihre aktuelle IP für Sie eintragen.
- Prüfen und erstellen. Der vollständige Token wird genau einmal angezeigt — kopieren Sie ihn sofort. Gespeichert wird nur ein Hash, er kann also nie erneut angezeigt werden; wenn Sie ihn verlieren, rotieren Sie den Token, um einen neuen zu erhalten.
Sie können später die Zugriffsrichtlinie und die Allowlist eines Tokens bearbeiten, ihn rotieren (ein neues Secret ausgeben, während das alte für eine kurze Übergangsfrist weiter funktioniert, damit Sie ohne Ausfall umstellen können) und ihn widerrufen. Jeder Token zeigt, wann und von wo er zuletzt verwendet wurde, dazu ein Protokoll der jüngsten Aktivität.
Scopes
Der Zugriff ist grobkörnig und an Ressourcenfamilien orientiert. Ein Token trägt eine feste Menge an Scopes; jede Top-Level-Operation prüft einen davon.
| Scope | Gewährt |
|---|---|
tickets:read | Tickets, Nachrichten, Entwürfe, Verlauf, Anhänge, Reports lesen |
tickets:write | Tickets erstellen / aktualisieren / löschen, Nachrichten posten, Anhänge hochladen. Schließt tickets:read ein |
chat:read | Chats, Konversationen, Nachrichten, Sitzungen lesen |
chat:write | Agentennachrichten senden, Konversationen betreten / verlassen / schließen / wieder öffnen. Schließt chat:read ein |
customers:read | Kundendatensätze lesen |
customers:write | Kundendatensätze erstellen / aktualisieren / zusammenführen. Schließt customers:read ein |
settings:read | Kontoeinstellungen lesen (Abteilungen, Status, Prioritäten, Postfächer — ohne Secrets) |
Zugangsdaten-Felder von Postfächern (IMAP-/SMTP-Benutzernamen, -Passwörter und -Hosts) werden einem Token unabhängig vom Scope nie zurückgegeben — diese Secrets gehören Ihrem E-Mail-Anbieter und bleiben außerhalb der Reichweite der öffentlichen API.
Fehlersystematik
GraphQL-Antworten verwenden errors[].extensions.code:
| Code | Bedeutung | HTTP |
|---|---|---|
SCOPE_DENIED | Dem Token fehlt der erforderliche Scope. extensions.valid_values listet die Scopes auf, die für die Operation genügen würden | 200 |
RATE_LIMITED | Das Anfragebudget pro Token ist erschöpft. extensions.retryAfter ist die Anzahl Sekunden bis zum Reset, und der Header Retry-After trägt dieselbe Zahl | 429 |
INVALID_API_TOKEN | Token nicht gefunden, fehlerhaft oder anderweitig unbrauchbar | 200 |
Widerrufene Tokens, abgelaufene Tokens, kontenübergreifende Fehlzuordnungen und Ablehnungen durch die IP-Allowlist werden abgewiesen, bevor die Query läuft, und erscheinen als HTTP 401 ohne GraphQL-Body. Behandeln Sie ein 401 bei einer Token-Anfrage als „dieser Token ist für diese Anfrage nicht mehr gültig — prüfen Sie Ablaufdatum, Scopes und IP-Allowlist".
Rate Limits
Jede Token-Anfrage trägt Header:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 96
X-RateLimit-Reset: 1715692800
Das Standardbudget beträgt 120 Anfragen pro Minute und Token. Jede Anfrage kostet 1, ob lesend oder schreibend. Eine Überschreitung liefert HTTP 429 mit einem Retry-After-Header und extensions.code = "RATE_LIMITED"; ein gutmütiger Client wartet bis zum Reset-Zeitpunkt.
IP-Allowlist
Jeder selbst erstellte Token muss mindestens eine IP oder ein CIDR tragen — Tokens für „beliebige IP" gibt es nicht. Die Quell-IP jeder Anfrage wird gegen die Liste des Tokens geprüft; eine Abweichung wird mit HTTP 401 und extensions.sub_code = "ip_not_allowed" abgelehnt.
- IPv4, IPv6 und CIDR-Bereiche werden akzeptiert. Verwenden Sie
/32(IPv4) oder/128(IPv6) für einen einzelnen Host. - Bereiche werden beim Speichern validiert und normalisiert.
- Die Allowlist ist nach der Erstellung bearbeitbar — eine Änderung ändert nicht das Secret.
Verwenden Sie einen Token von einem stabilen Ausgangspunkt aus: einem CI-Runner, einem geplanten Job, einem festen Büro-NAT oder Ihren eigenen Servern in einem bekannten IP-Bereich. Ein geleakter Token ist von überall außerhalb seiner Allowlist wertlos.
Token-Aktivität
Jede authentifizierte Anfrage eines Tokens wird protokolliert: Zeitpunkt, Name der Operation, Quell-IP, Ergebnis (Erfolg, Fehler, Rate-Limit, Scope-Ablehnung, widerrufen oder abgelaufen) und die Antwortzeit. Das ist die Spur, die Sie prüfen sollten, wenn sich ein Token unerwartet verhält.
Versionierung & Deprecation
Die API ist mit datierten YYYY-MM-Versionen versioniert. Legen Sie eine in der URL fest, und sie bleibt mindestens 12 Monate stabil; Deprecations werden in-band angekündigt, bevor etwas verschwindet, das Sie nutzen. Die vollständige Richtlinie finden Sie unter API-Versionierung.
Schema-Erkundung
Das Schema ist selbstbeschreibend: Verwenden Sie die standardmäßige GraphQL-Introspection gegen den versionierten Endpunkt, um Typen zu generieren und die Schnittstelle zu erkunden. Das interaktive GraphQL Playground steht unter …/backend/<subdomain>/playground bereit.
curl-Schnellstart
Diese Beispiele setzen den Host helpdesk.example.com, die Subdomain acme, die Version 2026-07 und einen Token in $TOKEN voraus.
Aktuellen Benutzer lesen (beliebiger Scope)
curl -sS https://helpdesk.example.com/backend/acme/api/2026-07/graphql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"{ currentUser { id email firstname lastname } }"}'
Aktuelle Tickets auflisten (tickets:read)
curl -sS https://helpdesk.example.com/backend/acme/api/2026-07/graphql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "query ($first: Int!) {
ticketList(first: $first) {
edges { node { code subject status { name } updatedAt } }
}
}",
"variables": { "first": 10 }
}'
Eine öffentliche Antwort posten (tickets:write)
curl -sS https://helpdesk.example.com/backend/acme/api/2026-07/graphql \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"query": "mutation ($input: SaveTicketInput!) {
saveTicket(input: $input) {
ticket { code }
error { code message }
}
}",
"variables": {
"input": {
"id": "TICKET-UUID-HERE",
"message": "Thanks — fixing this now.",
"messageType": "PUBLIC"
}
}
}'
Für den Alltag kapselt die hdmx-CLI diese gesamte Schnittstelle hinter ergonomischen Befehlen.