Publieke API
De helpdesk biedt één publieke API: een GraphQL-eindpunt. Elke operatie in het schema is buiten de browser bereikbaar met een persoonlijk toegangstoken (Personal Access Token, PAT).
Deze pagina is het contract — wat stabiel is, hoe u zich authenticeert, wat scopes verlenen en hoe fouten zijn opgebouwd. De hdmx-CLI is erop gebouwd, en API-versiebeheer beschrijft hoe dit oppervlak evolueert.
Het eindpunt
POST https://<your-host>/backend/<subdomain>/api/<version>/graphql
<subdomain>identificeert uw account (dezelfde naam waarmee u inlogt).<version>is een gedateerde API-versie zoals2026-07— zie API-versiebeheer. U kunt het versiesegment ook weglaten en…/backend/<subdomain>/graphqlaanroepen; de aanvraag wordt dan afgehandeld door de oudste ondersteunde versie, en elk antwoord vertelt u welke versie antwoordde.
Authenticatie
Stuur een persoonlijk toegangstoken als Bearer-credential:
Authorization: Bearer hdmx_<random>
Een PAT is langlevend (met een verplichte vervaldatum), voorzien van scopes, beperkt per IP en intrekbaar. Hij is gebonden aan één account: een token aanbieden bij het subdomein van een ander account wordt geweigerd met HTTP 401.
Een token aanmaken
Maak tokens zelf aan en beheer ze in de agent-app onder Settings → API tokens:
- Klik op New token.
- Geef hem een naam die u later herkent.
- Kies een vervaldatum (tot 365 dagen — er is geen "nooit").
- Stel een toegangsbeleid in — schakel precies de resources in die dit token nodig heeft, lezen of lezen-en-schrijven. Standaard is er geen toegang.
- Voeg minstens één IP-adres of CIDR toe aan de allowlist (verplicht — zie IP-allowlist). Het formulier kan uw huidige IP voor u toevoegen.
- Controleer en maak aan. Het volledige token wordt precies één keer getoond — kopieer het meteen. Alleen een hash wordt opgeslagen, dus het kan nooit opnieuw getoond worden; bent u het kwijt, roteer het token dan om een nieuw te krijgen.
Later kunt u het toegangsbeleid en de allowlist van een token aanpassen, hem roteren (een nieuw geheim uitgeven terwijl het oude nog een korte respijtperiode werkt, zodat u zonder downtime kunt overstappen) en hem intrekken. Elk token toont wanneer en vanwaar het voor het laatst gebruikt is, plus een logboek met recente activiteit.
Scopes
Toegang is grofmazig en per resourcefamilie ingedeeld. Een token draagt een vaste set scopes; elke operatie op het hoogste niveau controleert er één.
| Scope | Verleent |
|---|---|
tickets:read | Tickets, berichten, concepten, geschiedenis, bijlagen en rapporten lezen |
tickets:write | Tickets aanmaken / bijwerken / verwijderen, berichten plaatsen, bijlagen uploaden. Impliceert tickets:read |
chat:read | Chats, gesprekken, berichten en sessies lezen |
chat:write | Agentberichten versturen, gesprekken betreden / verlaten / sluiten / heropenen. Impliceert chat:read |
customers:read | Klantrecords lezen |
customers:write | Klantrecords aanmaken / bijwerken / samenvoegen. Impliceert customers:read |
settings:read | Accountinstellingen lezen (afdelingen, statussen, prioriteiten, mailboxen — zonder geheimen) |
Inloggegevensvelden van mailboxen (IMAP/SMTP-gebruikersnamen, -wachtwoorden en -hosts) worden nooit aan een token teruggegeven, ongeacht de scope — die geheimen horen bij uw e-mailprovider en blijven buiten bereik van de publieke API.
Fouttaxonomie
GraphQL-antwoorden gebruiken errors[].extensions.code:
| Code | Betekenis | HTTP |
|---|---|---|
SCOPE_DENIED | Het token mist de vereiste scope. extensions.valid_values somt de scope(s) op die de operatie zouden toestaan | 200 |
RATE_LIMITED | Het aanvraagbudget per token is uitgeput. extensions.retryAfter is het aantal seconden tot de reset, en de Retry-After-header bevat hetzelfde getal | 429 |
INVALID_API_TOKEN | Token niet gevonden, misvormd of anderszins onbruikbaar | 200 |
Ingetrokken tokens, verlopen tokens, verkeerde accountkoppelingen en weigeringen door de IP-allowlist worden geweigerd vóór de query draait en komen terug als HTTP 401 zonder GraphQL-body. Behandel een 401 op een tokenaanvraag als "dit token is niet langer geldig voor deze aanvraag — controleer vervaldatum, scopes en IP-allowlist."
Rate limits
Elke tokenaanvraag draagt headers:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 96
X-RateLimit-Reset: 1715692800
Het standaardbudget is 120 aanvragen per minuut per token. Elke aanvraag kost 1, of ze nu leest of schrijft. Erover gaan geeft HTTP 429 met een Retry-After-header en extensions.code = "RATE_LIMITED"; een net gedragende client wacht tot het resetmoment.
IP-allowlist
Elk zelf aangemaakt token moet minstens één IP of CIDR bevatten — er bestaan geen "elk IP"-tokens. Het bron-IP van elke aanvraag wordt getoetst aan de lijst van het token; een misser wordt geweigerd met HTTP 401 en extensions.sub_code = "ip_not_allowed".
- IPv4, IPv6 en CIDR-bereiken worden alle geaccepteerd. Gebruik
/32(IPv4) of/128(IPv6) voor één host. - Bereiken worden bij het opslaan gevalideerd en genormaliseerd.
- De allowlist is na aanmaak te bewerken — bewerken verandert het geheim niet.
Gebruik een token vanaf een stabiel uitgaand punt: een CI-runner, een geplande taak, een vaste kantoor-NAT of uw eigen servers in een bekend IP-bereik. Een gelekt token is nutteloos vanaf elke plek buiten zijn allowlist.
Tokenactiviteit
Elke geauthenticeerde aanvraag die een token doet, wordt vastgelegd: het tijdstip, de operatienaam, het bron-IP, de uitkomst (succes, fout, rate-limited, scope geweigerd, ingetrokken of verlopen) en de responstijd. Dit is het spoor om te controleren als een token zich onverwacht gedraagt.
Versiebeheer & deprecatie
De API is geversioneerd met gedateerde YYYY-MM-versies. Zet er een vast in de URL en die blijft minstens 12 maanden stabiel; deprecaties worden in-band aangekondigd voordat er iets verdwijnt dat u gebruikt. Zie API-versiebeheer voor het volledige beleid.
Schema verkennen
Het schema beschrijft zichzelf: gebruik standaard GraphQL-introspectie op het geversioneerde eindpunt om types te genereren en het oppervlak te verkennen. De interactieve GraphQL Playground is beschikbaar op …/backend/<subdomain>/playground.
Snelle start met curl
Deze voorbeelden gaan uit van host helpdesk.example.com, subdomein acme, versie 2026-07 en een token in $TOKEN.
De huidige gebruiker lezen (elke 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 } }"}'
Recente tickets opsommen (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 }
}'
Een openbaar antwoord plaatsen (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"
}
}
}'
Voor dagelijks gebruik verpakt de hdmx-CLI dit hele oppervlak achter ergonomische commando's.