View as Markdown

Scopes

A scope names one kind of access. API keys and registered apps carry scope lists, and every endpoint that reads or changes data needs one. A call without the scope gets 403 insufficient_scope; detail names the missing scope.

Vocabulary

Only a key that works in its own company (This company) can hold admin:org or *. See Company scope.

Archiving a resource needs that resource's write scope: write:projects for projects and pages, write:products for products and lists, write:vendors, write:labor. Disconnecting an integration needs write:integrations. Widgets and custom properties are company setup: only an admin of the company, or a key with admin:org, can create, change or remove them. An app is refused with 403 forbidden whatever its scopes; an admin can do it in Exayard.

API keys

Every key belongs to an app, and a key's scopes are a subset of its app's. When you make a key you pick All of the app's scopes (the default) or Specific ones. A key can never hold a scope its app does not ask for. The one exception is admin:org or * on a This company key, as above.

A call made with a key is checked against the key's own scopes and against what its app holds in that company. So removing a scope from the app also takes it from every key of that app. See Apps and keys.

Older ak_ keys hold exactly the scopes picked when they were made.

Registered apps: scopes per install

An app lists the scopes it asks for when it is registered (any scope except admin:org). Each company that installs it grants those scopes to its own install, and the app's calls in that company are checked against that grant. For an app, the 403 detail says the install in this company does not grant the scope, and that an admin of the company can approve it on the Developer page.

Project-limited installs

When an admin installs an app, they choose All projects or Only these projects (1 to 500 of the company's projects). They can change the choice later by installing again. With a project list:

Session tokens and personal connections

The Exayard web app's own session, and OAuth tokens from clients that are not registered apps (personal connections such as ChatGPT, Claude or Cursor), are not checked against scopes. They act with the permissions of the person who signed in, in that person's companies. See Personal connections.

MCP

On the MCP server every tool needs a scope. A tool that mirrors a REST endpoint needs that endpoint's scope. A registered app sees and can call only the tools its install grants. A This company key acts in its own company without naming it. Any other app call names its company with the Exayard-Organization-Id header or an organizationId argument. Tools that only a person may use are never available to apps.