Permissions
Every permission, which roles hold it, and how API key scopes use the same list.
Every operation, over the API or MCP, checks a resource:action permission. A signed-in person gets permissions from
their role; an API key from the scopes it was minted with (none means the workspace's full authority); an OAuth
client from the person's role, cut down to what they approved.
A 403 names the permission that was missing. GET /api/v1/api-keys/permissions serves this list at runtime.
Roles nest: an owner holds everything an admin does, an admin everything a manager does, and a manager everything a member does.
| Permission | Owner | Admin | Manager | Member |
|---|---|---|---|---|
organization:read | ✓ | ✓ | ✓ | ✓ |
organization:update | ✓ | ✓ | ||
organization:delete | ✓ | |||
member:read | ✓ | ✓ | ✓ | ✓ |
member:create | ✓ | ✓ | ||
member:update | ✓ | ✓ | ||
member:delete | ✓ | ✓ | ||
invitation:read | ✓ | ✓ | ||
invitation:create | ✓ | ✓ | ||
invitation:cancel | ✓ | ✓ | ||
team:create | ✓ | ✓ | ||
team:update | ✓ | ✓ | ||
team:delete | ✓ | ✓ | ||
ac:create | ✓ | ✓ | ||
ac:read | ✓ | ✓ | ✓ | ✓ |
ac:update | ✓ | ✓ | ||
ac:delete | ✓ | ✓ | ||
post:read | ✓ | ✓ | ✓ | ✓ |
post:create | ✓ | ✓ | ✓ | ✓ |
post:update | ✓ | ✓ | ✓ | ✓ |
post:delete | ✓ | ✓ | ✓ | ✓ |
post:publish | ✓ | ✓ | ✓ | |
tag:read | ✓ | ✓ | ✓ | ✓ |
tag:create | ✓ | ✓ | ✓ | |
tag:update | ✓ | ✓ | ✓ | |
tag:delete | ✓ | ✓ | ✓ | |
hashtagSet:read | ✓ | ✓ | ✓ | ✓ |
hashtagSet:create | ✓ | ✓ | ✓ | ✓ |
hashtagSet:update | ✓ | ✓ | ✓ | ✓ |
hashtagSet:delete | ✓ | ✓ | ✓ | ✓ |
campaign:read | ✓ | ✓ | ✓ | ✓ |
campaign:create | ✓ | ✓ | ✓ | ✓ |
campaign:update | ✓ | ✓ | ✓ | ✓ |
campaign:delete | ✓ | ✓ | ✓ | ✓ |
account:read | ✓ | ✓ | ✓ | ✓ |
account:connect | ✓ | ✓ | ✓ | |
account:disconnect | ✓ | ✓ | ✓ | |
account:update | ✓ | ✓ | ✓ | |
media:read | ✓ | ✓ | ✓ | ✓ |
media:create | ✓ | ✓ | ✓ | ✓ |
media:delete | ✓ | ✓ | ✓ | ✓ |
comment:read | ✓ | ✓ | ✓ | ✓ |
comment:create | ✓ | ✓ | ✓ | ✓ |
comment:update | ✓ | ✓ | ✓ | ✓ |
comment:delete | ✓ | ✓ | ✓ | ✓ |
comment:manageAny | ✓ | ✓ | ✓ | |
approval:read | ✓ | ✓ | ✓ | ✓ |
approval:request | ✓ | ✓ | ✓ | ✓ |
approval:decide | ✓ | ✓ | ✓ | |
inbox:read | ✓ | ✓ | ✓ | ✓ |
inbox:reply | ✓ | ✓ | ✓ | ✓ |
inbox:update | ✓ | ✓ | ✓ | ✓ |
teamInbox:read | ✓ | ✓ | ✓ | ✓ |
teamInbox:create | ✓ | ✓ | ✓ | |
teamInbox:update | ✓ | ✓ | ✓ | |
teamInbox:delete | ✓ | ✓ | ✓ | |
inboxStatus:read | ✓ | ✓ | ✓ | ✓ |
inboxStatus:update | ✓ | ✓ | ✓ | ✓ |
inboxStatus:manageAny | ✓ | ✓ | ✓ | |
analytics:read | ✓ | ✓ | ✓ | ✓ |
analytics:readAny | ✓ | ✓ | ✓ | |
apiKey:read | ✓ | ✓ | ✓ | ✓ |
apiKey:create | ✓ | ✓ | ||
apiKey:delete | ✓ | ✓ | ||
webhook:read | ✓ | ✓ | ✓ | ✓ |
webhook:create | ✓ | ✓ | ||
webhook:update | ✓ | ✓ | ||
webhook:delete | ✓ | ✓ | ||
billing:read | ✓ | ✓ | ✓ | ✓ |
billing:manage | ✓ | ✓ | ||
integration:read | ✓ | ✓ | ✓ | ✓ |
integration:connect | ✓ | ✓ | ✓ | |
integration:disconnect | ✓ | ✓ | ✓ | |
integration:update | ✓ | ✓ | ✓ | |
auditLog:read | ✓ | ✓ | ||
brandVoice:read | ✓ | ✓ | ✓ | ✓ |
brandVoice:seed | ✓ | ✓ | ✓ | ✓ |
brandVoice:update | ✓ | ✓ | ✓ | |
linkTracking:read | ✓ | ✓ | ✓ | ✓ |
linkTracking:update | ✓ | ✓ | ✓ | |
postingSchedule:read | ✓ | ✓ | ✓ | ✓ |
postingSchedule:update | ✓ | ✓ | ✓ | |
publicProfile:read | ✓ | ✓ | ✓ | ✓ |
publicProfile:update | ✓ | ✓ | ✓ | |
calendarFeed:read | ✓ | ✓ | ✓ | ✓ |
calendarFeed:create | ✓ | ✓ | ✓ | ✓ |
calendarFeed:update | ✓ | ✓ | ✓ | ✓ |
calendarFeed:delete | ✓ | ✓ | ✓ | ✓ |
calendarFeed:manageAny | ✓ | ✓ | ||
ai:use | ✓ | ✓ | ✓ | ✓ |
autoDm:read | ✓ | ✓ | ✓ | ✓ |
autoDm:create | ✓ | ✓ | ✓ | ✓ |
autoDm:update | ✓ | ✓ | ✓ | |
autoDm:delete | ✓ | ✓ | ✓ |
On plans without approval workflows (Standard and Pro), members also hold post:publish, since there's nobody set up
to review their posts.