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 type | Companies covered |
|---|---|
| OAuth application access token (client credentials) | All companies the OAuth application can access. |
| Company Developer token | The 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_subscriptionsscope. This is enforced when you call the endpoint - without it, the request is rejected with403 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 --> DUpdated 6 days ago

