Create Role
POST /roles
Define a new role. It grants nobody anything until it is assigned.
Two of the app’s own guards run inside the handler and are not duplicated
here: _assert_can_grant_permissions refuses a permission the CALLER does
not hold, and _require_teams_manage refuses manages_role_slugs without
teams:manage. Both reach the caller as a 403 with the app’s own message.
This is write rather than destructive on purpose: a brand-new role is
held by no one, so creating it changes nobody’s access. Editing one does -
which is why PUT /roles/{role_id} is tiered differently.
Authorizations
Parameters
Header Parameters
Request Body required
Define a new role. Mirrors roles.RoleCreateRequest.
permissions is bounded by the app’s own non-escalation guard
(_assert_can_grant_permissions): a caller may not mint a role granting a
permission they do not themselves hold. That guard runs INSIDE the handler
and is deliberately not duplicated here - see the router docstring.
object
Per-role reveal/ownership limits. Mirrors roles.RepLimitsSettings.
The three Literals are closed here rather than left as strings because
they reach the app’s own Literal inside _apply_rep_limits.
Responses
201
Successful Response
object
An open envelope for a single role, team, member or account record.
Open on purpose. The app’s own response models on this surface grow with
the product - RoleResponse gained rep_limits and manages_role_slugs,
TeamResponse gained channel counts and a campaign count - and a pinned
mirror would SILENTLY DROP whatever it had not caught up on. A dropped
permission in a role read is the worst possible kind of stale: it reads as
“they do not have it”.
object
object
Whether there are more pages
Items per page
Current page number (1-indexed)
Total number of items
422
Validation Error