Custom Roles API

Overview

The Custom Roles API enables organization administrators and owners to create, manage, and assign custom roles with fine-grained permissions. Custom roles are organization-specific and can be assigned to members alongside built-in roles (owner, admin, member, staff).

Base URL

/api/v1/organizations/:orgId/roles

Authentication

All endpoints require JWT authentication via the Authorization header:
Authorization: Bearer <jwt_token>

Endpoints

Create Custom Role

POST /:orgId/roles Create a new custom role in the organization. Requires owner or admin role.

Request Body

{
  "name": "Editor",
  "description": "Can edit and publish content",
  "permissions": ["content:write", "content:publish"]
}

Parameters

  • name (string, required): Unique role name within the organization
  • description (string, optional): Human-readable role description
  • permissions (array, required): Array of permission strings in resource:action format

Response

201 Created
{
  "id": "role_abc123",
  "name": "Editor",
  "organizationId": "org_xyz789",
  "description": "Can edit and publish content",
  "permissions": ["content:write", "content:publish"],
  "createdAt": "2026-04-24T10:30:00Z",
  "createdBy": "user_def456"
}

Errors

  • 400 Bad Request: Validation failed or name already exists in organization
  • 403 Forbidden: User is not a member or lacks admin/owner role

Example

curl -X POST http://localhost:3000/api/v1/organizations/org_xyz789/roles \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Editor",
    "permissions": ["content:write", "content:publish"]
  }'

List Custom Roles

GET /:orgId/roles List all custom roles in the organization with pagination support. Requires organization membership.

Query Parameters

  • page (number, optional, default: 1): Page number for pagination
  • pageSize (number, optional, default: 20): Number of roles per page

Response

200 OK
{
  "roles": [
    {
      "id": "role_abc123",
      "name": "Editor",
      "organizationId": "org_xyz789",
      "description": "Can edit and publish content",
      "permissions": ["content:write", "content:publish"],
      "createdAt": "2026-04-24T10:30:00Z",
      "createdBy": "user_def456"
    },
    {
      "id": "role_def456",
      "name": "Reviewer",
      "organizationId": "org_xyz789",
      "description": "Can review content",
      "permissions": ["content:read", "content:review"],
      "createdAt": "2026-04-24T11:00:00Z",
      "createdBy": "user_def456"
    }
  ],
  "total": 2,
  "page": 1,
  "pageSize": 20
}

Errors

  • 403 Forbidden: User is not a member of the organization

Example

curl http://localhost:3000/api/v1/organizations/org_xyz789/roles?page=1&pageSize=10 \
  -H "Authorization: Bearer <token>"

Get Custom Role

GET /:orgId/roles/:roleId Retrieve a specific custom role by ID. Requires organization membership.

Response

200 OK
{
  "role": {
    "id": "role_abc123",
    "name": "Editor",
    "organizationId": "org_xyz789",
    "description": "Can edit and publish content",
    "permissions": ["content:write", "content:publish"],
    "createdAt": "2026-04-24T10:30:00Z",
    "createdBy": "user_def456"
  }
}

Errors

  • 403 Forbidden: User is not a member of the organization
  • 404 Not Found: Role not found or belongs to different organization

Example

curl http://localhost:3000/api/v1/organizations/org_xyz789/roles/role_abc123 \
  -H "Authorization: Bearer <token>"

Update Custom Role

PATCH /:orgId/roles/:roleId Update permissions or description of a custom role. Requires owner or admin role. Built-in roles cannot be modified.

Request Body

{
  "name": "Senior Editor",
  "description": "Can edit, publish, and archive content",
  "permissions": ["content:write", "content:publish", "content:archive"]
}

Parameters

  • name (string, optional): New role name
  • description (string, optional): New description (can be set to null)
  • permissions (array, optional): Updated permissions array

Response

