Agent skill
ROLLER Webhooks Skill
Receive and authenticate ROLLER webhooks. Use when setting up a ROLLER venue or attraction ticketing webhook endpoint, verifying the x-roller-apikey header, debugging 401s, or handling booking, customer, redemption and payment-link events (body `type` plus `eventType`, e.g. type Booking with eventType Created).
Install this skill
npx skills add hookdeck/webhook-skills --skill roller-webhooks
ROLLER (venue and attraction ticketing) sends a JSON webhook when something happens, such as a booking being created or cancelled. Webhooks are registered through the REST API. They are not signed: when you register one you supply authentication.apiKey, and ROLLER sends that value as plain text in the x-roller-apikey header of every delivery. Your endpoint authenticates the request by comparing the header with the value you chose.
When to Use This Skill
- How do I receive ROLLER webhooks?
- How do I verify the
x-roller-apikeyheader? - Does ROLLER sign webhook payloads? (No: it sends a shared API key)
- How do I handle booking created/cancelled or redemption events (
type+eventType)? - Why does my ROLLER webhook endpoint return 401?
Setup note
Set the webhook's apiKey to a long random value, then paste the same value here.
"Here" is Hookdeck's ROLLER source, or the ROLLER_WEBHOOK_API_KEY variable in your own handler. The apiKey is user-chosen and the docs' example is just a label, which would be trivially guessable, so generate something like openssl rand -hex 32.
Verification (core)
const crypto = require('crypto');
// Hash both sides: equal-length buffers, so timingSafeEqual never throws.
function safeEqual(a, b) {
const ha = crypto.createHash('sha256').update(String(a)).digest();
const hb = crypto.createHash('sha256').update(String(b)).digest();
return crypto.timingSafeEqual(ha, hb);
}
function verifyRollerRequest(headers, apiKey = process.env.ROLLER_WEBHOOK_API_KEY) {
if (!apiKey) return false; // never accept when unconfigured
const received = headers['x-roller-apikey']; // whole value, plain text
return Boolean(received) && safeEqual(received, apiKey);
}
- Header:
x-roller-apikey: <apiKey>(compare the whole value; name is case-insensitive). - Return
401on a missing header or mismatch,400for a body that isn't a JSON object,200once handled. Acknowledge within 10 seconds. - Read the body raw (
express.raw({ type: '*/*' })) and authenticate before parsing it. - Python:
hmac.compare_digeston bytes (encode both sides;strraises on non-ASCII).
A static shared credential authenticates the sender, not the body. There is no signature and no timestamp, so there is no replay protection. Use HTTPS only, and rotate the apiKey (re-register the webhook with a new value) if it leaks.
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Event Types
The JSON body carries the payload type in type (Booking, Customer, Redemption, BulkExport, SignedWaiver, PaymentLink) and the action in eventType (Created, Updated, Cancelled). ROLLER never sends a dotted name: the examples join the two fields into the keys below. All webhooks are POST.
Event (type.eventType) | Sent When |
|---|---|
Booking.Created | A booking is created |
Booking.Updated | A booking is changed |
Booking.Cancelled | A booking is cancelled |
Customer.Created | A guest is created (the guest webhook's type is Customer) |
Redemption.Created | A ticket is redeemed |
PaymentLink.Created | A payment link is created |
Environment Variables
ROLLER_WEBHOOK_API_KEY=your-long-random-value # the apiKey you set on the webhook
Local Development
ROLLER can't reach localhost. Tunnel with the Hookdeck CLI (no account required):
npx hookdeck-cli listen 3000 roller --path /webhooks/roller
Use the printed URL as the webhook url when you register it.
Resources
- references/overview.md - What ROLLER webhooks are, events and payload shape
- references/setup.md - Register a webhook through the REST API
- references/verification.md - API key check details, gotchas, debugging 401s
- examples/ - Runnable Express, Next.js and FastAPI handlers with tests