Subscriber types & company scoping

Subscriber types & company scoping

A webhook subscription is owned by the token that creates it. What determines the companies it covers is whether that token is bound to a single company:

Token typeCompanies covered
OAuth application access token (client credentials)All companies the OAuth application can access.
Company Developer tokenThe single company the token is linked to.

In short: a company-bound token creates a subscription scoped to that one company, while a client-credentials token creates an app-wide subscription that delivers for every company the app can access. This is decided per request. The same endpoint produces a company-scoped or app-wide subscription depending on the token you call it with.

A company-bound token also only ever sees and manages its own company's subscriptions. Listing, fetching, updating, or deleting another company's subscription or an app-wide one, returns 404 Not Found.

A subscription has a callback URL (which must be HTTPS), a list of events, and a signing secret. You can create several subscriptions — for example, different callback URLs for different events.


Scopes

Two scope checks apply, at different moments:

  • Managing subscriptions requires the webhook_subscriptions scope. This is enforced when you call the endpoint - without it, the request is rejected with 403 Forbidden.
  • Receiving deliveries for an event requires a scope that grants read access to the underlying resource. Each event page lists its accepted scopes. This is not enforced at subscription time — a subscription can be created for any recognized event regardless of your current resource scopes.

The delivery check happens when an event fires: if your credential doesn't satisfy the resource scope requirement at that moment, the delivery is skipped.

Practically, this means:

  • A subscription created without the required resource scope is valid and will start receiving deliveries as soon as the credential obtains that scope.
  • For developer tokens, the access token must hold the scope, be non-revoked and unexpired.
  • For OAuth applications, at least one active (non-revoked) access token with a non-expired refresh token for the relevant company must hold the scope.

For how tokens obtain scopes, see the Understand Scopes guide .

Authorization Flow

flowchart TD
    A([Event fires for a company]) --> B{Subscription matches event?}
    B -- No --> Z([No delivery])
    B -- Yes --> N{Subscription scope}
    N -- App-wide --> C
    N -- Scoped to this company --> C
    N -- Scoped to another company --> Y([No delivery])
    C{Event has required scopes?}
    C -- No --> D([Delivery created ✓])
    C -- Yes --> E{Token type}
    E -- Developer token --> F{Token holds required scope?}
    F -- No --> G([Skipped — missing scope])
    F -- Yes --> H{Token revoked?}
    H -- Yes --> I([Skipped — token revoked])
    H -- No --> J{Token expired?}
    J -- No --> D
    J -- Yes, has refresh token --> D
    J -- Yes, no refresh token --> K([Skipped — token expired])
    E -- OAuth application --> L{"Active token for company holds scope?"}
    L -- No --> M([Skipped — application ineligible])
    L -- Yes --> D