Bouwplan 02
Piekuren-heatmap: wanneer komen je tickets echt binnen?
Stap voor stap van Zendesk-data naar een live heatmap van instroom per uur × weekdag. Zelfde dashboard als wij bouwden voor onze klanten. Bouw 'm zelf met Claude, of laat ons het doen.
Niveau: gevorderd · Bouwtijd: 2–4 uur · Nodig: Zendesk admin, Vercel, Claude
Wat je bouwt
- Heatmap van nieuwe tickets per uur (0–23) × weekdag (ma–zo), gemiddeld over 8 volle weken
- Kantooruren (ma–vr, 08–18u) zichtbaar omkaderd, zodat je in één blik ziet wat er buiten bezetting binnenkomt
- KPI-tegels: tickets in venster · piekmoment · % buiten kantooruren · huidige kantooruren
- Filter op contactreden (C1) en subonderwerp (C2)
- Tweede blok: "Waar gaan avond- en weekendvragen over?" — top C1/C2 buiten kantooruren
- Live uit Zendesk, per uur ververst, tweetalig NL/EN
Waarom dit rapport
Bezetting op echte pieken
Roosteren op onderbuikgevoel kost geld aan beide kanten.
Onderbouwing voor openingstijden en selfservice
Zie je 36% van je volume buiten kantooruren, dan is dat je businesscase voor een goede kennisbank of bot.
Eén waarheid
Dezelfde definities als je andere rapporten, dus geen discussie over cijfers.
In 7 stappen
- 1
Leg je meetregels vast (vóór je bouwt)
- Instroom = ticket op aanmaakdatum (created_at). Niet op oplosdatum.
- Tijdzone hard op Europe/Amsterdam. Bucket in lokale tijd, niet in UTC — anders schuift je hele grafiek een uur bij zomer-/wintertijd.
- Spam en closed_by_merge tellen niet mee.
- Venster = 8 volle weken (56 dagen). Geen lopende week, geen deel-dag: die drukken je gemiddelde kunstmatig omlaag.
- Kantooruren: ma–vr, 08–18u. Zet dit als variabele, niet hard in je HTML.
- Filter hard op brand_id als je Zendesk meerdere merken bevat.
- 2
Haal de tickets op
- Gebruik de Zendesk Incremental Ticket Export API met een cursor op start_time. Niet de Search API: die kapt af op 1000 resultaten.
- Bewaar per ticket een slank record: aanmaakmoment in seconden, C1, C2, taal-tag, brand. Meer heb je voor dit rapport niet nodig.
GET /api/v2/incremental/tickets.json?start_time=<unix> - 3
Aggregeer naar een 7×24 grid
- Tel elk ticket in het vakje [weekdag][uur] van zijn lokale aanmaakmoment.
- Deel door het aantal weken (8) → gemiddeld aantal per uur-vak. Absolute totalen liegen zodra je venster verandert.
- Bouw hetzelfde grid ook per C1 (byC1). Dan kost je filter geen tweede API-call.
- Datavorm die wij gebruiken:
{ "tz": "Europe/Amsterdam", "days": 56, "weeks": 8, "total": 20381, "grid": [[...24 waarden...] × 7], "byC1": { "<c1>": [[...]] }, "officeStart": 8, "officeEnd": 18, "offHours": { "count": 7379, "pct": 36, "topC1": [], "topC2": [] } } - 4
Bereken "buiten kantooruren"
- Alles buiten ma–vr 08–18u: avond, nacht én het hele weekend.
- Geef niet alleen het percentage, maar ook de top C1/C2 van die tickets. Dat percentage is het probleem, die top is de oplossing.
- 5
Cache en ververs
- Draai de aggregatie in een cron (elk uur) en schrijf het resultaat weg in een key-value store. De pagina leest één endpoint en is direct snel.
- Een "Ververs nu"-knop roept server-side je refresh aan met een secret. Zet dat secret nooit in de browser.
- Faal veilig: gaat de refresh stuk, dan blijft de laatste goede versie staan.
- 6
Visualiseer het goed
- Eén sequentiële kleurschaal (licht → donker). Geen regenboog: die suggereert categorieën waar een schaal hoort.
- Legenda "Weinig → Veel" en waarden in de tooltip.
- Kantooruren markeer je met een kader, niet met een tweede kleur — anders vecht het met je schaal.
- Bied een tabelweergave aan naast de heatmap. Kleur alleen is niet toegankelijk.
- Rond af op één decimaal. "3,4 tickets per uur" is eerlijker dan "3".
- 7
Schrijf de uitleg erbij
- Zet een blok "Hoe lees je dit?" onder de heatmap: elk vakje is een gemiddelde over 8 volle weken, geen momentopname.
- Noem je tijdzone, je venster en wat je hebt uitgesloten. Zonder die regels gaat de eerste vergadering over de cijfers in plaats van over de actie.
Valkuilen
Zomer-/wintertijd: Bucket in lokale tijd, niet UTC. Anders verschuift je piek een uur.
Deel-week of deel-dag meetellen: Verlaagt je gemiddelde stilletjes. Alleen volle weken.
Search API-limiet: 1000 resultaten per query. Gebruik de incremental export.
Lage tag-dekking: Tickets zonder C1 vallen in "Overig" — je filter is net zo compleet als je categorisatie.
Auto-afgehandelde tickets: Die tellen wél als instroom (ze komen echt binnen), maar niet als teamwerk. Houd dat gescheiden in je capaciteitsrapport.
Functie-timeout bij de eerste backfill: Verhoog je maxDuration en werk met een cursor, zodat elke run verder komt.
Dubbele y-as: Nooit doen. Zet backlog of tweede reeks in een eigen paneel.
Doe het samen met Claude
Drie prompts. Kopieer, plak, bouw mee.
Prompt 1 — Meetregels vastleggen: levert een definitieblok dat je letterlijk op de pagina zet.
Ik bouw een piekuren-heatmap op Zendesk-data: instroom per uur × weekdag, gemiddeld over 8 volle weken, tijdzone Europe/Amsterdam. Stel mij de vragen die nodig zijn om de meetregels waterdicht te krijgen (venster, uitsluitingen, kantooruren, merkfilter, categorievelden) en schrijf daarna een definitieblok dat ik letterlijk op de pagina kan zetten.
Prompt 2 — De aggregatie schrijven: levert de serverless functie die je data ophaalt en aggregeert.
Schrijf een serverless functie die via de Zendesk Incremental Ticket Export alle tickets van de laatste 8 volle weken ophaalt (cursor op start_time, brandfilter, spam en closed_by_merge eruit) en aggregeert naar een 7×24 grid met gemiddelden per uur-vak, plus hetzelfde grid per C1 en een blok met tickets buiten kantooruren (ma–vr 08–18) inclusief top C1 en C2. Bucket in Europe/Amsterdam. Schrijf het resultaat weg in een key-value store en houd de functie herstartbaar met een cursor.
Prompt 3 — De pagina bouwen: levert de heatmap-pagina met filters, KPI's en tabelweergave.
Bouw een heatmap-pagina op dit JSON-endpoint: uren verticaal, weekdagen horizontaal, één sequentiële kleurschaal met legenda Weinig–Veel, kantooruren omkaderd, tooltip met de waarde, een filter op C1 en C2, vier KPI-tegels (tickets in venster, piekmoment, percentage buiten kantooruren, kantooruren-instelling), een tabelweergave als alternatief voor kleur en een uitklapbaar blok 'Hoe lees je dit?'. Tweetalig NL/EN.
Checklist voor oplevering
- Definities staan op de pagina, niet in een los document
- Venster is 8 volle weken, deel-dagen uitgesloten
- Tijdzone staat expliciet vermeld
- Filter op C1 en C2 werkt zonder herladen
- Top C1/C2 buiten kantooruren staat erbij
- Tabelweergave beschikbaar naast de heatmap
- Cron draait en de pagina toont wanneer de data is ververst
- Iemand die het rapport niet gebouwd heeft, kan het in 30 seconden uitleggen
Twee routes
Laat CX Digital het bouwen
Wij zetten de koppeling, het rapport en de definities in jouw omgeving neer en kalibreren met je team.
Plan een gesprekVeelgestelde vragen
Wat is een piekuren-heatmap?+
Een raster van instroom per uur × weekdag, gemiddeld over 8 volle weken. Elk vakje toont hoeveel nieuwe tickets er gemiddeld in dat uur op die dag binnenkomen. Daarmee plan je bezetting op echte pieken in plaats van op gevoel.
Waarom 8 weken en niet 30 dagen?+
Je wilt per weekdag genoeg metingen. Bij 30 dagen heb je maar 4 metingen per weekdag; één uitschieter bepaalt dan het beeld. Met 8 volle weken heb je 8 metingen per vakje en blijft het weekritme zichtbaar.
Werkt dit ook zonder Zendesk?+
Ja. De methode is systeemonafhankelijk: je hebt alleen het aanmaakmoment en een categorie per ticket nodig. Voor Gorgias, Freshdesk of een eigen systeem verandert alleen de manier waarop je de data ophaalt.
Hoe zwaar is dit voor mijn Zendesk API-limiet?+
Licht. De incremental export haalt in batches op en je draait de aggregatie één keer per uur, niet per paginabezoek. De pagina zelf leest een cache.
Wat als onze tickets slecht gecategoriseerd zijn?+
Dan werkt de heatmap nog steeds — instroom per uur hangt niet van categorieën af. Alleen het C1/C2-filter en de top buiten kantooruren worden onbetrouwbaar. Begin dan eerst met de C1-C2 Masterclass.
Kan ik dit combineren met een capaciteitsrapport?+
Ja, dat is de logische vervolgstap. De heatmap laat zien wanneer het volume komt, het capaciteitsrapport of je het aankunt (instroom vs. uitstroom en backlog-ontwikkeling).
De hele methodiek
Wil je de hele methodiek? Start de gratis cursus.
De C1-C2 Masterclass leert je stap voor stap hoe je een waterdichte ticketcategorisatie opzet. Vijf modules, ongeveer twee uur.
Start de cursus