# Members & Roles

Tenant members, invitations, roles, and the permission registry.

Generated from `apps/api/openapi.json`. HTML version: https://docs.institflow.com/en/reference/iam

15 operations.

## POST /api/v1/invitations/accept

Accept a tenant invitation (creates the user if new, activates the membership, assigns the role).

- Operation id: `InvitationsController_accept_v1`
- Permission: —
- Auth: public (no credential)
- `Idempotency-Key`: not required

### Request body

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `token` | string | yes | ≥1 chars |
| `password` | string | no | ≥10 chars |
| `fullName` | string | no | ≥1 chars |

```json
{
  "token": "string",
  "password": "string",
  "fullName": "Ada Lovelace"
}
```

### Responses

**201** — The membership is now active.

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `tenantId` | string (uuid) | yes |  |
| `membershipId` | string (uuid) | yes |  |
| `userId` | string (uuid) | yes |  |

Every other status answers with the shared `ErrorEnvelope` — see
https://docs.institflow.com/md/en/error-codes.md

### Example request

```bash
curl -X POST "https://your-institute.example/api/v1/invitations/accept" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "token": "string",
    "password": "string",
    "fullName": "Ada Lovelace"
  }'
```

## GET /api/v1/me

The calling user’s own profile row (name, phone, locale, avatar).

- Operation id: `MeController_get_v1`
- Permission: —
- Auth: credential required
- `Idempotency-Key`: not required

### Responses

**200** — Success.

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes |  |
| `email` | string (email) | yes |  |
| `fullName` | string | yes |  |
| `phone` | string \| null | yes |  |
| `locale` | enum: "ar" \| "en" \| "he" | yes |  |
| `avatarFileId` | string (uuid) \| null | yes |  |
| `status` | enum: "active" \| "disabled" | yes |  |
| `emailVerified` | boolean | yes |  |

Every other status answers with the shared `ErrorEnvelope` — see
https://docs.institflow.com/md/en/error-codes.md

### Example request

```bash
curl -X GET "https://your-institute.example/api/v1/me" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"
```

## PATCH /api/v1/me

Update the calling user’s own profile: full name, phone, locale, avatar file.

- Operation id: `MeController_update_v1`
- Permission: —
- Auth: credential required
- `Idempotency-Key`: required for API-key callers

### Request body

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `fullName` | string | no | 1–200 chars |
| `phone` | string \| null | no |  |
| `locale` | enum: "ar" \| "en" \| "he" | no |  |
| `avatarFileId` | string (uuid) \| null | no |  |

```json
{
  "fullName": "Ada Lovelace",
  "phone": "+15551234567",
  "locale": "ar",
  "avatarFileId": "3561389f-3561-7561-8613-3561389f3561"
}
```

### Responses

**200** — Success.

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes |  |
| `email` | string (email) | yes |  |
| `fullName` | string | yes |  |
| `phone` | string \| null | yes |  |
| `locale` | enum: "ar" \| "en" \| "he" | yes |  |
| `avatarFileId` | string (uuid) \| null | yes |  |
| `status` | enum: "active" \| "disabled" | yes |  |
| `emailVerified` | boolean | yes |  |

Every other status answers with the shared `ErrorEnvelope` — see
https://docs.institflow.com/md/en/error-codes.md

### Example request

```bash
curl -X PATCH "https://your-institute.example/api/v1/me" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "fullName": "Ada Lovelace",
    "phone": "+15551234567",
    "locale": "ar",
    "avatarFileId": "3561389f-3561-7561-8613-3561389f3561"
  }'
```

## GET /api/v1/members

List members of the active tenant (cursor-paginated).

- Operation id: `MembersController_list_v1`
- Permission: `members.manage`
- Auth: credential required
- `Idempotency-Key`: not required

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no | 1–100 · default: 25 |

### Responses

**200** — A page of members, each with their roles.

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `data` | array<object> | yes |  |
| `nextCursor` | string \| null | yes |  |

Every other status answers with the shared `ErrorEnvelope` — see
https://docs.institflow.com/md/en/error-codes.md

### Example request

```bash
curl -X GET "https://your-institute.example/api/v1/members" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"
```

## POST /api/v1/members

Invite a new member by email (sends an invitation email).

- Operation id: `MembersController_invite_v1`
- Permission: `members.manage`
- Auth: credential required
- `Idempotency-Key`: required for API-key callers

### Request body

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `email` | string (email) | yes |  |
| `roleId` | string (uuid) | yes |  |
| `branchId` | string (uuid) | no |  |

