Scopes
Every endpoint declares a required scope. The bearer token
must hold that scope or the request fails with
403 insufficient_scope and a
WWW-Authenticate: Bearer error="insufficient_scope"
scope="<scope>"
header.
Scopes are granted when:
- the user approves the OAuth consent screen for a third-party client,
- the admin selects scopes when minting a PAT, or
-
the user
connects an
AI assistant, and the MCP consent screen grants the two
mcp:scheduling:*aliases below.
Active scopes
| Scope | What it grants |
|---|---|
user:read |
Read the authenticated user's profile
(/v1/me).
|
users:read |
List and search organization members. (MCP only.) |
event_types:read |
List and read event types. |
event_types:create |
Create event types. (Reserved; no public write endpoints yet.) |
event_types:update |
Modify event types. (MCP only.) |
event_types:delete |
Delete event types. (Reserved.) |
slots:read |
Check slot availability. |
bookings:read |
List and read bookings. |
bookings:create |
Create bookings. |
bookings:cancel |
Cancel bookings. |
bookings:reschedule |
Reschedule bookings. |
bookings:update |
Patch booking metadata, responses, and attendee name. |
webhooks:read |
List and read webhook subscriptions, and their recent
deliveries (/v1/webhooks).
|
webhooks:write |
Create, edit, delete, rotate the secret of, and test webhooks. |
availability:read |
Read schedules. (MCP only.) |
availability:write |
Modify schedules. (MCP only.) |
meetings:read |
Read the host-side meetings view. (MCP only.) |
meetings:write |
Mark meetings as no-show. (MCP only.) |
contacts:read |
Search contacts and read meeting history. (MCP only.) |
single_use_links:read |
List single-use booking links. (MCP only.) |
single_use_links:write |
Generate and delete single-use booking links. (MCP only.) |
roundtables:read |
List and read roundtables (group scheduling polls). (MCP only.) |
roundtables:write |
Create and publish roundtables. (MCP only.) |
"Reserved" scopes are recognized by the auth server but
nothing consumes them yet, but they exist so apps can request
the right surface ahead of the endpoints landing. "MCP only"
scopes are consumed by the
MCP server's tools
(the /mcp endpoint for
AI assistants); no
/v1/* REST endpoint reads them yet.
Alias scopes
Some commonly-bundled scopes are exposed as aliases. When a token is granted with an alias, the alias is expanded at grant time into its constituent granular scopes, and runtime checks always read the expanded set.
| Alias | Expands to |
|---|---|
event_types:write |
event_types:create,
event_types:update,
event_types:delete
|
bookings:write |
bookings:create,
bookings:cancel,
bookings:reschedule,
bookings:update
|
mcp:scheduling:read |
user:read, event_types:read,
slots:read, bookings:read,
meetings:read, contacts:read,
availability:read,
single_use_links:read,
roundtables:read, users:read
|
mcp:scheduling:write |
everything in mcp:scheduling:read, plus
event_types:update,
bookings:create,
bookings:cancel,
bookings:reschedule,
meetings:write,
availability:write,
single_use_links:write,
roundtables:write
|
The two mcp:scheduling:* aliases are what the
AI-assistant consent screen
grants. They are OAuth-only: they never appear in the PAT
scope picker, and are only valid for tokens addressed to the
MCP endpoint.
Practical consequence: a token granted
bookings:write carries four granular scopes, and
that's the set you'll see in
meta.request_id audit logs, in the
/v1/_ping response, and in the
scope claim of an issued OAuth token.
Reserved scopes (not yet active)
These appear in discovery but no endpoint currently consumes them:
routing_forms:read routing_forms:create routing_forms:update
routing_forms:delete routing_forms:write teams:read
teams:write calendars:read calendars:write
analytics:read
Required scope per endpoint
| Method · Path | Scope |
|---|---|
GET /v1/_ping |
none (auth only) |
GET /v1/me |
user:read |
GET /v1/event-types |
event_types:read |
GET /v1/event-types/:idOrSlug |
event_types:read |
GET /v1/slots |
slots:read |
GET /v1/slots/check |
slots:read |
GET /v1/bookings |
bookings:read |
GET /v1/bookings/:uid |
bookings:read |
POST /v1/bookings |
bookings:create |
POST /v1/bookings/:uid/cancel |
bookings:cancel |
POST /v1/bookings/:uid/reschedule |
bookings:reschedule |
PATCH /v1/bookings/:uid |
bookings:update |
GET /v1/webhooks |
webhooks:read |
GET /v1/webhooks/:id |
webhooks:read |
GET /v1/webhooks/:id/deliveries |
webhooks:read |
POST /v1/webhooks |
webhooks:write |
PATCH /v1/webhooks/:id |
webhooks:write |
DELETE /v1/webhooks/:id |
webhooks:write |
POST /v1/webhooks/:id/rotate-secret |
webhooks:write |
POST /v1/webhooks/:id/test |
webhooks:write |
Requesting scopes
OAuth: include them on
/v1/oauth/authorize as a space-separated
scope parameter. The set must be a subset of the
client's registered allowed_scopes, otherwise
400 invalid_scope. The user can narrow further
from the consent screen; granted scopes are the user's choice
intersected with the request.
PAT: select scopes in the New API key dialog in Admin Center → API. Expanding the scope set on an existing key requires re-confirming your account password; narrowing does not.
Insufficient scope
{
"error": {
"code": "insufficient_scope",
"message": "This action requires the 'bookings:create' scope",
"details": { "required_scope": "bookings:create" },
"request_id": "req_…"
}
}
The remedy is always: mint or re-authorize a token that holds the required scope. Scopes cannot be elevated mid-session.
Last updated July 29, 2026.