Skip to content

Roles

Roles define what each team member can do in BenchKey. Every workspace has the four built-in roles, owner, admin, tech, viewer, and owners can define custom roles (Settings → Team & Access → Roles & Permissions) with their own permission matrix.

These read-only endpoints make the role catalog discoverable, so your integration never has to hardcode the builtins and guess at customs. The slug values are what you’ll see in the user object’s role field and what you can pass to the role list filter.

Assignability is narrower than the catalog. The app never assigns the owner role through team management, and the public change-role endpoint currently accepts only tech and viewer as targets. This resource is discovery, it tells you which slugs exist and which values you may encounter when reading users.

{
"object": "role",
"slug": "tech",
"name": "Technician",
"builtin": true,
"description": null
}
FieldTypeDescription
slugstringStable identifier accepted by the user role endpoints
namestringDisplay label
builtinbooleantrue for the system roles (owner/admin/tech/viewer)
descriptionstring|nullOwner-written description (custom roles)

GET /api/v1/roles

Returns every role a team member can hold in this workspace: the four built-in roles plus any custom roles the owner has defined, cursor-paginated in the app’s own display order.

Scope required: team.read

ParameterTypeDescription
limitintegerPage size, 1–100 (default: 25)
cursorstringOpaque cursor from a previous response’s next_cursor
Terminal window
curl "https://app.benchkey.com/api/v1/roles" \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa"
const res = await fetch("https://app.benchkey.com/api/v1/roles", {
headers: { Authorization: "Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa" },
});
const { data } = await res.json();
const slugs = data.map((r) => r.slug); // ["owner", "admin", "tech", "viewer", "front-desk", ...]
{
"object": "list",
"data": [
{ "object": "role", "slug": "owner", "name": "Owner", "builtin": true, "description": null },
{ "object": "role", "slug": "admin", "name": "Admin", "builtin": true, "description": null },
{ "object": "role", "slug": "tech", "name": "Technician", "builtin": true, "description": null },
{ "object": "role", "slug": "viewer", "name": "Viewer", "builtin": true, "description": null },
{ "object": "role", "slug": "front-desk", "name": "Front Desk", "builtin": false, "description": "Check-in and checkout only" }
],
"has_more": false,
"next_cursor": null
}

See Pagination for how to page through results.


GET /api/v1/roles/:slug

Returns a single role by its slug (case-insensitive), e.g. tech or a custom slug.

Scope required: team.read

Terminal window
curl "https://app.benchkey.com/api/v1/roles/front-desk" \
-H "Authorization: Bearer bk_live_01J8X4_kvWz9nP3mRqTs7uYeBfGhDjLa"

Returns the role object. Returns 404 if no role with that slug exists in this workspace.


HTTP statusCodeMeaning
400invalid_queryA query parameter was supplied as an array or object instead of a single scalar value
400invalid_cursorThe pagination cursor is malformed
404not_foundNo role with that slug exists in this workspace
403insufficient_scopeAPI key lacks team.read

See Errors for the full error envelope format.

System status