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:

  1. An operator installs your app for their venue in ROLLER Venue Manager.
  2. ROLLER mints a ROLLER client key for that venue โ€” a client_id and
    client_secret pair, scoped to the permissions your app declared โ€” then POSTs
    a venue.connect webhook to your connect_webhook_url. The client_secret
    travels in that body once and is never re-sent.
  3. Your app validates the request, stores the client_id and client_secret
    against the venue, and records the operator as the owner. It replies 200 OK.
  4. Later, if the operator removes your app, ROLLER POSTs a venue.disconnect
    webhook to the same URL. Your app honours the delete_data flag 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 with 401 and 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
    plaintext http:// URL โ€” your connect_webhook_url must be https://.
๐Ÿ“˜

Future (production) upgrade โ€” informational. Production will add an

HMAC-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)

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:

FieldTypeNotes
eventstringAlways "venue.connect".
request_idstringUnique per delivery. Use for idempotency + your logs.
timestampnumberUnix epoch seconds at send time.
venue_idstringOpaque ROLLER venue identifier. Your primary key for the venue.
venue_guidstringStable venue GUID.
api_base_uristringBase URI to call the ROLLER platform API for this venue.
cellstringThe ROLLER cell/region the venue lives in.
operator_emailstringThe installing operator's email โ€” PII. Record as the owner. Appears in the connect body only, never in disconnect.
client_idstringThe ROLLER client ID for this venue's key. Identifies the credential; sent on every reconnect.
client_secretstringThe 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_id and client_secret against venue_id (encrypted at
    rest
    โ€” the client_secret is a live credential and is never sent again).
  • Set operator_email as the venue's owner in your system.
  • Reply 200 OK.

4. Disconnect webhook (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:

FieldTypeNotes
eventstringAlways "venue.disconnect".
request_idstringUnique per delivery.
timestampnumberUnix epoch seconds at send time.
venue_idstringThe venue being disconnected.
venue_guidstringStable venue GUID.
delete_databooleanSee below.

Expected app behaviour on disconnect

  • Verify the secret header (see ยง2). Mismatch โ†’ 401.
  • Discard the stored client_id and client_secret for 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:

StatusMeaning ROLLER assigns
200 OKSuccess. Connect: the venue was created/linked. Disconnect: the venue was deleted/marked disconnected.
401 UnauthorizedSecret header missing or mismatched. ROLLER treats delivery as failed.
409 ConflictAlready 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.
5xxYou 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_id and
    client_secret at POST /token for 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.

Did this page help you?