Skip to content
Taylorz CRM Developers
Esc
↑↓navigate↵open⌘Jpreview
On this page

Permissions

Which organization a token is bound to, then the four checks every request passes: the connection scope, the action scope, the role, and the module.

A request passes four checks. A refusal tells you which one it failed, and they fail for different reasons, so it is worth knowing all four.

Before any of them, one thing is already settled.

The organization is not a parameter

A grant is bound to one organization when a person consents, and every request resolves its organization from the token. Nothing a client sends can change it. Across the whole API there are twenty-seven request bodies and not one of them accepts an organizationId. Twenty-six also reject unknown properties outright, so sending one is an error rather than a hint.

Thirteen responses do carry an organizationId — approvals, products, price books, quotes, document templates, saved reports, dashboards — and it is always the caller’s own. Read it if you need to label data, never to choose whose data to read.

GET /capabilities does not report it. A client knows which organization it holds a token for because it was there at consent, not because the API will say.

One token, one organization. A client that serves two workspaces holds two grants and two tokens, and keeps them apart itself.

1. The connection scope

A token serves one resource, and each resource has one scope: the REST resources need api.access, MCP needs mcp.access. offline_access buys a refresh token.

Those three are the only *.access scopes that exist. There is no cpq.access or reports.access to ask for. A tenant module is not something a client requests — it is configured on the workspace and checked on the server.

2. The action scope

An endpoint’s scope is its action. GET /api/v1/objects/{objectId}/records needs records.read, because that is the action it performs. The reference names the scope for each endpoint.

Twenty-one actions exist:

objects.bootstrap   objects.read      objects.manage
records.read        records.write
prices.read         prices.manage
quotes.read         quotes.write
reports.read        reports.manage
documents.read      documents.generate  documents.manage
approvals.read      approvals.submit    approvals.decide   approvals.manage
marketing.read      marketing.manage
settings.manage

Ask only for the actions you use. A token carrying an action it never exercises is a larger grant than it needs.

marketing.read and marketing.manage are grantable but have no external endpoint — their only callers are session-only. Treat them as reserved.

3. The member’s role

The scope has to be in the token and the member’s role has to permit the action. A token holding records.write granted by a viewer still cannot write.

Only actions this API reaches are listed; marketing.read and marketing.manage belong to the role sets too but have no endpoint here.

Role Can
owner, admin every action
member read everything a viewer can, plus records.write, quotes.write, documents.generate, approvals.submit, approvals.decide
viewer objects.read, records.read, prices.read, quotes.read, reports.read, documents.read, approvals.read

4. The workspace’s modules

Many actions belong to an optional module, which the workspace enables or does not. The action fails if the module is off, whatever the token says.

Module Actions it owns
custom_objects objects.manage
cpq prices.read, prices.manage, quotes.read, quotes.write, settings.manage
reports reports.read, reports.manage
documents documents.read, documents.generate, documents.manage
approvals approvals.read, approvals.submit, approvals.decide, approvals.manage
core objects.read, objects.bootstrap, records.read, records.write

The api module gates the REST resources themselves and mcp gates MCP. They are independent: a workspace can have one without the other.

Read GET /api/v1/capabilities to see what the caller may do and which modules are on, at the configuration revision both were read at. Poll it rather than inferring entitlements from a refusal.

When a module is turned off

Turning a module off refuses tokens that already exist, before they expire. The check runs again inside the transaction that does the work, so a request admitted a moment earlier may still finish while a later one is refused.

Four pairings worth knowing

The scope an endpoint needs is not always the one its name suggests.

  • GET /api/v1/capabilities reports which modules are on, but still needs objects.read. You cannot discover your own entitlements without it.
  • PUT /api/v1/settings/commercial needs settings.manage and the cpq module.
  • GET /api/v1/documents/{id}, /retry and /download need documents.generate, not documents.read. A read-only client cannot poll a generation it did not request.
  • POST /api/v1/bootstrap and record reads and writes are core: no module, only the scope and the role.

Changing what a client may do

Update the client’s registered scopes and obtain fresh consent. A consent records the resources it covers, and a token names one of them, so a consent that no longer covers the resource stops issuing tokens for it. A token from before a scope change does not gain the new scope.

Was this page helpful?