```json
{
  "email": "ada.lovelace@example.com",
  "roleId": "5b007a17-5b00-7b00-8007-5b007a175b00",
  "branchId": "390b8975-390b-790b-80b8-390b8975390b"
}
```

### Responses

**201** — The invitation was created and emailed.

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes |  |
| `email` | string (email) | yes |  |
| `expiresAt` | string (date-time) | yes |  |

Every other status answers with the shared `ErrorEnvelope` — see
https://docs.institflow.com/md/en/error-codes.md

### Example request

```bash
curl -X POST "https://your-institute.example/api/v1/members" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "email": "ada.lovelace@example.com",
    "roleId": "5b007a17-5b00-7b00-8007-5b007a175b00",
    "branchId": "390b8975-390b-790b-80b8-390b8975390b"
  }'
```

## DELETE /api/v1/members/{id}

Remove a member from the tenant.

- Operation id: `MembersController_remove_v1`
- Permission: `members.manage`
- Auth: credential required
- `Idempotency-Key`: required for API-key callers

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Responses

**200** — The member was removed.

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `ok` | enum: true | yes |  |

Every other status answers with the shared `ErrorEnvelope` — see
https://docs.institflow.com/md/en/error-codes.md

### Example request

```bash
curl -X DELETE "https://your-institute.example/api/v1/members/37386ae0-3738-7738-8386-37386ae03738" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"
```

## PATCH /api/v1/members/{id}

Update a member’s status (active/disabled).

- Operation id: `MembersController_updateStatus_v1`
- Permission: `members.manage`
- Auth: credential required
- `Idempotency-Key`: required for API-key callers

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `status` | enum: "active" \| "disabled" | yes |  |

```json
{
  "status": "active"
}
```

### Responses

**200** — The member’s status was updated.

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `ok` | enum: true | yes |  |

Every other status answers with the shared `ErrorEnvelope` — see
https://docs.institflow.com/md/en/error-codes.md

### Example request

```bash
curl -X PATCH "https://your-institute.example/api/v1/members/37386ae0-3738-7738-8386-37386ae03738" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "status": "active"
  }'
```

## POST /api/v1/members/{id}/roles

Assign a role to a member (optionally scoped to one branch).

- Operation id: `MembersController_assignRole_v1`
- Permission: `members.manage`
- Auth: credential required
- `Idempotency-Key`: required for API-key callers

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `roleId` | string (uuid) | yes |  |
| `branchId` | string (uuid) | no |  |

```json
{
  "roleId": "5b007a17-5b00-7b00-8007-5b007a175b00",
  "branchId": "390b8975-390b-790b-80b8-390b8975390b"
}
```

### Responses

**201** — The role was assigned.

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `ok` | enum: true | yes |  |

Every other status answers with the shared `ErrorEnvelope` — see
https://docs.institflow.com/md/en/error-codes.md

### Example request

```bash
curl -X POST "https://your-institute.example/api/v1/members/37386ae0-3738-7738-8386-37386ae03738/roles" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "roleId": "5b007a17-5b00-7b00-8007-5b007a175b00",
    "branchId": "390b8975-390b-790b-80b8-390b8975390b"
  }'
```

## DELETE /api/v1/members/{id}/roles/{roleId}

Unassign a role from a member.

- Operation id: `MembersController_unassignRole_v1`
- Permission: `members.manage`
- Auth: credential required
- `Idempotency-Key`: required for API-key callers

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `roleId` | path | string | yes |  |

### Responses

**200** — The role was unassigned.

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `ok` | enum: true | yes |  |

Every other status answers with the shared `ErrorEnvelope` — see
https://docs.institflow.com/md/en/error-codes.md

### Example request

```bash
curl -X DELETE "https://your-institute.example/api/v1/members/37386ae0-3738-7738-8386-37386ae03738/roles/5b007a17-5b00-7b00-8007-5b007a175b00" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"
```

## GET /api/v1/permissions

The full permission-key registry (docs/specs/phase1-kernel.md).

- Operation id: `PermissionsController_list_v1`
- Permission: —
- Auth: credential required
- `Idempotency-Key`: not required

### Responses

**200** — Every permission key known to the platform.

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `permissions` | array<string> | yes |  |

Every other status answers with the shared `ErrorEnvelope` — see
https://docs.institflow.com/md/en/error-codes.md

### Example request

```bash
curl -X GET "https://your-institute.example/api/v1/permissions" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"
```

## GET /api/v1/roles

List every role defined in the active tenant.

- Operation id: `RolesController_list_v1`
- Permission: `roles.manage`
- Auth: credential required
- `Idempotency-Key`: not required

### Responses

