Integration Apps
Every app built on the ROLLER Platform API is an integration app. Before you call any endpoint, implement the connect and disconnect webhook contract your app receives when an operator installs or removes it.
Every app you build against these docs is an integration app: it links a
ROLLER venue to your external system. This page is the prerequisite contract
every integration app must conform to โ how your app is connected to a
venue, how it receives the ROLLER client credentials it authenticates with,
and how it cleans up when disconnected. Read it before the authentication and
endpoint guides that follow.
When an operator installs (connects) or removes (disconnects) your app for a
venue, ROLLER calls a webhook you host. Your app reacts to those two events: it
stores the venue's ROLLER client credentials on connect, and cleans up on
disconnect.
1. Overview of the flow
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#0052FF', 'primaryTextColor': '#ffffff', 'primaryBorderColor': '#0A1128', 'lineColor': '#0052FF', 'secondaryColor': '#E8F0FE', 'tertiaryColor': '#E8F0FE', 'mainBkg': '#0052FF', 'clusterBkg': '#E8F0FE', 'edgeLabelBackground': '#0A1128', 'fontFamily': 'Montserrat, sans-serif', 'fontSize': '14px', 'actorBkg': '#0A1128', 'actorBorder': '#0052FF', 'actorTextColor': '#ffffff', 'actorLineColor': '#0A1128', 'signalColor': '#0052FF', 'signalTextColor': '#0052FF', 'labelBoxBkgColor': '#E8F0FE', 'labelTextColor': '#0A1128', 'loopTextColor': '#0052FF', 'noteBkgColor': '#E8F0FE', 'noteTextColor': '#0A1128', 'noteBorderColor': '#0052FF', 'activationBorderColor': '#FF3B30', 'activationBkgColor': '#E8F0FE'}, 'themeCSS': '.node rect, .cluster rect, rect.actor { rx: 10px; ry: 10px; } .labelBox, .note { rx: 8px; ry: 8px; } .edgeLabel rect, .activation0, .activation1, .activation2 { rx: 4px; ry: 4px; } .nodeLabel, .edgeLabel, .label, .cluster-label, text, tspan, span, p { font-family: Montserrat, sans-serif; }'}}%%
sequenceDiagram
participant Operator
participant ROLLER
participant YourApp as Your App
Operator->>ROLLER: Install app in Venue Manager
activate ROLLER
ROLLER->>ROLLER: Mint client key<br/>(client_id + client_secret)
ROLLER->>YourApp: POST venue.connect webhook
deactivate ROLLER
activate YourApp
YourApp->>YourApp: Validate secret header
YourApp->>YourApp: Store credentials<br/>(encrypted at rest)
YourApp->>YourApp: Record operator as owner
YourApp->>ROLLER: 200 OK
deactivate YourApp
Operator->>ROLLER: Remove app from Venue Manager
activate ROLLER
ROLLER->>ROLLER: Revoke client key
ROLLER->>YourApp: POST venue.disconnect webhook
deactivate ROLLER
activate YourApp
YourApp->>YourApp: Validate secret header
YourApp->>YourApp: Delete/mark venue inactive
YourApp->>ROLLER: 200 OK
deactivate YourApp
Step-by-step:
- An operator installs your app for their venue in ROLLER Venue Manager.
- ROLLER mints a ROLLER client key for that venue โ a
client_idand
client_secretpair, scoped to the permissions your app declared โ then POSTs
avenue.connectwebhook to yourconnect_webhook_url. Theclient_secret
travels in that body once and is never re-sent. - Your app validates the request, stores the
client_idandclient_secret
against the venue, and records the operator as the owner. It replies200 OK. - Later, if the operator removes your app, ROLLER POSTs a
venue.disconnect
webhook to the same URL. Your app honours thedelete_dataflag and replies
200 OK.
You register a single connect_webhook_url for your app; both events are
delivered to it and distinguished by the event field in the body.
2. Authentication
Every webhook ROLLER sends carries a fixed shared-secret header:
X-Roller-Webhook-Secret: <base64url secret>
- The value is the per-app webhook secret ROLLER issued to your app. Hold a
copy and compare the incoming header against it on every request, using a
constant-time comparison. Store this secret encrypted at rest; treat it as a
credential of equal sensitivity to the client credentials below. - If the header is missing or does not match your stored secret, reject the
request with401and do nothing else. Do not store the credentials, do not
create anything. - The secret is transmitted only over
https://. ROLLER refuses to deliver to a
plaintexthttp://URL โ yourconnect_webhook_urlmust behttps://.
Future (production) upgrade โ informational. Production will add anHMAC-signature header (
X-Roller-Signature) alongside the shared secret. It is
additive: the shared-secret header described here remains valid. You do not
need to implement signature verification today; this note exists so you can plan
for it. This guide will be updated when the signature scheme ships.
3. Connect webhook (venue.connect)
venue.connect)Sent when an operator installs your app for a venue.
POST <your connect_webhook_url>
Headers:
Content-Type: application/json
X-Roller-Webhook-Secret: <base64url secret>
Sample body:
{
"event": "venue.connect",
"request_id": "3f1a9c2e-8b4d-4e77-9c2a-1d5f6b0e7a44",
"timestamp": 1767225600,
"venue_id": "9d2b7c14-6a3e-4f21-8c9d-2b7e1f0a5c88",
"venue_guid": "b1e6a0f2-3c4d-5e6f-7a8b-9c0d1e2f3a4b",
"api_base_uri": "https://api.roller.app",
"cell": "us",
"operator_email": "[email protected]",
"client_id": "roller_mkt_9f8e7d6c5b4a3928",
"client_secret": "rlp_live_1706a5b4c3d2e1f0..."
}Field reference:
| Field | Type | Notes |
|---|---|---|
event | string | Always "venue.connect". |
request_id | string | Unique per delivery. Use for idempotency + your logs. |
timestamp | number | Unix epoch seconds at send time. |
venue_id | string | Opaque ROLLER venue identifier. Your primary key for the venue. |
venue_guid | string | Stable venue GUID. |
api_base_uri | string | Base URI to call the ROLLER platform API for this venue. |
cell | string | The ROLLER cell/region the venue lives in. |
operator_email | string | The installing operator's email โ PII. Record as the owner. Appears in the connect body only, never in disconnect. |
client_id | string | The ROLLER client ID for this venue's key. Identifies the credential; sent on every reconnect. |
client_secret | string | The ROLLER client secret for this venue's key, scoped to your app's approved permissions. Delivered once. Store it securely; treat it as a live credential. |
Together client_id and client_secret are the credential you exchange for a
bearer token at POST /token โ see Vendor App Auth &
Credentials and
Authentication.
Expected app behaviour on connect
- Verify the secret header (see ยง2). Mismatch โ
401. - Persist
client_idandclient_secretagainstvenue_id(encrypted at
rest โ theclient_secretis a live credential and is never sent again). - Set
operator_emailas the venue's owner in your system. - Reply
200 OK.
4. Disconnect webhook (venue.disconnect)
venue.disconnect)Sent when an operator removes your app from a venue. The disconnect body carries
no credential โ the ROLLER platform key has already been revoked by the time
you receive this.
POST <your connect_webhook_url>
Sample body:
{
"event": "venue.disconnect",
"request_id": "7c2d1e0f-4a5b-6c7d-8e9f-0a1b2c3d4e5f",
"timestamp": 1767312000,
"venue_id": "9d2b7c14-6a3e-4f21-8c9d-2b7e1f0a5c88",
"venue_guid": "b1e6a0f2-3c4d-5e6f-7a8b-9c0d1e2f3a4b",
"delete_data": true
}Field reference:
| Field | Type | Notes |
|---|---|---|
event | string | Always "venue.disconnect". |
request_id | string | Unique per delivery. |
timestamp | number | Unix epoch seconds at send time. |
venue_id | string | The venue being disconnected. |
venue_guid | string | Stable venue GUID. |
delete_data | boolean | See below. |
Expected app behaviour on disconnect
- Verify the secret header (see ยง2). Mismatch โ
401. - Discard the stored
client_idandclient_secretfor this venue (the
credential is already revoked). - Honour
delete_data:trueโ delete all data you hold for this venue.falseโ keep the venue's data but mark the venue disconnected
(do not continue calling the ROLLER API for it).
- Reply
200 OK.
5. Response contract
ROLLER only inspects the HTTP status code of your response; no body is
required. Return one of:
| Status | Meaning ROLLER assigns |
|---|---|
200 OK | Success. Connect: the venue was created/linked. Disconnect: the venue was deleted/marked disconnected. |
401 Unauthorized | Secret header missing or mismatched. ROLLER treats delivery as failed. |
409 Conflict | Already in the requested state โ connect for a venue you already have, or disconnect for a venue you already removed. Safe to treat as idempotent success on your side. |
5xx | You hit an error creating (connect) or removing (disconnect) the venue. ROLLER treats delivery as failed and records the response code. |
Any 2xx is treated as delivered; anything else is a failed delivery. Because
request_id is unique per delivery and retries may occur, make your handler
idempotent โ returning 409 (or 200) for a repeat of an
already-applied event is the intended behaviour.
6. Scope changes (reconnect)
Your app's granted scopes are fixed to what your app declared and was approved
for. If the approved scope set later changes, the operator is prompted to
reconnect; ROLLER mints a fresh client key and sends a new venue.connect for
the venue. Treat a venue.connect for a venue you already have as a credential
rotation: replace the stored client_id and client_secret with the newly
delivered pair and return 200 (or 409).
7. Testing against the non-prod webhook mock
In non-prod, ROLLER runs a canned-response mock you can point your integration
at while building the ROLLER side, and vice-versa. If you need to exercise each
response branch from ROLLER's delivery side, a mock vendor endpoint returns a
status keyed off the path: /ok โ 200, /unauthorized โ 401,
/conflict โ 409, /error โ 500. Contact ROLLER for the current non-prod
mock URL.
Next steps
With the connect/disconnect contract implemented, your app holds a client_id
and client_secret per venue. From here:
- Authenticate โ exchange the delivered
client_idand
client_secretatPOST /tokenfor a bearer token to call the ROLLER Platform
API. - Understand scoped permissions โ know which endpoints
your credential can call. - Subscribe to Platform API webhooks for booking,
ticket and product events. These are distinct from the connect/disconnect
lifecycle webhooks described above.
Reference
- Event names:
venue.connect,venue.disconnect. - Auth header (non-prod):
X-Roller-Webhook-Secret.
Updated 23 days ago
