Skip to content

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

X-Target-Org-Id
Any of:
string

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
description
Any of:
string
manages_role_slugs
Any of:
Array<string>
name
required
string
>= 1 characters <= 100 characters
permissions
Array<string>
rep_limits
Any of:

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.

object
conflict_company_owned
string
default: allow
Allowed values: allow warn block
conflict_contact_active
string
default: allow
Allowed values: allow warn block
max_companies
Any of:
integer
max_contacts
Any of:
integer
reveal_monthly_credit_budget
Any of:
integer
reveal_policy
string
default: no_limit
Allowed values: within_limits monthly_credit_budget no_limit
slug
required
string
>= 1 characters <= 50 characters /^[a-z][a-z0-9_-]*$/

Responses

201

Successful Response

object
data
required

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
key
additional properties
any
pagination
Any of:
object
has_next
required

Whether there are more pages

boolean
limit
required

Items per page

integer
next_cursor
Any of:
string
notes
Any of:
Array<string>
page
required

Current page number (1-indexed)

integer
total
required

Total number of items

integer
total_available
Any of:
integer
total_is_lower_bound
Any of:
boolean

422

Validation Error

object
detail
Array<object>
object
loc
required
Array
msg
required
string
type
required
string