Authorization
Staff access is permission-based. Each admin endpoint requires one or more permissions. A user gets permissions from roles, and a role reaches a user through a role assignment, either for the whole tenant or for one site.
The API checks permissions on every request. Changing a role or an assignment takes effect on the user's next request, without a new login. The permissions list in the login response is only a snapshot for your UI.
A missing permission returns 403 with the required permission in detail, for example Insufficient permissions. Required: promotions:manage. When an endpoint lists several permissions, any one of them is enough. For example, check-in accepts bookings:checkin or bookings:write.
API keys have a separate, smaller permission list. See Key permissions.
Permissions
Permission keys follow resource:action. Many areas come as a pair: a read (or view) permission to see things, and a manage or write permission to change them.
Read
| Permission | Grants |
|---|---|
admin:read | Read access to the admin console |
admin:calendar:read | View the admin calendar |
admin:bookings:read | View bookings in the admin console |
admin:products:read | View products and the catalog |
admin:customers:view | View customer records |
admin:capacity:view | View capacity information |
reporting:read | View reports and analytics |
bookings:read | Read booking data |
bookings:hold | Create a temporary booking hold |
pricing:read | View pricing |
promotions:read | View promotions |
courses:read | View courses and attendance rosters |
campaigns:read | View campaigns and their reporting |
Write and manage
| Permission | Grants |
|---|---|
admin:write | General admin write access |
admin:calendar:write | Change the admin calendar |
admin:bookings:write | Change bookings; walk-in grid and walk-in create |
admin:bookings:create | Create bookings, including free and zero-price bookings |
admin:products:write | Create and edit products and the catalog |
admin:pricing:adjust | Adjust the price of a booking |
schedules:manage | Create and edit schedules and blackouts, regenerate slots |
promotions:manage | Create, edit and delete promotions and vouchers |
pricing:manage | Create, edit and delete pricing rulesets and rules |
admin:capacity:override:basic | Basic capacity overrides |
admin:capacity:revoke:own | Revoke your own capacity overrides |
admin:capacity:analytics | View capacity analytics |
admin:bookings:bulk:read | Read bookings in bulk operations |
admin:bookings:bulk:cancel | Bulk-cancel bookings |
admin:bookings:bulk:update | Bulk-update bookings |
admin:bookings:bulk:notify | Bulk-notify booking customers |
admin:refunds:view | View refunds |
admin:refunds:process | Process refunds |
bookings:write | Full booking changes: mark paid, party size, complete |
bookings:create | Create bookings |
bookings:modify | Modify bookings |
bookings:checkin | Mark bookings arrived or no-show |
payments:record | Record a payment against a booking |
manage_catalog | Manage the product catalog (older key) |
manage_bookings | Manage bookings (older key) |
settings:write | Change tenant and site settings, manage API keys |
courses:manage | Author courses and mark attendance |
campaigns:manage | Configure seasonal campaigns and their doors |
customers:erase | Erase a person's personal data by email (GDPR request) |
Restricted
These three are tenant-wide and high-privilege:
| Permission | Grants |
|---|---|
tenant:manage | Manage tenant-wide configuration |
users:manage | Manage team members, roles and assignments |
billing:manage | Manage billing and the subscription |
A restricted permission can never be given through a site-scoped assignment, and only a user who holds it can put it in a role or assign it.
Roles
A role is a named bundle of permissions. There are two kinds.
System roles are built in, the same for every tenant, and can't be edited or deleted:
| Role | Key | Permissions |
|---|---|---|
| Owner | owner | Everything Admin has, plus the three restricted permissions |
| Admin | admin | All read and write-and-manage permissions except bookings:checkin and payments:record |
| Member | member | All read permissions, plus bookings:checkin, admin:bookings:write and courses:manage |
| Viewer | viewer | All read permissions |
Custom roles belong to your tenant. You pick the permissions yourself, but only permissions you hold. You can't create a role that gives more than you have.
Role assignments
An assignment gives one role to one user at one scope:
scopeType | scopeId | Effect |
|---|---|---|
tenant | Your tenant ID | The role's permissions apply everywhere in the tenant. |
site | A site ID | The role's permissions apply only to requests about that site. Restricted permissions are refused. |
A user's effective permissions for a request are their tenant-scoped permissions plus the site-scoped permissions for the site the request targets. The site comes from a siteId route parameter, a siteId or site_id query parameter, or a siteId or site_id body field.
Site assignments also limit what the user sees. Once a user has any site-scoped assignment, lists and reports show only their assigned sites, even if they also have a tenant-wide role. Owners always see every site.
RBAC API
Every endpoint below requires the users:manage permission.
| Endpoint | Description |
|---|---|
GET /api/v1/admin/rbac/permissions | The permission catalogue. |
GET /api/v1/admin/rbac/roles | System roles and your custom roles. |
POST /api/v1/admin/rbac/roles | Create a custom role. |
PUT /api/v1/admin/rbac/roles/{id} | Replace a custom role's name, description and permissions. |
DELETE /api/v1/admin/rbac/roles/{id} | Delete a custom role. Its assignments go with it. |
GET /api/v1/admin/rbac/assignments?userId= | One user's assignments. |
POST /api/v1/admin/rbac/assignments | Assign a role to a user. |
DELETE /api/v1/admin/rbac/assignments/{id} | Remove an assignment. |
List permissions
GET /api/v1/admin/rbac/permissions returns every permission, each marked with whether you hold it. Use held to grey out what you can't grant.
[
{
"key": "promotions:manage",
"description": "Create, edit, and delete promotions and vouchers",
"restricted": false,
"held": true
}
]
Roles
GET /api/v1/admin/rbac/roles returns an array of roles:
[
{
"id": "role-id",
"key": "admin",
"name": "Admin",
"description": "Full read and write access to operations and catalog.",
"isSystem": true,
"tenantId": null,
"permissions": ["admin:read", "admin:write"]
}
]
tenantId is null for system roles and your tenant ID for custom roles.
To create a custom role, send:
{
"name": "Front desk lead",
"description": "Check-in plus refunds",
"permissions": [
"admin:read",
"admin:bookings:read",
"bookings:checkin",
"admin:refunds:process"
]
}
| Field | Required | Description |
|---|---|---|
name | Yes | 1 to 100 characters. Must be unique in the tenant. |
description | No | Up to 500 characters. |
permissions | Yes | Permission keys from the catalogue. |
The response is the new role. PUT /api/v1/admin/rbac/roles/{id} takes the same body and replaces the role's contents.
| Status | Cause |
|---|---|
400 | Unknown permission key, or a role with a matching name already exists. |
403 | The role includes a permission you don't hold, or you tried to edit or delete a system role. |
404 | No such custom role in your tenant. |
Assignments
To assign a role, send:
{
"userId": "user-id",
"roleId": "role-id",
"scopeType": "site",
"scopeId": "your-site-id"
}
The response, and each item from GET /api/v1/admin/rbac/assignments?userId=, looks like this:
{
"id": "assignment-id",
"userId": "user-id",
"roleId": "role-id",
"roleKey": "member",
"roleName": "Member",
"scopeType": "site",
"scopeId": "your-site-id"
}
| Status | Cause |
|---|---|
400 | For tenant scope, scopeId is not your tenant ID. For site scope, the site is not in your tenant. |
403 | The role includes a permission you don't hold at that scope, or a restricted permission at site scope. |
404 | No such role or assignment. |
DELETE /api/v1/admin/rbac/roles/{id} and DELETE /api/v1/admin/rbac/assignments/{id} return 204 with no body.
In the admin console, the same actions are under Settings > Team.