---
title: "Apply User Role Change"
method: POST
path: "/internal/migration/users/{user_id}/apply"
tags: ["internal"]
---

# Apply User Role Change

`POST /internal/migration/users/{user_id}/apply`

## Request

- Base URL: `https://api.kobaltlabs.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.kobaltlabs.com/internal/migration/users/{user_id}/apply`
- Auth: none declared

Move a user's role attachments: add company roles, remove (typically global) roles.

DB-only by design — company-scoped archetype roles are never mirrored to SuperTokens
(authz reads the DB; only the global ``kobalt_admin`` claim is mirrored, and this flow
never touches it). Invalidates the user's permission + vendor-access caches so the change
takes effect at once across replicas.

## Path parameters

- `user_id` string, uuid, required

## Request body

- UserRoleChangeRequest
  - `add_role_ids` string[]
  - `remove_role_ids` string[]

## Response `200`

Successful Response

- ApplyUserRoleChangeResponse
  - `user_id` string, required
  - `roles` MigrationUserRole[], required
    - `role_id` string, required
    - `role_name` string, required
    - `scope` string, required
    - `archetype` 'tprm_admin' | 'business_owner' | 'tprm_analyst' | 'sme' | 'view_only' | 'collateral_admin' | 'collateral_reviewer' | 'collateral_submitter' | 'policy_reviewer': Closed, product-owned set of role identities. Stable machine keys — never renamed.
    - `module` string, nullable
  - `added` string[], required
  - `removed` string[], required

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/kobaltlabs/apis/kobaltlabs-api.md) - [All operations](https://skmtc.dev/kobaltlabs/apis/kobaltlabs-api/llms.txt) - [OpenAPI document](https://skmtc.dev/kobaltlabs/apis/kobaltlabs-api/revisions/8587332d5e43?raw)
