Authorization
Subscriber types & company scoping
A webhook subscription is owned by the access token that creates it, and the type of token determines which companies it covers:
| Token type | Companies covered |
|---|---|
| Company Developer token | The single company the token is linked to. |
| Firm Developer token | All companies belonging to the firm |
| OAuth application access token | All companies the OAuth application can access. |
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
To subscribe to an event, your token must hold a scope that grants read access to the underlying resource.
Each event page lists its accepted scopes; holding either the resource's :readonly or :all scope satisfies the requirement. This requirement is not enforced at subscription time: a subscription can be created for any recognized event regardless of your current scopes.
The check happens when an event fires: if your credential doesn't satisfy the scope requirement at that moment, the delivery is skipped.
Practically, this means:
- A subscription created without the required 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]) --> B{Subscription matches event?}
B -- No --> Z([No delivery])
B -- Yes --> 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
Updated about 11 hours ago

