A scope is a permission that a credential holds. REST API endpoints each require a scope, and API keys and OAuth access tokens are checked against the same list: a request that needs content.write fails the same way for a Read only key as for a token without that scope.
{
"status": "error",
"code": "insufficient_scope",
"message": "This action requires the content.write scope."
}
The scopes
The third column is what the consent screen shows a person when an OAuth app asks for the scope.
Scope | Allows | Consent screen text |
|---|---|---|
| Reading the help center: sites, articles, categories, images, comments, staged changes and versions, change sets, FAQ sections, the widget's install details, interface translations and exports. | Read your help-center categories and articles. |
| Every change to content: creating, updating and deleting articles and categories, uploading and deleting images, replying to, moderating and deleting comments, staging and publishing changes, restoring versions, change sets, FAQ sections, interface translations and relaying reader feedback. | Create and update your help-center articles. |
| The analytics reports, and reader feedback: the votes and messages readers leave on articles. | Read your help-center analytics reports. |
| Listing, creating and deleting webhooks. | Register webhooks that notify it when your content changes. |
| Reading the private notes your team leaves on articles. | Read the private notes your team leaves on drafts. Readers never see these. |
| Starting notes on passages, and replying to and resolving notes. | Reply to and resolve the private notes your team leaves on drafts. |
| Reading the help center's design: the draft, the customization guide, the themes and the published versions. | See your help center's design: its theme, page layouts, components, custom CSS and scripts. |
| Every change to the design: editing the draft, applying themes, discarding the draft, restoring versions into it, and publishing it. That includes the custom CSS and scripts every visitor's browser runs once the design is published. |
|
| Reading, setting and removing the help center's custom domain. | Connect your help center to your own domain, check its DNS and certificate, and remove the domain. |
| Changing which websites may embed the help center and run its widget: its embedding origins. | Choose which websites may embed your help center and run its widget. This changes your help center's security headers. |
content.write covers every change to content, including deleting articles and categories, deleting images and moderating comments. If your app asks for it, tell your users what the app will do with it.
design.read and design.write aren't part of content.read and content.write: a credential needs them to read or change the design, whatever content scopes it holds. See Design API.
Endpoints by scope
Each endpoint requires exactly one scope, with three kinds of exception: two endpoints any valid credential may call, the single-use image upload URL, which is its own credential, and the requests an AI agent makes before it has a key. Creating a help center and filing a migration request take no credential, and a migration request's status takes the status token that filing it returned (see Migrate a knowledge base as an AI agent).
Scope | Endpoints |
|---|---|
None (any valid credential) |
|
None (no credential) |
|
The request's status token |
|
| Sites: Articles: Categories: Images: Comments: Change sets: Widget and FAQ sections: Redirects (API keys only): AI agents (the key of the agent that created the help center): Other: |
| Articles: Staged changes and versions: Categories: Images: Comments: Interface translations: Change sets: FAQ sections: Imports, reading included (an OAuth token also needs an Owner or Admin): Redirects (API keys only): AI agents (the key of the agent that created the help center): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
None (the URL is the credential) |
|
Redirects accept only API keys: an OAuth token gets 403 with the code api_key_required. See Redirects. Imports and the custom domain accept OAuth tokens whose person is an Owner or Admin.
How API keys map to scopes
An API key doesn't list scopes itself. Its scope in the dashboard, and its Team notes, Design and Custom domain settings, give it these. A fourth setting, Redirects, adds no scope: it lets the key's redirects lead to other sites (see Redirects).
API key | Scopes it holds |
|---|---|
Read only |
|
Read & write |
|
Read only with Team notes | The read-only scopes, plus |
Read & write with Team notes | The read and write scopes, plus |
Read only with Design | The read-only scopes, plus |
Read & write with Design | The read and write scopes, plus |
Read & write with Custom domain | The read and write scopes, plus |
An AI agent's key (named AI agent, or AI agent (setup) once its user keeps it) | The read and write scopes, plus |
An AI agent's key is the one POST /v1/agent/help-centers returns. It expires, and until someone claims its help center it reaches only that help center's content and design. A key its user lets the agent keep after the claim reaches the help center's content, design, redirects and custom domain; every other endpoint answers 403 with agent_not_allowed. See Migrate a knowledge base as an AI agent.
A Read only key never holds notes.write, design.write, domain.manage or embed.manage. A key holds the design scopes only when Allow access to the help center design is ticked for it, and domain.manage only when Allow managing the custom domain is ticked for a Read & write key. An Owner or Admin sets these when they create the key, or later with Edit access on it in Settings; the change applies from the key's next request. To see what a credential can do, call GET /v1/account: kb.capabilities.read and kb.capabilities.write tell you whether it holds content.read and content.write. See API keys.
How OAuth tokens get scopes
An OAuth app asks for scopes in the scope parameter of the authorization request, separated by spaces:
scope=openid email content.read content.write
All or nothing. The consent screen lists every requested scope with its description. The person approves the whole list or denies it; they can't pick some scopes and leave others.
A token holds what its request asked for. The granted scopes are in the access token's
scopesclaim, an array. The token response has noscopefield.Unknown scopes fail. A scope that isn't on this page ends the authorization with the error
invalid_scope.No scope, no content. An authorization request without
scopegives a token with no scopes. It can callGET /v1andGET /v1/account; everything else answers403withinsufficient_scope.Asking for more later. Send the person through authorization again with the longer list. The consent screen appears whenever you ask for a scope they haven't approved for your app; when every scope was approved before, the browser returns to your app without it. What a person approves adds up: a later approval doesn't take back scopes they approved earlier.
Refreshing can narrow, not widen. A refresh request can pass
scopewith fewer scopes than the original token. Asking for one the original didn't have fails withinvalid_scope.
The full flow is in OAuth 2.1 for apps and AI clients.
OpenID Connect scopes
These identify the person who approved your app. None of them opens a REST API endpoint.
Scope | What you get | Consent screen text |
|---|---|---|
| An | Authenticate you and confirm your identity. |
| The claims | Access your basic profile information (name, picture). |
| The claims | Access your email address. |
| Nothing extra. Every app gets a refresh token whether or not it asks for this scope; it's accepted for clients that always request it. | Stay connected, so you are not asked to sign in again each time its short-lived access expires. |
Team notes need scope and access
Holding notes.read or notes.write isn't enough on its own. On every notes request, the person behind the credential (the creator of the API key, or the person who approved the OAuth app) must be an Owner, Admin, Editor or Translator of the help center. If they aren't, the request fails with 403, the code notes_forbidden and this message: "Editorial notes are visible only to team members who can access team comments in the dashboard. The account this credential authenticates as no longer has that access on this help center."
The design needs scope and access
Holding design.read or design.write isn't enough on its own either. On every design request, the person behind the credential must be able to edit the help center's design in the dashboard: an Owner, Admin or Editor. If they can't, the request fails with 403, the code design_forbidden and this message: "Only team members who can edit this help center's design in the dashboard (editors, admins and owners) can read or change it through the API. The account this credential authenticates as no longer has that access on this help center."
The custom domain and the embedding list need scope and role
Holding domain.manage or embed.manage isn't enough either. The person behind the credential must be an Owner or Admin of the help center, as in the dashboard, where only they can change its domain and which websites may embed it. An API key's creator always is: their keys stop working when they aren't. An OAuth token whose person is, for example, an Editor gets 403 with the code role_forbidden and their role.
When a scope is missing
A credential without the scope an endpoint needs gets 403 Forbidden with the body at the top of this page. The message always names the missing scope, for API keys and OAuth tokens alike. Retrying won't help:
With an API key, an Owner or Admin can add a setting the key lacks: Edit access on the key in Settings, under API keys, then Team notes, Design or Custom domain. A key's Read only or Read & write scope can't change, so a Read only key that needs a write scope is replaced by a new Read & write key. For
domain.manage, a key's message goes on to name the setting:This action requires the domain.manage scope. An API key holds it only when it is a Read & write key and one of the help center's Owners or Admins has ticked "Allow managing the custom domain" for it in Settings > API keys.With an OAuth token, send the person through authorization again with the scope added.
Two other errors look similar. 401 means the credential itself isn't valid. 403 with site_forbidden means the token doesn't reach the help center you named (see Choose which help center a request acts on). Every code is listed in Errors.
AI assistants and their first connection
When an AI assistant connects to the HelpCenter.io MCP server without credentials, the server's sign-in challenge asks for every scope one of its tools uses, and its metadata lists those and webhooks.manage, which no tool uses. An assistant that asks for fewer scopes than the challenge gets a token without the rest. The tools that need them are then refused with an error that names the missing permission, until the person connects the assistant again and approves it. Which scopes an assistant asks for is up to the assistant. See Connect an AI assistant to your help center.