Ga naar hoofdinhoud

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 zoals 2026-07 — zie API-versiebeheer. U kunt het versiesegment ook weglaten en …/backend/<subdomain>/graphql aanroepen; 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:

  1. Klik op New token.
  2. Geef hem een naam die u later herkent.
  3. Kies een vervaldatum (tot 365 dagen — er is geen "nooit").
  4. Stel een toegangsbeleid in — schakel precies de resources in die dit token nodig heeft, lezen of lezen-en-schrijven. Standaard is er geen toegang.
  5. Voeg minstens één IP-adres of CIDR toe aan de allowlist (verplicht — zie IP-allowlist). Het formulier kan uw huidige IP voor u toevoegen.
  6. 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.

ScopeVerleent
tickets:readTickets, berichten, concepten, geschiedenis, bijlagen en rapporten lezen
tickets:writeTickets aanmaken / bijwerken / verwijderen, berichten plaatsen, bijlagen uploaden. Impliceert tickets:read
chat:readChats, gesprekken, berichten en sessies lezen
chat:writeAgentberichten versturen, gesprekken betreden / verlaten / sluiten / heropenen. Impliceert chat:read
customers:readKlantrecords lezen
customers:writeKlantrecords aanmaken / bijwerken / samenvoegen. Impliceert customers:read
settings:readAccountinstellingen 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:

CodeBetekenisHTTP
SCOPE_DENIEDHet token mist de vereiste scope. extensions.valid_values somt de scope(s) op die de operatie zouden toestaan200
RATE_LIMITEDHet aanvraagbudget per token is uitgeput. extensions.retryAfter is het aantal seconden tot de reset, en de Retry-After-header bevat hetzelfde getal429
INVALID_API_TOKENToken niet gevonden, misvormd of anderszins onbruikbaar200

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.