Scopes and roles¶
Two independent checks run on every authenticated request, and the narrower one wins:
- Scope — what this credential may touch. Chosen when you create a token, or approved by the user in an OAuth2 flow.
- Role — what its owner may do in that team. Set by whoever invited them.
Granting a token more scopes never grants its owner more power. A viewer's token
carrying moderate:submissions still cannot approve a submission, because the
role does not permit approving at all.
Scopes¶
| Scope | Grants |
|---|---|
read:profile |
Read your profile |
write:profile |
Update your profile |
read:teams |
Read your teams and members |
write:teams |
Create invitations and manage teams |
read:feedback |
Read projects, submissions, imports and usage |
write:feedback |
Create and edit projects, submissions and imports |
read:testimonials |
Read testimonials |
write:testimonials |
Create and edit testimonials |
moderate:submissions |
Approve, reject, restore and mark as spam |
read:widgets |
Read widgets, collection pages and embed codes |
write:widgets |
Create, update and delete widgets and collection pages |
read:surveys |
Read surveys, versions and results |
write:surveys |
Create and edit surveys, publish versions |
read:contacts |
Read contacts |
write:contacts |
Edit and merge contacts |
read:webhooks |
List and inspect endpoints and deliveries |
write:webhooks |
Create, update and delete endpoints |
read:jobs |
Poll job status |
write:jobs |
Start background jobs |
admin |
Administrative access |
read:profile is the default when a flow requests nothing specific.
Moderation is its own scope on purpose
write:feedback does not let you approve anything. Publishing is the
decision with consequences, so it needs moderate:submissions and it is
the one scope worth thinking twice about handing out.
Roles¶
| Action | Viewer | Member | Admin | Owner |
|---|---|---|---|---|
| View inbox, submissions, stats | ✓ | ✓ | ✓ | ✓ |
| Approve, reject, tag | — | ✓ | ✓ | ✓ |
| Manage surveys, widgets, pages, imports | — | ✓ | ✓ | ✓ |
| Project settings, branding, secrets | — | — | ✓ | ✓ |
| Delete project, export or delete a contact | — | — | ✓ | ✓ |
| Billing and plans | — | — | — | ✓ |
This matrix lives in one place in the code, and the dashboard, the API and the MCP server all consult it — so the three cannot disagree about what a viewer may do.
Choosing scopes in practice¶
| Task | Scopes |
|---|---|
| Show approved testimonials in your own app | read:testimonials |
| A moderation bot | read:feedback, moderate:submissions |
| Nightly CSV import | write:feedback, read:jobs, write:jobs |
| Sync contacts to your CRM | read:contacts |
| Manage embeds from CI | read:widgets, write:widgets |
| Read-only dashboard of your own | read:feedback, read:surveys |
Start with reads. Add a write scope when a specific call returns 403, rather
than ticking everything and finding out later what the token could have done.