Skip to main content

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​

PermissionGrants
admin:readRead access to the admin console
admin:calendar:readView the admin calendar
admin:bookings:readView bookings in the admin console
admin:products:readView products and the catalog
admin:customers:viewView customer records
admin:capacity:viewView capacity information
reporting:readView reports and analytics
bookings:readRead booking data
bookings:holdCreate a temporary booking hold
pricing:readView pricing
promotions:readView promotions
courses:readView courses and attendance rosters
campaigns:readView campaigns and their reporting

Write and manage​

PermissionGrants
admin:writeGeneral admin write access
admin:calendar:writeChange the admin calendar
admin:bookings:writeChange bookings; walk-in grid and walk-in create
admin:bookings:createCreate bookings, including free and zero-price bookings
admin:products:writeCreate and edit products and the catalog
admin:pricing:adjustAdjust the price of a booking
schedules:manageCreate and edit schedules and blackouts, regenerate slots
promotions:manageCreate, edit and delete promotions and vouchers
pricing:manageCreate, edit and delete pricing rulesets and rules
admin:capacity:override:basicBasic capacity overrides
admin:capacity:revoke:ownRevoke your own capacity overrides
admin:capacity:analyticsView capacity analytics
admin:bookings:bulk:readRead bookings in bulk operations
admin:bookings:bulk:cancelBulk-cancel bookings
admin:bookings:bulk:updateBulk-update bookings
admin:bookings:bulk:notifyBulk-notify booking customers
admin:refunds:viewView refunds
admin:refunds:processProcess refunds
bookings:writeFull booking changes: mark paid, party size, complete
bookings:createCreate bookings
bookings:modifyModify bookings
bookings:checkinMark bookings arrived or no-show
payments:recordRecord a payment against a booking
manage_catalogManage the product catalog (older key)
manage_bookingsManage bookings (older key)
settings:writeChange tenant and site settings, manage API keys
courses:manageAuthor courses and mark attendance
campaigns:manageConfigure seasonal campaigns and their doors
customers:eraseErase a person's personal data by email (GDPR request)

Restricted​

These three are tenant-wide and high-privilege:

PermissionGrants
tenant:manageManage tenant-wide configuration
users:manageManage team members, roles and assignments
billing:manageManage 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:

RoleKeyPermissions
OwnerownerEverything Admin has, plus the three restricted permissions
AdminadminAll read and write-and-manage permissions except bookings:checkin and payments:record
MembermemberAll read permissions, plus bookings:checkin, admin:bookings:write and courses:manage
ViewerviewerAll 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:

scopeTypescopeIdEffect
tenantYour tenant IDThe role's permissions apply everywhere in the tenant.
siteA site IDThe 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.

EndpointDescription
GET /api/v1/admin/rbac/permissionsThe permission catalogue.
GET /api/v1/admin/rbac/rolesSystem roles and your custom roles.
POST /api/v1/admin/rbac/rolesCreate 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/assignmentsAssign 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"
]
}
FieldRequiredDescription
nameYes1 to 100 characters. Must be unique in the tenant.
descriptionNoUp to 500 characters.
permissionsYesPermission 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.

StatusCause
400Unknown permission key, or a role with a matching name already exists.
403The role includes a permission you don't hold, or you tried to edit or delete a system role.
404No 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"
}
StatusCause
400For tenant scope, scopeId is not your tenant ID. For site scope, the site is not in your tenant.
403The role includes a permission you don't hold at that scope, or a restricted permission at site scope.
404No 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.