Getting Started

The three permission systems

CognitionDesk has three permission systems, and they don't substitute for each other. Mixing them up is the most common support question — this page exists so a 403 sends you to the right one.

Giving an API key inventory:write does not give the ASSISTANT any new tool. Raising a contact to staff does not grant the assistant a capability it didn't already have. Each system answers a different question.

The ASSISTANT

Agent capabilities (grantedScopes)

What the assistant may do inside a chat — its owner grants a set of scopes, and a tool only appears if its scope is in that set.

The PROGRAM

API key scopes

What a program from outside (your code, an MCP client, the dashboard) may call on /platform-api. Your 403 is almost always this one.

The PERSON

Audience rungs

What each person talking to the assistant gets to see: guest, contact, staff, owner. Below the rung, a tool doesn't exist for that person this turn.

Side by side, by domain

Generated from the live catalog — a domain that only exists on one side is real, not a gap in this table.

DomainAgent capabilityAPI key scopeIn the default key
Appointments sensitiveread, writeread, write—
Agent Workspace (Notes & Files)read, write——
API Keys sensitiveread, writemanage—
Assistant files sensitive—read, write—
Assistant setup wizard—read, writeyes
Assistants (Agent Builder)read, writeread, writeyes
Audience (quién le habla al agente) sensitiveread, writeread, write—
Email sensitiveread, write, sendread, write—
Channels (widgets web) sensitiveread, writeread, write—
Receivables (Cobros) sensitiveread, writeread, write—
Usage & Plansreadread, writeyes
Contacts (CRM)read, write——
Handoff (especialistas para derivar) sensitiveread, writeread, write—
Escalate to the Workspacewrite——
Custom Tools sensitiveread, writeread, write—
Image Generation & Assets sensitiveread, writewrite—
Inventory & Catalogread, writeread, writeyes
Knowledge Baseread, write——
Work loops—read, write—
User memory sensitive—read, write—
Orders & Checkoutread, write——
Ask a human sensitive—read, write—
Chat (probar agentes) sensitiverunrun—
Projects—read—
Public Storefrontread, write——
Skillsread, write——
Squads (multi-agente)read, write——
Tasksread, writeread, write—
Schedules & Reportsread, writeread, writeyes
Video (Kondor) sensitive—read, write, analyze—
WhatsApp Messagingread, write, send——
Workflowsread, writeread, write, runyes

Full detail on granting and the owner-bounded model: Capabilities & Grants · API Keys

What a new API key can do by default

A key created without explicit scopes gets exactly this set — DEFAULT_API_KEY_SCOPES in the backend. Nothing else, until you grant it.

assistants:*workflows:*wizard:*usage:readinventory:readinventory:writeschedules:read

Scopes marked sensitive (chat:run, images:write, tools:*, audience:*, handoff:*, email:*, receivables:*, channels:*, apikeys:manage…) never travel by default — they cost money, leave the platform, or decide who your assistant answers. Granting them is an act, not a default.

The widget's embed key is a different, smaller set

The key that ships inside a public page's HTML (web-widget) is not a secret — anyone who views source can read it. It carries only this, on purpose:

assistants:read

Until 2026-08-29 the embed key got the same DEFAULT_API_KEY_SCOPES as a server key, so a key published in a page's source could rewrite assistants and write inventory for the whole account. If you're on an old widget build, upgrade — this is not a config flag, it's a code fix.

Audience rungs: who's on the other end of the chat

Rungs compare with >=: a rule written once for staff keeps working when a new role is added. A role like "nutritionist" or "cashier" is data on the assistant — it maps to one of these four rungs.

RungMeans
guestsomeone we haven't identified
contacta known contact, unverified
staffsomeone from the team, verified
ownerthe account owner

On a self-authenticating channel (WhatsApp, Telegram, Facebook, Instagram) a contact's declared role is trusted directly. On the web widget nothing authenticates itself — even a contact saved as owner starts every conversation at contact and has to redeem a PIN to reach staff or owner that turn.

Your 403 is one of these three

The error names which system stopped you. Only one of the three gets fixed by editing the assistant: the scope one goes on the API key, the audience one on the contact.

"missing scope" / "forbidden" on /platform-api

Your API KEY lacks that scope. Check the table above, then grant it on the key (dashboard, or update_api_key if your key can manage keys) — never on the assistant.

a tool the assistant should have just isn't offered in chat

The ASSISTANT doesn't have that capability granted. grantedScopes lives on the assistant's config, bounded by its owner's role and plan — grant the scope there, not on any API key.

the assistant says it can't help with that, to a specific person

That PERSON's audience rung is below what the tool requires. A guest asking a staff-only question isn't a bug — check their rung, or have them redeem a PIN.

The three permission systems — CognitionDesk Docs