---
title: Permissions
description: "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`](/reference/crm/get-api-v1-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.
