Scopes & permissions
The OAuth consent scope catalog, how it maps to the fine-grained scopes tools enforce, the super-scope, and plan/module gating.
Every MCP tool declares the scope a credential must hold to call it. Scopes work slightly differently per channel:
- API keys are created directly with fine-grained scopes
(
resource:action, e.g.invoices:read) — the same closed catalog the REST API uses. You can also grant the super-scope*. - OAuth tokens are granted dotted scopes (
resource.action, e.g.invoices.read) on the consent screen. The server translates these to the fine-grained scopes automatically, so both channels enforce the same set at the tool boundary.
OAuth consent catalog
These are the scopes a user can grant a third-party app on the consent screen. There are 56 simple scopes plus 3 macros.
Simple scopes
Each grants one capability. The Maps to column shows the fine-grained scope the tools enforce — the consent layer translates dotted OAuth scopes to these automatically. The Sensitive column marks scopes the consent screen flags and does not pre-check.
Profile
| Scope | Grants | Maps to | Sensitive |
|---|---|---|---|
profile.read | Read your name, email and active company. | account:read | no |
CRM — clients & suppliers
| Scope | Grants | Maps to | Sensitive |
|---|---|---|---|
clients.read | List and read clients. | clients:read | no |
clients.write | Create and update clients. | clients:write | no |
clients.delete | Delete clients. | clients:delete | ⚠ yes |
suppliers.read | List and read suppliers. | suppliers:read | no |
suppliers.write | Create and update suppliers. | suppliers:write | no |
suppliers.delete | Delete suppliers. | suppliers:delete | ⚠ yes |
Catalog — products, series, taxes
| Scope | Grants | Maps to | Sensitive |
|---|---|---|---|
products.read | List and read the product catalog. | products:read | no |
products.write | Create and update products. | products:write | no |
products.delete | Delete products. | products:delete | ⚠ yes |
series.read | Read numbering series. | series:read | no |
series.write | Create and update numbering series. | series:write | no |
taxes.read | Read tax rates and retentions. | taxes:read | no |
taxes.write | Create and update tax rates. | taxes:write | no |
Sales — invoices, quotes, pro-formas, delivery notes
| Scope | Grants | Maps to | Sensitive |
|---|---|---|---|
invoices.read | List and read invoices. | invoices:read | no |
invoices.write | Create and update invoices. | invoices:write | no |
invoices.send | Send invoices by email. | invoices:send | no |
invoices.delete | Delete draft invoices. | invoices:delete | ⚠ yes |
invoices.annul | Annul issued invoices. | invoices:void | ⚠ yes |
invoices.create_corrective | Issue corrective invoices. | invoices:write | no |
quotes.read | List and read quotes. | quotes:read | no |
quotes.write | Create and update quotes. | quotes:write | no |
quotes.send | Send quotes by email. | quotes:send | no |
quotes.delete | Delete quotes. | quotes:delete | ⚠ yes |
quotes.convert_to_invoice | Accept/reject and convert quotes to invoices. | quotes:transition | no |
proformas.read | List and read pro-forma invoices. | proformas:read | no |
proformas.write | Create and update pro-formas. | proformas:write | no |
proformas.send | Send pro-formas by email. | proformas:send | no |
proformas.delete | Delete pro-formas. | proformas:delete | ⚠ yes |
proformas.convert | Convert pro-formas to invoices. | proformas:transition | no |
delivery_notes.read | List and read delivery notes. | delivery_notes:read | no |
delivery_notes.write | Create, update and send delivery notes. | delivery_notes:write | no |
delivery_notes.send | Send delivery notes by email. | delivery_notes:write | no |
delivery_notes.delete | Delete delivery notes. | delivery_notes:delete | ⚠ yes |
delivery_notes.convert | Convert delivery notes. | delivery_notes:transition | no |
delivery_notes.sign | Mark delivered / sign delivery notes. | delivery_notes:transition | ⚠ yes |
Purchases
| Scope | Grants | Maps to | Sensitive |
|---|---|---|---|
purchase_invoices.read | List and read vendor bills. | purchase_invoices:read | no |
purchase_invoices.write | Create and update vendor bills. | purchase_invoices:write | no |
purchase_invoices.mark_paid | Mark vendor bills as paid. | purchase_invoices:transition | ⚠ yes |
purchase_invoices.delete | Delete vendor bills. | purchase_invoices:delete | ⚠ yes |
Payment scopes are asymmetric across sales and purchases. Registering a
payment on a sales invoice (register_invoice_payment) needs
invoices:write — it edits the invoice. Registering a payment on a
purchase invoice (register_purchase_invoice_payment) needs
purchase_invoices:transition instead, because on the buy side a payment moves
the bill through its lifecycle (pending → paid) rather than editing it.
Recurring invoices
| Scope | Grants | Maps to | Sensitive |
|---|---|---|---|
recurring.read | List and read recurring templates. | recurring_invoices:read | no |
recurring.write | Create and update recurring templates. | recurring_invoices:write | no |
recurring.pause | Pause recurring templates. | recurring_invoices:transition | no |
recurring.resume | Resume recurring templates. | recurring_invoices:transition | no |
recurring.generate_now | Emit a recurring invoice manually. | recurring_invoices:transition | ⚠ yes |
recurring.delete | Delete recurring templates. | recurring_invoices:delete | ⚠ yes |
Compliance (VeriFactu)
| Scope | Grants | Maps to | Sensitive |
|---|---|---|---|
verifactu.read | Read VeriFactu records, events, certificates and config. | verifactu:read | no |
Webhooks
| Scope | Grants | Maps to | Sensitive |
|---|---|---|---|
webhooks.read | List webhook endpoints and deliveries. | webhooks:read | no |
webhooks.write | Create, update, rotate and ping webhook endpoints. | webhooks:write | ⚠ yes |
webhooks.delete | Delete webhook endpoints. | webhooks:delete | ⚠ yes |
Macro scopes
Convenience bundles that expand to a list of simple scopes at token-issue time. The token persists the expanded scopes — macros are never stored.
| Macro | Grants | Sensitive |
|---|---|---|
factuarea.read | Full read access to everything (no writes). | no |
factuarea.write | Read everything, plus create/update documents and send emails. | no |
factuarea.full | Read, write, send and destructive actions (delete, annul, mark paid, sign). Excludes VeriFactu writes. | ⚠ yes |
The super-scope *
A credential holding * covers every scope — all 232 tools for an API key.
It's the equivalent of an owner key. Reserve it for one-off migrations or
fully-trusted owner automations; prefer the narrowest scope set for everything
else. The super-scope is available to API keys; OAuth consent grants explicit
scopes (or macros), never a raw *.
How OAuth scopes become fine scopes
When an OAuth token is issued, its dotted scopes are translated once to the fine-grained catalog the tools enforce. A few reconciliations are worth knowing:
recurring.*maps to therecurring_invoices:*resource.invoices.create_correctivemaps toinvoices:write(creating is a write).invoices.annulmaps toinvoices:void.- Lifecycle actions (
*.convert,*.sign,*.pause,*.resume,*.generate_now,*.mark_paid,quotes.convert_to_invoice) map to the resource's:transitionscope. - Any read scope on a document also grants the transversal read utilities
pdfs:read(download its PDF/receipt) andevents:read(its activity log). verifactu.writeanddelivery_notes:gdpr_forgethave no OAuth dotted scope — they are unreachable via OAuth by design.facturae:read/facturae:writeare not in the OAuth consent catalog yet — the FacturaE (FACe) tools are reachable only with an API key for now.
Plan & module gating
No public MCP tool is module-gated today: every published tool is reachable
once the credential holds the required scope — only the scope check applies. If
a future module-gated tool is published, the server hides it from tools/list
when the company's plan lacks the module and returns module_not_in_plan
(-32005) on a direct call.
- Plan usage limits (e.g. monthly document quotas) are enforced at call time
and surface as
plan_limit_exceeded(-32004). See Errors & rate limits.
The whole public MCP surface also requires the company's developer API add-on
to be active; otherwise every call returns addon_not_active (-32007).