**200** — The tenant’s roles, each with its resolved permission set.

```json
[
  {
    "id": "37386ae0-3738-7738-8386-37386ae03738",
    "tenantId": "4332af8b-4332-7332-832a-4332af8b4332",
    "key": "string",
    "name": "Algebra I",
    "description": "A short, human-readable description.",
    "isSystem": true,
    "createdAt": "2026-03-02T09:00:00.000Z",
    "updatedAt": "2026-03-02T09:00:00.000Z",
    "permissions": [
      "string"
    ]
  }
]
```

Every other status answers with the shared `ErrorEnvelope` — see
https://docs.institflow.com/md/en/error-codes.md

### Example request

```bash
curl -X GET "https://your-institute.example/api/v1/roles" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"
```

## POST /api/v1/roles

Create a custom role.

- Operation id: `RolesController_create_v1`
- Permission: `roles.manage`
- Auth: credential required
- `Idempotency-Key`: required for API-key callers

### Request body

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `name` | string | yes | 1–100 chars |
| `description` | string | no | 0–500 chars |

```json
{
  "name": "Algebra I",
  "description": "A short, human-readable description."
}
```

### Responses

**201** — The newly created role.

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes |  |
| `tenantId` | string (uuid) | yes |  |
| `key` | string \| null | yes | ≥1 chars |
| `name` | string | yes |  |
| `description` | string \| null | yes | 0–500 chars |
| `isSystem` | boolean | yes |  |
| `createdAt` | string (date-time) | yes |  |
| `updatedAt` | string (date-time) | yes |  |

Every other status answers with the shared `ErrorEnvelope` — see
https://docs.institflow.com/md/en/error-codes.md

### Example request

```bash
curl -X POST "https://your-institute.example/api/v1/roles" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "name": "Algebra I",
    "description": "A short, human-readable description."
  }'
```

## DELETE /api/v1/roles/{id}

Delete a custom role (system roles cannot be deleted).

- Operation id: `RolesController_remove_v1`
- Permission: `roles.manage`
- Auth: credential required
- `Idempotency-Key`: required for API-key callers

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Responses

**200** — The role was deleted.

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `ok` | enum: true | yes |  |

Every other status answers with the shared `ErrorEnvelope` — see
https://docs.institflow.com/md/en/error-codes.md

### Example request

```bash
curl -X DELETE "https://your-institute.example/api/v1/roles/37386ae0-3738-7738-8386-37386ae03738" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY"
```

## PATCH /api/v1/roles/{id}

Update a role’s name/description (the system `owner` role is immutable).

- Operation id: `RolesController_update_v1`
- Permission: `roles.manage`
- Auth: credential required
- `Idempotency-Key`: required for API-key callers

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `name` | string | no | 1–100 chars |
| `description` | string \| null | no | 0–500 chars |

```json
{
  "name": "Algebra I",
  "description": "A short, human-readable description."
}
```

### Responses

**200** — The updated role.

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes |  |
| `tenantId` | string (uuid) | yes |  |
| `key` | string \| null | yes | ≥1 chars |
| `name` | string | yes |  |
| `description` | string \| null | yes | 0–500 chars |
| `isSystem` | boolean | yes |  |
| `createdAt` | string (date-time) | yes |  |
| `updatedAt` | string (date-time) | yes |  |

Every other status answers with the shared `ErrorEnvelope` — see
https://docs.institflow.com/md/en/error-codes.md

### Example request

```bash
curl -X PATCH "https://your-institute.example/api/v1/roles/37386ae0-3738-7738-8386-37386ae03738" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "name": "Algebra I",
    "description": "A short, human-readable description."
  }'
```

## PUT /api/v1/roles/{id}/permissions

Replace a role’s permission set. A caller can only grant permissions they themselves hold.

- Operation id: `RolesController_updatePermissions_v1`
- Permission: `roles.manage`
- Auth: credential required
- `Idempotency-Key`: required for API-key callers

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Property | Type | Required | Constraints |
| --- | --- | --- | --- |
| `permissions` | array<string> | yes |  |

```json
{
  "permissions": [
    "string"
  ]
}
```

### Responses

**200** — The role’s new permission set.

```json
[
  "string"
]
```

Every other status answers with the shared `ErrorEnvelope` — see
https://docs.institflow.com/md/en/error-codes.md

### Example request

```bash
curl -X PUT "https://your-institute.example/api/v1/roles/37386ae0-3738-7738-8386-37386ae03738/permissions" \
  -H "Authorization: Bearer $INSTITFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "permissions": [
      "string"
    ]
  }'
```