200 OK
{
  "id": "role_abc123",
  "name": "Senior Editor",
  "organizationId": "org_xyz789",
  "description": "Can edit, publish, and archive content",
  "permissions": ["content:write", "content:publish", "content:archive"],
  "createdAt": "2026-04-24T10:30:00Z",
  "createdBy": "user_def456",
  "updatedAt": "2026-04-24T12:00:00Z"
}

Errors

  • 400 Bad Request: Validation failed
  • 403 Forbidden: User lacks admin/owner role or role is built-in
  • 404 Not Found: Role not found

Example

curl -X PATCH http://localhost:3000/api/v1/organizations/org_xyz789/roles/role_abc123 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "permissions": ["content:write", "content:publish", "content:archive"]
  }'

Delete Custom Role

DELETE /:orgId/roles/:roleId Delete a custom role. Requires owner or admin role. Built-in roles cannot be deleted. Role must not be assigned to any members.

Response

204 No Content

Errors

  • 400 Bad Request: Role is assigned to members
  • 403 Forbidden: User lacks admin/owner role or role is built-in
  • 404 Not Found: Role not found

Example

curl -X DELETE http://localhost:3000/api/v1/organizations/org_xyz789/roles/role_abc123 \
  -H "Authorization: Bearer <token>"

Permission Format

Permissions follow the resource:action format:
content:read
content:write
content:publish
content:delete
team:manage
settings:admin

Supported Resources & Actions

ResourceActions
contentread, write, publish, delete, archive
teamread, write, manage
settingsread, write, admin
billingread, write
Custom resources and actions can be defined per organization needs.

Member Role Assignment

Custom roles are assigned to members via the organization member API: PATCH /api/v1/organizations/:orgId/members/:memberId
{
  "roleId": "role_abc123"
}
See Organizations API Documentation for full member management details.

Built-in Roles

The following roles are built-in and cannot be modified or deleted:
  • owner: Full organization access (automatically assigned on creation)
  • admin: Organization administration (invite, remove members, manage roles)
  • member: Basic member access (view organization, list members)
  • staff: Limited staff access (organization-specific)

Error Responses

400 Bad Request

{
  "error": "Role name \"Editor\" already exists in this organization"
}

403 Forbidden

{
  "error": "Requires admin or owner role"
}
{
  "error": "Cannot modify built-in roles"
}

404 Not Found

{
  "error": "Role not found"
}
{
  "error": "Custom role not found in this organization"
}

Access Control

  • List/View Roles: Any organization member
  • Create/Update/Delete Roles: Owner or Admin only
  • Assign Roles: Owner or Admin only (via member API)

Rate Limiting

All endpoints are subject to rate limiting. See Rate Limiting Documentation for details.

Webhooks (Future)

Role changes will trigger webhooks in a future release:
  • role.created
  • role.updated
  • role.deleted

Examples

Create an Editor Role

curl -X POST http://localhost:3000/api/v1/organizations/org_xyz789/roles \
  -H "Authorization: Bearer eyJhbGc..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Content Editor",
    "description": "Can create and edit published content",
    "permissions": [
      "content:read",
      "content:write",
      "content:publish"
    ]
  }'

List All Roles

curl http://localhost:3000/api/v1/organizations/org_xyz789/roles \
  -H "Authorization: Bearer eyJhbGc..."

Assign Role to Member

curl -X PATCH http://localhost:3000/api/v1/organizations/org_xyz789/members/member_abc123 \
  -H "Authorization: Bearer eyJhbGc..." \
  -H "Content-Type: application/json" \
  -d '{
    "roleId": "role_editor_123"
  }'

Grant Additional Permissions

curl -X PATCH http://localhost:3000/api/v1/organizations/org_xyz789/roles/role_abc123 \
  -H "Authorization: Bearer eyJhbGc..." \
  -H "Content-Type: application/json" \
  -d '{
    "permissions": [
      "content:read",
      "content:write",
      "content:publish",
      "content:delete"
    ]
  }'

See Also