Developer
Permission scopes
Scopes are the product's own feature codes. A credential can only narrow.
| Scope | Resource | Verbs |
|---|---|---|
| sales_customers | /customers | read · create · update · delete |
| purchases_vendors | /vendors | read · create · update · delete |
| sales_invoices | /invoices | read · create · update · delete |
| ops_products | /items | read · create · update · delete |
| sales_receipts | /receipts | read · create |
| purchases_payments | /payments | read · create |
| finance_banking | /bank-feeds | read · create |
A scope string is feature_code:verb, e.g. sales_invoices:create. In OAuth the user picks scopes on the consent screen; for API keys the Super Administrator picks them when minting. Either way the server checks three things on every call, and denies on the first failure:
- the credential is valid — exists, active, not expired, not revoked;
- the scope was granted at issuance;
- the user the credential is bound to still holds the right now.
⚠️Errors you will see
403 insufficient_scope — the credential was never granted this feature. 403 insufficient_permissions — the feature was granted but not this verb, or the bound user no longer holds it.
Two things that are not scopes
An API key can also carry a capability grant. It is not a feature and has no verbs — it decides where the key works, while the scopes above still decide what it may touch. Neither is available to an OAuth token.
| Grant | Minted with | Opens |
|---|---|---|
| assistant | Allow AI assistants (MCP) | The MCP server at /mcp — see [Assistant tools](/developer/mcp-tools) |
| webhooks | Allow webhook subscriptions | /api/v1/webhooks/* — see [Subscribe an endpoint](/developer/subscribing) |