@canopy-io/node 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1095,6 +1095,170 @@ interface paths {
1095
1095
  patch?: never;
1096
1096
  trace?: never;
1097
1097
  };
1098
+ "/api/v1/organizations/{id}/me": {
1099
+ parameters: {
1100
+ query?: never;
1101
+ header?: never;
1102
+ path?: never;
1103
+ cookie?: never;
1104
+ };
1105
+ /**
1106
+ * What the caller administers in an organization
1107
+ * @description The authority read a customer's admin screen renders from: whether the caller holds `canopy:organization.manage` at the organization node (`administers_organization`), the topmost nodes where they hold `canopy:access.manage` inside it (`access_roots`, each with its name, type and the path of names from the organization down to it; the organization node itself when they administer the organization), the same for the structure and roles keys (empty until those ship), and whether the Environment's schema allows nodes beneath an organization (`has_hierarchy`). Computed from assignments at or beneath the organization node only, so a role held above every organization does not count. The developer's key answers as administering the whole organization. Refused with `403` for a caller holding nothing inside the organization.
1108
+ */
1109
+ get: operations["ApiOrganizationAccessController_me"];
1110
+ put?: never;
1111
+ post?: never;
1112
+ delete?: never;
1113
+ options?: never;
1114
+ head?: never;
1115
+ patch?: never;
1116
+ trace?: never;
1117
+ };
1118
+ "/api/v1/organizations/{id}/tree": {
1119
+ parameters: {
1120
+ query?: never;
1121
+ header?: never;
1122
+ path?: never;
1123
+ cookie?: never;
1124
+ };
1125
+ /**
1126
+ * List the organization's tree as the caller sees it
1127
+ * @description The organization's subtree pruned to the caller: every node beneath a node they administer is `accessible`, the ancestors between the organization node and such a node are `context_only`, and nothing else is returned. A paged flat list, each row carrying its parent, in the shape of the developer's node listing. Admitted to whoever the authority read admits.
1128
+ */
1129
+ get: operations["ApiOrganizationAccessController_tree"];
1130
+ put?: never;
1131
+ post?: never;
1132
+ delete?: never;
1133
+ options?: never;
1134
+ head?: never;
1135
+ patch?: never;
1136
+ trace?: never;
1137
+ };
1138
+ "/api/v1/organizations/{id}/nodes/{nodeId}/access": {
1139
+ parameters: {
1140
+ query?: never;
1141
+ header?: never;
1142
+ path?: never;
1143
+ cookie?: never;
1144
+ };
1145
+ /**
1146
+ * List who holds a role at a node in the organization
1147
+ * @description Who holds a role at the node, directly or inherited from a node above it inside the organization: one row per assignment with the identity, the role, where it was granted and its window. Paginated; filtered and sorted as the developer's node identities listing is. Requires `hierarchy.view` at the node, or `canopy:organization.manage` at the organization, or `canopy:access.manage` at the node or above it.
1148
+ */
1149
+ get: operations["ApiOrganizationAccessController_listAccess"];
1150
+ put?: never;
1151
+ post?: never;
1152
+ delete?: never;
1153
+ options?: never;
1154
+ head?: never;
1155
+ patch?: never;
1156
+ trace?: never;
1157
+ };
1158
+ "/api/v1/organizations/{id}/nodes/{nodeId}/access/summary": {
1159
+ parameters: {
1160
+ query?: never;
1161
+ header?: never;
1162
+ path?: never;
1163
+ cookie?: never;
1164
+ };
1165
+ /**
1166
+ * Summarize who holds a role at a node in the organization
1167
+ * @description The counts over the node's assignments: direct and inherited people, by status, roles in use and the most recent arrivals, with `can_manage_assignments` saying whether the caller may change them. Requires the same as the node access listing.
1168
+ */
1169
+ get: operations["ApiOrganizationAccessController_accessSummary"];
1170
+ put?: never;
1171
+ post?: never;
1172
+ delete?: never;
1173
+ options?: never;
1174
+ head?: never;
1175
+ patch?: never;
1176
+ trace?: never;
1177
+ };
1178
+ "/api/v1/organizations/{id}/nodes/{nodeId}/grantable-roles": {
1179
+ parameters: {
1180
+ query?: never;
1181
+ header?: never;
1182
+ path?: never;
1183
+ cookie?: never;
1184
+ };
1185
+ /**
1186
+ * List the roles the caller may grant at a node
1187
+ * @description The active, assignable roles of the Environment kept to the ones the caller may grant at the node under the grant ceiling: for an identity, those whose every permission it holds at the node or above; every assignable role for the developer's key and Console users. The list a picker offers, so nothing it shows is refused on write. Requires `canopy:access.manage` at the node or above it, `canopy:organization.manage` at the organization, or `hierarchy.manage` at the node. The response is an unpaginated `{ items }` array.
1188
+ */
1189
+ get: operations["ApiOrganizationAccessController_grantableRoles"];
1190
+ put?: never;
1191
+ post?: never;
1192
+ delete?: never;
1193
+ options?: never;
1194
+ head?: never;
1195
+ patch?: never;
1196
+ trace?: never;
1197
+ };
1198
+ "/api/v1/organizations/{id}/nodes/{nodeId}/members": {
1199
+ parameters: {
1200
+ query?: never;
1201
+ header?: never;
1202
+ path?: never;
1203
+ cookie?: never;
1204
+ };
1205
+ /**
1206
+ * List the organization's members, for granting a role at a node
1207
+ * @description The organization's members as candidates for a role at the node: each row names the identity only. Paginated; `q` searches name and email. Requires the same as the grantable-roles read at the node, so an administrator of one office may choose from the whole organization's roster without reading what anyone else holds.
1208
+ */
1209
+ get: operations["ApiOrganizationAccessController_listMembersAt"];
1210
+ put?: never;
1211
+ post?: never;
1212
+ delete?: never;
1213
+ options?: never;
1214
+ head?: never;
1215
+ patch?: never;
1216
+ trace?: never;
1217
+ };
1218
+ "/api/v1/organizations/{id}/assignments": {
1219
+ parameters: {
1220
+ query?: never;
1221
+ header?: never;
1222
+ path?: never;
1223
+ cookie?: never;
1224
+ };
1225
+ get?: never;
1226
+ put?: never;
1227
+ /**
1228
+ * Grant a role at a node beneath the organization
1229
+ * @description Grants `role_id` to `identity_id` at `node_id`, the organization node or one beneath it. The identity must be a member of the organization (`409 organization.membership_required` otherwise). Requires `rbac.manage_assignments` at the node, `canopy:organization.manage` at the organization, or `canopy:access.manage` at the node or above it, within the grant ceiling. Emits `assignment.created`.
1230
+ */
1231
+ post: operations["ApiOrganizationAccessController_createAssignment"];
1232
+ delete?: never;
1233
+ options?: never;
1234
+ head?: never;
1235
+ patch?: never;
1236
+ trace?: never;
1237
+ };
1238
+ "/api/v1/organizations/{id}/assignments/{assignmentId}": {
1239
+ parameters: {
1240
+ query?: never;
1241
+ header?: never;
1242
+ path?: never;
1243
+ cookie?: never;
1244
+ };
1245
+ get?: never;
1246
+ put?: never;
1247
+ post?: never;
1248
+ /**
1249
+ * Take a grant in the organization away
1250
+ * @description Removes an assignment at the organization node or beneath it; the membership stays. Never bounded by the grant ceiling, but the last administrator's role at the organization node cannot be removed (`409 organization.last_admin`). Requires the same as creating one.
1251
+ */
1252
+ delete: operations["ApiOrganizationAccessController_removeAssignment"];
1253
+ options?: never;
1254
+ head?: never;
1255
+ /**
1256
+ * Change a grant in the organization
1257
+ * @description Changes the role or the window of an assignment at the organization node or beneath it. A new role meets the grant ceiling; dates alone do not. The last administrator's role at the organization node cannot be changed away (`409 organization.last_admin`). Requires the same as creating one.
1258
+ */
1259
+ patch: operations["ApiOrganizationAccessController_updateAssignment"];
1260
+ trace?: never;
1261
+ };
1098
1262
  "/api/v1/organizations": {
1099
1263
  parameters: {
1100
1264
  query?: never;
@@ -1352,13 +1516,13 @@ interface paths {
1352
1516
  };
1353
1517
  /**
1354
1518
  * List an organization's members
1355
- * @description Lists the organization's members: each row is the member's identity, their single role in this organization, effective dates, when they joined, and `node_assignments`, the grants the member also holds at nodes beneath the organization (empty in a flat Environment). Paginated; `q` searches name and email. Requires the `rbac.view_assignments` permission at the organization.
1519
+ * @description Lists the organization's members: each row is the membership (its `status`, `source` and `joined_at`), the member's identity, and `roles`, every role assignment the member holds in the organization, at its node and beneath, with the node and the effective window. Active members by default; `status=deactivated` lists those who left and `status=all` both. Paginated; `q` searches name and email, `role_id` keeps members holding that role anywhere in the organization. Requires the `rbac.view_assignments` permission at the organization.
1356
1520
  */
1357
1521
  get: operations["ApiOrganizationsController_listMembers"];
1358
1522
  put?: never;
1359
1523
  /**
1360
1524
  * Add a member to an organization
1361
- * @description Adds a member: assigns `role_id` to `identity_id` at the organization. The identity must already hold an active membership in this Environment (invite by email instead for someone who does not). A member holds exactly one role per organization, so an identity that is already a member returns `409` — use the change-role operation. Requires the `rbac.manage_assignments` permission at the organization and emits `organization.member.added`. An organization's own administrator, signed in with an identity token and admitted by `canopy:organization.manage` alone, is refused with `403` (`organization.member_add_requires_invite`): the person never agreed to join, so the administrator invites them instead.
1525
+ * @description Adds a member. Membership is admission, not authority: with `role_id` the member also holds that role from the start, at the organization node or at the office or team `node_id` names, for the `effective_from` to `effective_to` window when given; without it they belong and hold nothing until a role is assigned (a place or dates need a role, `400 invite.window_requires_role`). The identity must already hold an active membership in this Environment (invite by email instead for someone who does not). An identity that is already a member returns `409`; roles are added through the assignment routes. Requires the `rbac.manage_assignments` permission at the organization and emits `organization.member.added`. An organization's own administrator, signed in with an identity token and admitted by `canopy:organization.manage` alone, is refused with `403` (`organization.member_add_requires_invite`): the person never agreed to join, so the administrator invites them instead.
1362
1526
  */
1363
1527
  post: operations["ApiOrganizationsController_addMember"];
1364
1528
  delete?: never;
@@ -1379,16 +1543,12 @@ interface paths {
1379
1543
  post?: never;
1380
1544
  /**
1381
1545
  * Remove a member from an organization
1382
- * @description Removes the member from this organization, revoking their role here and nothing else — the identity and its memberships in other organizations are untouched. Returns `404` when the identity is not a member. Responds `204 No Content`, requires the `rbac.manage_assignments` permission at the organization, and emits `organization.member.removed`.
1546
+ * @description Removes the member from this organization: the membership is deactivated and every role assignment they hold at the organization's nodes goes with it, and nothing else; the identity and its memberships in other organizations are untouched. Returns `404` when the identity is not an active member and `409` when they are the last administrator. Responds `204 No Content`, requires the `rbac.manage_assignments` permission at the organization, and emits `organization.member.removed`.
1383
1547
  */
1384
1548
  delete: operations["ApiOrganizationsController_removeMember"];
1385
1549
  options?: never;
1386
1550
  head?: never;
1387
- /**
1388
- * Change a member's role
1389
- * @description Replaces the member's role in this organization with `role_id`. A member holds exactly one role per organization, so this updates the existing membership in place; changing to the role already held is a no-op. Returns `404` when the identity is not a member. Requires the `rbac.manage_assignments` permission at the organization and emits `organization.member.role_changed`.
1390
- */
1391
- patch: operations["ApiOrganizationsController_changeMemberRole"];
1551
+ patch?: never;
1392
1552
  trace?: never;
1393
1553
  };
1394
1554
  "/api/v1/organizations/{id}/members/{identityId}/mfa/reset": {
@@ -1426,7 +1586,7 @@ interface paths {
1426
1586
  put?: never;
1427
1587
  /**
1428
1588
  * Invite a member into an organization
1429
- * @description Invites an email into the organization with the role bound to the invitation; acceptance creates the Environment membership and the organization membership in one step. Works for emails with no identity in the Environment — one is created on acceptance. Requires the `identity.manage` permission and emits `invite.created`.
1589
+ * @description Invites an email into the organization. `role_id` is held on acceptance at `node_id`, the organization node (the default) or an office or team beneath it, for the `effective_from` to `effective_to` window when given; with no `role_id` the invitation admits a member holding nothing, which only the organization node allows (`400 invite.malformed_assignment` beneath it). Acceptance creates what is missing in one transaction: the identity, its Environment membership, the organization membership and the role. For someone who already holds an active membership in this Environment the invitation is a request to join (`intent: grant`): accepting is their consent, proven by their password or their own sign-in. Requires the `identity.manage` permission, or `canopy:organization.manage` at the organization or `canopy:access.manage` at the place for the organization's own administrators, and emits `invite.created`.
1430
1590
  */
1431
1591
  post: operations["ApiOrganizationsController_createInvite"];
1432
1592
  delete?: never;
@@ -1444,7 +1604,7 @@ interface paths {
1444
1604
  };
1445
1605
  /**
1446
1606
  * List the roles an organization may assign
1447
- * @description The active, assignable roles of the organization's Environment, for choosing a member's role or an invitation's. System roles are left out, since they cannot be assigned. Requires `hierarchy.view` or `canopy:organization.manage` at the organization. The response is an unpaginated `{ items }` array.
1607
+ * @description The active, assignable roles of the organization's Environment, for choosing a member's role or an invitation's, each with `grantable`: whether the caller may grant it at the organization node under the grant ceiling (always true for the developer's key). System roles are left out, since they cannot be assigned. Requires `hierarchy.view`, `canopy:organization.manage` at the organization, or `canopy:access.manage` at the organization node. The response is an unpaginated `{ items }` array.
1448
1608
  */
1449
1609
  get: operations["ApiOrganizationsController_listRoles"];
1450
1610
  put?: never;
@@ -2504,6 +2664,7 @@ interface components {
2504
2664
  effective_node_id?: string | null;
2505
2665
  /** @description Ids of the roles whose assignments produced a node-scoped allow. Always empty for `scope_evaluated: "app_wide"`, whose answer is not tied to a node, and for a deny. */
2506
2666
  granting_roles: string[];
2667
+ /** @description Why the check was refused: `NO_ROLE_ASSIGNMENT`, `PERMISSION_NOT_GRANTED`, `NODE_SCOPE_VIOLATION`, `ROLE_EXPIRED`, `IDENTITY_INACTIVE`, `IDENTITY_NOT_ENV_MEMBER`, or `ORGANIZATION_MEMBERSHIP_INACTIVE` (assignments sit on the lineage inside an organization the identity's membership in is deactivated, so none count). Null on an allow. */
2507
2668
  denial_reason?: string | null;
2508
2669
  };
2509
2670
  EvaluatePermissionDto: {
@@ -2538,7 +2699,7 @@ interface components {
2538
2699
  assignment_id: string;
2539
2700
  role_id: string;
2540
2701
  role_name: string;
2541
- /** @description Whether the assignment counts right now: within its effective_from/effective_to window, and its role is active. An inactive role's assignments are kept but grant nothing. */
2702
+ /** @description Whether the assignment counts right now: within its effective_from/effective_to window, its role active, and, inside an organization, the holder's membership there active. An assignment that fails any of these is listed but grants nothing. */
2542
2703
  active: boolean;
2543
2704
  effective_from?: string | null;
2544
2705
  effective_to?: string | null;
@@ -2612,6 +2773,8 @@ interface components {
2612
2773
  effective_from: string | null;
2613
2774
  /** @description When this assignment expires; null means it never does */
2614
2775
  effective_to: string | null;
2776
+ /** @description Optimistic-lock version; send it back as `If-Match` */
2777
+ version: number;
2615
2778
  };
2616
2779
  IdentityRowDto: {
2617
2780
  id: string;
@@ -2758,6 +2921,8 @@ interface components {
2758
2921
  created_at: string;
2759
2922
  /** Format: date-time */
2760
2923
  updated_at: string;
2924
+ /** @description Optimistic-lock version; send it back as `If-Match` */
2925
+ version: number;
2761
2926
  };
2762
2927
  IdentityAccessibleNodesResponseDto: {
2763
2928
  /** @example reports.view */
@@ -2803,12 +2968,28 @@ interface components {
2803
2968
  name: string;
2804
2969
  role_id?: string | null;
2805
2970
  node_id?: string | null;
2971
+ /** @description The name of the node at `node_id`, when it has one. */
2972
+ node_name?: string | null;
2973
+ /** @description The organization the invitation joins, when `node_id` is an organization node or sits beneath one. */
2974
+ organization_node_id?: string | null;
2975
+ /**
2976
+ * Format: date-time
2977
+ * @description When the role it grants starts to count.
2978
+ */
2979
+ effective_from?: string | null;
2980
+ /**
2981
+ * Format: date-time
2982
+ * @description When the role it grants stops counting.
2983
+ */
2984
+ effective_to?: string | null;
2806
2985
  has_initial_assignment: boolean;
2807
2986
  /** @enum {string} */
2808
2987
  status: "pending" | "accepted" | "revoked" | "expired";
2809
2988
  /** Format: date-time */
2810
2989
  expires_at: string;
2811
2990
  invited_by: string;
2991
+ /** @description The customer's own administrator who sent it with their identity token; `invited_by` names a platform user instead. */
2992
+ invited_by_identity_id?: string | null;
2812
2993
  /** Format: date-time */
2813
2994
  created_at: string;
2814
2995
  };
@@ -2834,12 +3015,28 @@ interface components {
2834
3015
  name: string;
2835
3016
  role_id?: string | null;
2836
3017
  node_id?: string | null;
3018
+ /** @description The name of the node at `node_id`, when it has one. */
3019
+ node_name?: string | null;
3020
+ /** @description The organization the invitation joins, when `node_id` is an organization node or sits beneath one. */
3021
+ organization_node_id?: string | null;
3022
+ /**
3023
+ * Format: date-time
3024
+ * @description When the role it grants starts to count.
3025
+ */
3026
+ effective_from?: string | null;
3027
+ /**
3028
+ * Format: date-time
3029
+ * @description When the role it grants stops counting.
3030
+ */
3031
+ effective_to?: string | null;
2837
3032
  has_initial_assignment: boolean;
2838
3033
  /** @enum {string} */
2839
3034
  status: "pending" | "accepted" | "revoked" | "expired";
2840
3035
  /** Format: date-time */
2841
3036
  expires_at: string;
2842
3037
  invited_by: string;
3038
+ /** @description The customer's own administrator who sent it with their identity token; `invited_by` names a platform user instead. */
3039
+ invited_by_identity_id?: string | null;
2843
3040
  /** Format: date-time */
2844
3041
  created_at: string;
2845
3042
  /** @description Tokenized URL the invitee would land on. Returned so callers that pass send_email=false can deliver it themselves. */
@@ -2858,7 +3055,7 @@ interface components {
2858
3055
  first_name?: string;
2859
3056
  /** @description Required for `activate`. Ignored for `add_to_app` and `password_reset`. */
2860
3057
  last_name?: string;
2861
- /** @description Role ID — required if node_id is provided */
3058
+ /** @description The role the invitation grants at `node_id`. Required with a `node_id`, except an organization node, where an invitation may admit a member with no role. */
2862
3059
  role_id?: string;
2863
3060
  /** @description Node ID — required if role_id is provided */
2864
3061
  node_id?: string;
@@ -2867,6 +3064,16 @@ interface components {
2867
3064
  * @default true
2868
3065
  */
2869
3066
  send_email: boolean;
3067
+ /**
3068
+ * Format: date-time
3069
+ * @description When the role starts to count (ISO 8601). Copied onto the assignment the invitation grants; needs a role.
3070
+ */
3071
+ effective_from?: string;
3072
+ /**
3073
+ * Format: date-time
3074
+ * @description When the role stops counting (ISO 8601), after `effective_from`. Copied onto the assignment; an invitation whose window has ended by acceptance is refused with `400 invite.window_ended`.
3075
+ */
3076
+ effective_to?: string;
2870
3077
  };
2871
3078
  BulkCreateIdentityInvitesDto: {
2872
3079
  invites: components["schemas"]["CreateIdentityInviteDto"][];
@@ -2999,6 +3206,8 @@ interface components {
2999
3206
  status: "active" | "scheduled" | "expired";
3000
3207
  /** Format: date-time */
3001
3208
  created_at: string;
3209
+ /** @description Optimistic-lock version; send it back as `If-Match` */
3210
+ version: number;
3002
3211
  };
3003
3212
  IdentityAssignmentRowDto: {
3004
3213
  identity: components["schemas"]["AssignmentIdentityDto"];
@@ -3023,6 +3232,65 @@ interface components {
3023
3232
  distinct_role_count: number;
3024
3233
  recent_identities: components["schemas"]["RecentIdentityDto"][];
3025
3234
  };
3235
+ OrganizationAuthorityRootDto: {
3236
+ node_id: string;
3237
+ name: string;
3238
+ /** @description The node's type, as the schema names it */
3239
+ node_type: string;
3240
+ /** @description The names from the organization node down to this node's parent, so the node can be named in context; empty for the organization node itself */
3241
+ path: string[];
3242
+ };
3243
+ OrganizationMeResponseDto: {
3244
+ /** @description Holds `canopy:organization.manage` at the organization node, or is the developer's key */
3245
+ administers_organization: boolean;
3246
+ /** @description The topmost nodes where `canopy:access.manage` is held inside the organization; the organization node when `administers_organization` */
3247
+ access_roots: components["schemas"]["OrganizationAuthorityRootDto"][];
3248
+ /** @description The same for `canopy:structure.manage`, a key no role carries yet; always empty */
3249
+ structure_roots: components["schemas"]["OrganizationAuthorityRootDto"][];
3250
+ /** @description The same for `canopy:roles.manage`, a key no role carries yet; always empty */
3251
+ roles_roots: components["schemas"]["OrganizationAuthorityRootDto"][];
3252
+ /** @description Whether the Environment's schema allows nodes beneath an organization; false in a flat Environment, where the organization is its only node */
3253
+ has_hierarchy: boolean;
3254
+ };
3255
+ RoleResponseDto: {
3256
+ id: string;
3257
+ application_id: string;
3258
+ name: string;
3259
+ description?: string | null;
3260
+ is_system_role: boolean;
3261
+ system_key?: string | null;
3262
+ is_active: boolean;
3263
+ /** Format: date-time */
3264
+ created_at: string;
3265
+ /** Format: date-time */
3266
+ updated_at: string;
3267
+ /** @description Optimistic-lock version. Send back as the `If-Match` header when updating to detect concurrent edits. */
3268
+ version: number;
3269
+ /** @description Number of permissions currently assigned to this role. Populated on list responses; omitted on single-role responses where the join isn't computed. */
3270
+ permission_count?: number;
3271
+ /** @description Number of distinct identities assigned this role. Populated on list responses; omitted on single-role responses where the join isn't computed. */
3272
+ member_count?: number;
3273
+ };
3274
+ OrganizationMemberCandidateResponseDto: {
3275
+ identity: components["schemas"]["AssignmentIdentityDto"];
3276
+ };
3277
+ CreateOrganizationAssignmentDto: {
3278
+ /** @description A member of the organization */
3279
+ identity_id: string;
3280
+ /** @description The organization node, or a node beneath it; the identity must be an active member of the organization */
3281
+ node_id: string;
3282
+ /** @description An active, assignable role of the Environment */
3283
+ role_id: string;
3284
+ /** @description When the grant starts (ISO 8601); now when omitted */
3285
+ effective_from?: Record<string, unknown>;
3286
+ /** @description When the grant ends (ISO 8601); never when omitted */
3287
+ effective_to?: Record<string, unknown>;
3288
+ };
3289
+ UpdateAssignmentDto: {
3290
+ role_id: string;
3291
+ effective_from?: string | null;
3292
+ effective_to?: string | null;
3293
+ };
3026
3294
  OrganizationResponseDto: {
3027
3295
  id: string;
3028
3296
  name: string;
@@ -3032,7 +3300,7 @@ interface components {
3032
3300
  metadata: Record<string, unknown>;
3033
3301
  /** @description Your own id for this organization, unique per Environment. */
3034
3302
  external_id?: string | null;
3035
- /** @description Members (one role each) in this organization. */
3303
+ /** @description Active members of this organization, whatever roles they hold. */
3036
3304
  member_count: number;
3037
3305
  /** @description Unexpired, unaccepted, unrevoked invitations. */
3038
3306
  pending_invite_count: number;
@@ -3223,44 +3491,82 @@ interface components {
3223
3491
  name: string;
3224
3492
  node_type: string;
3225
3493
  };
3226
- OrganizationMemberNodeAssignmentDto: {
3494
+ OrganizationMemberAssignmentDto: {
3227
3495
  /** @description The assignment id. */
3228
3496
  id: string;
3229
- application_node: components["schemas"]["OrganizationMemberNodeDto"];
3230
- role: components["schemas"]["OrganizationMemberRoleDto"];
3231
- };
3232
- OrganizationMemberResponseDto: {
3233
- /** @description The membership (role assignment) id. */
3234
- id: string;
3235
- identity: components["schemas"]["OrganizationMemberIdentityDto"];
3236
3497
  role: components["schemas"]["OrganizationMemberRoleDto"];
3498
+ node: components["schemas"]["OrganizationMemberNodeDto"];
3237
3499
  /** Format: date-time */
3238
3500
  effective_from?: string | null;
3239
3501
  /** Format: date-time */
3240
3502
  effective_to?: string | null;
3503
+ /** @description The assignment's version, for `If-Match` on a change. */
3504
+ version: number;
3505
+ };
3506
+ OrganizationMemberResponseDto: {
3507
+ /** @description The membership id. */
3508
+ id: string;
3509
+ identity: components["schemas"]["OrganizationMemberIdentityDto"];
3510
+ /**
3511
+ * @description `active` while the identity belongs; `deactivated` once removed, kept for the organization's history.
3512
+ * @enum {string}
3513
+ */
3514
+ status: "active" | "deactivated";
3515
+ /**
3516
+ * @description How the membership began: added by an administrator, an accepted invitation, single sign-on, directory sync, or the organization's own creation on sign-up.
3517
+ * @enum {string}
3518
+ */
3519
+ source: "added" | "invitation" | "sso" | "directory_sync" | "signup";
3241
3520
  /**
3242
3521
  * Format: date-time
3243
- * @description When the membership was created.
3522
+ * @description When the current membership began.
3244
3523
  */
3245
- created_at: string;
3246
- /** @description Assignments the member also holds at nodes beneath the organization. Empty in a flat Environment. */
3247
- node_assignments: components["schemas"]["OrganizationMemberNodeAssignmentDto"][];
3524
+ joined_at: string;
3525
+ /**
3526
+ * Format: date-time
3527
+ * @description When the member was removed; null while active.
3528
+ */
3529
+ deactivated_at?: string | null;
3530
+ /** @description Every role assignment the member holds in the organization, the organization node first, then beneath it. Empty for a member who holds none. */
3531
+ roles: components["schemas"]["OrganizationMemberAssignmentDto"][];
3532
+ /** @description The membership's version. */
3533
+ version: number;
3248
3534
  };
3249
3535
  AddOrganizationMemberDto: {
3250
3536
  /** @description Identity to add. Must already hold an active membership in this Environment; invite by email instead for someone who does not. */
3251
3537
  identity_id: string;
3252
- /** @description The single role the member holds in this organization, from the Environment's roles. */
3253
- role_id: string;
3254
- };
3255
- ChangeOrganizationMemberRoleDto: {
3256
- /** @description The replacement role. A member holds exactly one role per organization, so this updates the existing membership in place. */
3257
- role_id: string;
3538
+ /** @description A role to hold at the organization node from the start, from the Environment's roles. Left out, the member belongs and holds nothing until a role is assigned. */
3539
+ role_id?: string;
3540
+ /** @description Where the role is held: the organization node (the default) or an office or team beneath it. Needs a role. */
3541
+ node_id?: string;
3542
+ /**
3543
+ * Format: date-time
3544
+ * @description When the role starts to count (ISO 8601). Needs a role.
3545
+ */
3546
+ effective_from?: string;
3547
+ /**
3548
+ * Format: date-time
3549
+ * @description When the role stops counting (ISO 8601), after `effective_from`. Needs a role.
3550
+ */
3551
+ effective_to?: string;
3258
3552
  };
3259
3553
  CreateOrganizationInviteDto: {
3260
3554
  /** @description Email to invite. Works for people with no identity in this Environment — one is created when they accept. */
3261
3555
  email: string;
3262
- /** @description The role the member will hold in this organization on acceptance. */
3263
- role_id: string;
3556
+ /** @description The role the person holds on acceptance, at `node_id`. Optional at the organization node, where accepting admits a member with no role; required for a place beneath it. */
3557
+ role_id?: string;
3558
+ /** @description Where the role is held: the organization node (the default) or an office or team beneath it. Accepting admits the person to the organization either way. */
3559
+ node_id?: string;
3560
+ /**
3561
+ * Format: date-time
3562
+ * @description When the role starts to count (ISO 8601). Copied onto the assignment the invitation grants; needs a role.
3563
+ */
3564
+ effective_from?: string;
3565
+ /**
3566
+ * Format: date-time
3567
+ * @description When the role stops counting (ISO 8601), after `effective_from`. Copied onto the assignment; an invitation whose window has ended by acceptance is refused with `400 invite.window_ended`.
3568
+ */
3569
+ effective_to?: string;
3264
3570
  first_name?: string;
3265
3571
  last_name?: string;
3266
3572
  /**
@@ -3269,7 +3575,7 @@ interface components {
3269
3575
  */
3270
3576
  send_email: boolean;
3271
3577
  };
3272
- RoleResponseDto: {
3578
+ OrganizationRoleResponseDto: {
3273
3579
  id: string;
3274
3580
  application_id: string;
3275
3581
  name: string;
@@ -3287,6 +3593,8 @@ interface components {
3287
3593
  permission_count?: number;
3288
3594
  /** @description Number of distinct identities assigned this role. Populated on list responses; omitted on single-role responses where the join isn't computed. */
3289
3595
  member_count?: number;
3596
+ /** @description Whether the caller may grant this role at the organization node under the grant ceiling: for an identity, it holds every permission the role carries there; always true for the developer's key and Console users */
3597
+ grantable: boolean;
3290
3598
  };
3291
3599
  SsoConnectionTestSummaryDto: {
3292
3600
  test_id: string;
@@ -3596,11 +3904,6 @@ interface components {
3596
3904
  effective_from?: string;
3597
3905
  effective_to?: string;
3598
3906
  };
3599
- UpdateAssignmentDto: {
3600
- role_id: string;
3601
- effective_from?: string | null;
3602
- effective_to?: string | null;
3603
- };
3604
3907
  BulkRemoveAssignmentsDto: {
3605
3908
  assignment_ids: string[];
3606
3909
  };
@@ -5041,16 +5344,21 @@ interface components {
5041
5344
  * @description The identity that joined.
5042
5345
  */
5043
5346
  identity_id: string;
5347
+ /** @description Your own identifier for the organization, when you set one. */
5348
+ external_id?: string | null;
5044
5349
  /**
5045
5350
  * Format: uuid
5046
- * @description The role it holds in the organization.
5351
+ * @description The membership record.
5047
5352
  */
5048
- role_id: string;
5049
- /** @description Your own identifier for the organization, when you set one. */
5050
- external_id?: string | null;
5353
+ membership_id?: string;
5051
5354
  /**
5052
5355
  * Format: uuid
5053
- * @description The role assignment that is the membership.
5356
+ * @description The role given at the organization node on joining, when one was.
5357
+ */
5358
+ role_id?: string;
5359
+ /**
5360
+ * Format: uuid
5361
+ * @description That role's assignment, when a role was given.
5054
5362
  */
5055
5363
  assignment_id?: string;
5056
5364
  /**
@@ -5072,7 +5380,7 @@ interface components {
5072
5380
  * @description How the member joined, when it was not added directly.
5073
5381
  * @enum {string}
5074
5382
  */
5075
- source?: "sso_jit" | "invite" | "scim";
5383
+ source?: "sso_jit" | "invite" | "scim" | "self_signup";
5076
5384
  };
5077
5385
  };
5078
5386
  };
@@ -5129,13 +5437,13 @@ interface components {
5129
5437
  * @description The identity removed.
5130
5438
  */
5131
5439
  identity_id: string;
5440
+ /** @description Role assignments it held at the organization's nodes, removed with the membership. */
5441
+ assignments_removed: number;
5132
5442
  /**
5133
5443
  * Format: uuid
5134
- * @description The role it held.
5444
+ * @description The membership record, now deactivated.
5135
5445
  */
5136
- role_id: string;
5137
- /** @description Grants it held beneath the organization, removed with the membership. */
5138
- scoped_assignments_removed: number;
5446
+ membership_id?: string;
5139
5447
  /**
5140
5448
  * @description Set when directory sync made the change rather than somebody directly.
5141
5449
  * @enum {string}
@@ -5583,8 +5891,7 @@ interface operations {
5583
5891
  ApiPermissionsController_deletePermission: {
5584
5892
  parameters: {
5585
5893
  query?: never;
5586
- header: {
5587
- "if-match": string;
5894
+ header?: {
5588
5895
  /** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
5589
5896
  "If-Match"?: string;
5590
5897
  };
@@ -5712,8 +6019,7 @@ interface operations {
5712
6019
  ApiPermissionsController_updatePermission: {
5713
6020
  parameters: {
5714
6021
  query?: never;
5715
- header: {
5716
- "if-match": string;
6022
+ header?: {
5717
6023
  /** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
5718
6024
  "If-Match"?: string;
5719
6025
  };
@@ -8863,7 +9169,7 @@ interface operations {
8863
9169
  };
8864
9170
  };
8865
9171
  };
8866
- /** @description The request failed validation; `role_id` and `node_id` were not given together; a `password_reset` invite carries a role assignment or names an email with no identity; or `client_id` names no active OAuth client in this Environment, or one with no invite redirect URL; or the request sent both an `X-API-Key` and an `Authorization` header */
9172
+ /** @description The request failed validation; `role_id` came with no `node_id`, or a `node_id` with no `role_id` outside an organization node (`invite.malformed_assignment`); dates came with no role (`invite.window_requires_role`), end before they start, or have already ended (`invite.window_ended`); a `password_reset` invite carries a role assignment or names an email with no identity; or `client_id` names no active OAuth client in this Environment, or one with no invite redirect URL; or the request sent both an `X-API-Key` and an `Authorization` header */
8867
9173
  400: {
8868
9174
  headers: {
8869
9175
  [name: string]: unknown;
@@ -8874,7 +9180,7 @@ interface operations {
8874
9180
  * "error": {
8875
9181
  * "statusCode": 400,
8876
9182
  * "code": null,
8877
- * "message": "The request failed validation; `role_id` and `node_id` were not given together; a `password_reset` invite carries a role assignment or names an email with no identity; or `client_id` names no active OAuth client in this Environment, or one with no invite redirect URL; or the request sent both an `X-API-Key` and an `Authorization` header",
9183
+ * "message": "The request failed validation; `role_id` came with no `node_id`, or a `node_id` with no `role_id` outside an organization node (`invite.malformed_assignment`); dates came with no role (`invite.window_requires_role`), end before they start, or have already ended (`invite.window_ended`); a `password_reset` invite carries a role assignment or names an email with no identity; or `client_id` names no active OAuth client in this Environment, or one with no invite redirect URL; or the request sent both an `X-API-Key` and an `Authorization` header",
8878
9184
  * "timestamp": "2026-04-20T12:00:00.000Z",
8879
9185
  * "path": "/api/v1/identity-invites",
8880
9186
  * "method": "POST"
@@ -8926,7 +9232,7 @@ interface operations {
8926
9232
  "application/json": components["schemas"]["ErrorResponseDto"];
8927
9233
  };
8928
9234
  };
8929
- /** @description A pending invite already exists for this email at this scope, the identity already has access to this Environment, or the node sits inside an organization the identity is not a member of */
9235
+ /** @description A pending invite already exists for this email at this scope, the identity already has access to this Environment and the invitation joins no organization (`invite.identity_already_in_app`), or the identity is already an active member of the organization it joins (`organization.member_exists`) */
8930
9236
  409: {
8931
9237
  headers: {
8932
9238
  [name: string]: unknown;
@@ -8937,7 +9243,7 @@ interface operations {
8937
9243
  * "error": {
8938
9244
  * "statusCode": 409,
8939
9245
  * "code": null,
8940
- * "message": "A pending invite already exists for this email at this scope, the identity already has access to this Environment, or the node sits inside an organization the identity is not a member of",
9246
+ * "message": "A pending invite already exists for this email at this scope, the identity already has access to this Environment and the invitation joins no organization (`invite.identity_already_in_app`), or the identity is already an active member of the organization it joins (`organization.member_exists`)",
8941
9247
  * "timestamp": "2026-04-20T12:00:00.000Z",
8942
9248
  * "path": "/api/v1/identity-invites",
8943
9249
  * "method": "POST"
@@ -9843,8 +10149,7 @@ interface operations {
9843
10149
  ApiNodesController_deleteNode: {
9844
10150
  parameters: {
9845
10151
  query?: never;
9846
- header: {
9847
- "if-match": string;
10152
+ header?: {
9848
10153
  /** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
9849
10154
  "If-Match"?: string;
9850
10155
  };
@@ -9972,8 +10277,7 @@ interface operations {
9972
10277
  ApiNodesController_updateNode: {
9973
10278
  parameters: {
9974
10279
  query?: never;
9975
- header: {
9976
- "if-match": string;
10280
+ header?: {
9977
10281
  /** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
9978
10282
  "If-Match"?: string;
9979
10283
  };
@@ -10394,8 +10698,7 @@ interface operations {
10394
10698
  ApiNodesController_moveNode: {
10395
10699
  parameters: {
10396
10700
  query?: never;
10397
- header: {
10398
- "if-match": string;
10701
+ header?: {
10399
10702
  /** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
10400
10703
  "If-Match"?: string;
10401
10704
  };
@@ -10642,12 +10945,1075 @@ interface operations {
10642
10945
  /**
10643
10946
  * @example {
10644
10947
  * "error": {
10645
- * "statusCode": 404,
10948
+ * "statusCode": 404,
10949
+ * "code": null,
10950
+ * "message": "Node not found",
10951
+ * "timestamp": "2026-04-20T12:00:00.000Z",
10952
+ * "path": "/api/v1/nodes/{id}/identities",
10953
+ * "method": "GET"
10954
+ * }
10955
+ * }
10956
+ */
10957
+ "application/json": components["schemas"]["ErrorResponseDto"];
10958
+ };
10959
+ };
10960
+ };
10961
+ };
10962
+ ApiNodesController_getIdentityAssignmentsSummary: {
10963
+ parameters: {
10964
+ query?: never;
10965
+ header?: never;
10966
+ path: {
10967
+ id: string;
10968
+ };
10969
+ cookie?: never;
10970
+ };
10971
+ requestBody?: never;
10972
+ responses: {
10973
+ /** @description Identity counts by status returned */
10974
+ 200: {
10975
+ headers: {
10976
+ [name: string]: unknown;
10977
+ };
10978
+ content: {
10979
+ "application/json": {
10980
+ data: components["schemas"]["NodeIdentitiesSummaryDto"];
10981
+ };
10982
+ };
10983
+ };
10984
+ /** @description The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header */
10985
+ 400: {
10986
+ headers: {
10987
+ [name: string]: unknown;
10988
+ };
10989
+ content: {
10990
+ /**
10991
+ * @example {
10992
+ * "error": {
10993
+ * "statusCode": 400,
10994
+ * "code": null,
10995
+ * "message": "The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header",
10996
+ * "timestamp": "2026-04-20T12:00:00.000Z",
10997
+ * "path": "/api/v1/nodes/{id}/identities/summary",
10998
+ * "method": "GET"
10999
+ * }
11000
+ * }
11001
+ */
11002
+ "application/json": components["schemas"]["ErrorResponseDto"];
11003
+ };
11004
+ };
11005
+ /** @description Invalid or expired token */
11006
+ 401: {
11007
+ headers: {
11008
+ [name: string]: unknown;
11009
+ };
11010
+ content: {
11011
+ /**
11012
+ * @example {
11013
+ * "error": {
11014
+ * "statusCode": 401,
11015
+ * "code": null,
11016
+ * "message": "Invalid or expired token",
11017
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11018
+ * "path": "/api/v1/nodes",
11019
+ * "method": "GET"
11020
+ * }
11021
+ * }
11022
+ */
11023
+ "application/json": components["schemas"]["ErrorResponseDto"];
11024
+ };
11025
+ };
11026
+ /** @description The bearer token is not an admin or platform token, or the caller lacks the permission this operation checks: a scoped API key without that scope, an admin without the Account capability that covers it, or, for a node-scoped check, a node outside this Environment */
11027
+ 403: {
11028
+ headers: {
11029
+ [name: string]: unknown;
11030
+ };
11031
+ content: {
11032
+ /**
11033
+ * @example {
11034
+ * "error": {
11035
+ * "statusCode": 403,
11036
+ * "code": null,
11037
+ * "message": "The bearer token is not an admin or platform token, or the caller lacks the permission this operation checks: a scoped API key without that scope, an admin without the Account capability that covers it, or, for a node-scoped check, a node outside this Environment",
11038
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11039
+ * "path": "/api/v1/nodes",
11040
+ * "method": "GET"
11041
+ * }
11042
+ * }
11043
+ */
11044
+ "application/json": components["schemas"]["ErrorResponseDto"];
11045
+ };
11046
+ };
11047
+ /** @description Node not found */
11048
+ 404: {
11049
+ headers: {
11050
+ [name: string]: unknown;
11051
+ };
11052
+ content: {
11053
+ /**
11054
+ * @example {
11055
+ * "error": {
11056
+ * "statusCode": 404,
11057
+ * "code": null,
11058
+ * "message": "Node not found",
11059
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11060
+ * "path": "/api/v1/nodes/{id}/identities/summary",
11061
+ * "method": "GET"
11062
+ * }
11063
+ * }
11064
+ */
11065
+ "application/json": components["schemas"]["ErrorResponseDto"];
11066
+ };
11067
+ };
11068
+ };
11069
+ };
11070
+ ApiOrganizationAccessController_me: {
11071
+ parameters: {
11072
+ query?: never;
11073
+ header?: never;
11074
+ path: {
11075
+ id: string;
11076
+ };
11077
+ cookie?: never;
11078
+ };
11079
+ requestBody?: never;
11080
+ responses: {
11081
+ /** @description The caller's authority in the organization */
11082
+ 200: {
11083
+ headers: {
11084
+ [name: string]: unknown;
11085
+ };
11086
+ content: {
11087
+ "application/json": {
11088
+ data: components["schemas"]["OrganizationMeResponseDto"];
11089
+ };
11090
+ };
11091
+ };
11092
+ /** @description The request sent both an `X-API-Key` and an `Authorization` header; send one */
11093
+ 400: {
11094
+ headers: {
11095
+ [name: string]: unknown;
11096
+ };
11097
+ content: {
11098
+ /**
11099
+ * @example {
11100
+ * "error": {
11101
+ * "statusCode": 400,
11102
+ * "code": null,
11103
+ * "message": "The request sent both an `X-API-Key` and an `Authorization` header; send one",
11104
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11105
+ * "path": "/api/v1/organizations/{id}/me",
11106
+ * "method": "GET"
11107
+ * }
11108
+ * }
11109
+ */
11110
+ "application/json": components["schemas"]["ErrorResponseDto"];
11111
+ };
11112
+ };
11113
+ /** @description Invalid or expired token */
11114
+ 401: {
11115
+ headers: {
11116
+ [name: string]: unknown;
11117
+ };
11118
+ content: {
11119
+ /**
11120
+ * @example {
11121
+ * "error": {
11122
+ * "statusCode": 401,
11123
+ * "code": null,
11124
+ * "message": "Invalid or expired token",
11125
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11126
+ * "path": "/api/v1/organizations/{id}/me",
11127
+ * "method": "GET"
11128
+ * }
11129
+ * }
11130
+ */
11131
+ "application/json": components["schemas"]["ErrorResponseDto"];
11132
+ };
11133
+ };
11134
+ /** @description The caller holds no delegated key inside the organization and no developer key over it, or the token is not an admin, API key or identity token */
11135
+ 403: {
11136
+ headers: {
11137
+ [name: string]: unknown;
11138
+ };
11139
+ content: {
11140
+ /**
11141
+ * @example {
11142
+ * "error": {
11143
+ * "statusCode": 403,
11144
+ * "code": null,
11145
+ * "message": "The caller holds no delegated key inside the organization and no developer key over it, or the token is not an admin, API key or identity token",
11146
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11147
+ * "path": "/api/v1/organizations/{id}/me",
11148
+ * "method": "GET"
11149
+ * }
11150
+ * }
11151
+ */
11152
+ "application/json": components["schemas"]["ErrorResponseDto"];
11153
+ };
11154
+ };
11155
+ /** @description Organization not found */
11156
+ 404: {
11157
+ headers: {
11158
+ [name: string]: unknown;
11159
+ };
11160
+ content: {
11161
+ /**
11162
+ * @example {
11163
+ * "error": {
11164
+ * "statusCode": 404,
11165
+ * "code": null,
11166
+ * "message": "Organization not found",
11167
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11168
+ * "path": "/api/v1/organizations/{id}/me",
11169
+ * "method": "GET"
11170
+ * }
11171
+ * }
11172
+ */
11173
+ "application/json": components["schemas"]["ErrorResponseDto"];
11174
+ };
11175
+ };
11176
+ };
11177
+ };
11178
+ ApiOrganizationAccessController_tree: {
11179
+ parameters: {
11180
+ query?: {
11181
+ /** @description Page number (1-based) */
11182
+ page?: number;
11183
+ /** @description Items per page (1-100, default 20) */
11184
+ take?: number;
11185
+ /** @description Search node names and slugs */
11186
+ q?: string;
11187
+ /** @description Sort column. Defaults to `created`, oldest first. */
11188
+ sort_by?: "name" | "created";
11189
+ /** @description Sort direction */
11190
+ order?: "asc" | "desc";
11191
+ };
11192
+ header?: never;
11193
+ path: {
11194
+ id: string;
11195
+ };
11196
+ cookie?: never;
11197
+ };
11198
+ requestBody?: never;
11199
+ responses: {
11200
+ /** @description Nodes returned */
11201
+ 200: {
11202
+ headers: {
11203
+ [name: string]: unknown;
11204
+ };
11205
+ content: {
11206
+ "application/json": {
11207
+ items: components["schemas"]["ScopedNodeResponseDto"][];
11208
+ pagination: components["schemas"]["PageMetaDto"];
11209
+ };
11210
+ };
11211
+ };
11212
+ /** @description The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header */
11213
+ 400: {
11214
+ headers: {
11215
+ [name: string]: unknown;
11216
+ };
11217
+ content: {
11218
+ /**
11219
+ * @example {
11220
+ * "error": {
11221
+ * "statusCode": 400,
11222
+ * "code": null,
11223
+ * "message": "The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header",
11224
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11225
+ * "path": "/api/v1/organizations/{id}/tree",
11226
+ * "method": "GET"
11227
+ * }
11228
+ * }
11229
+ */
11230
+ "application/json": components["schemas"]["ErrorResponseDto"];
11231
+ };
11232
+ };
11233
+ /** @description Invalid or expired token */
11234
+ 401: {
11235
+ headers: {
11236
+ [name: string]: unknown;
11237
+ };
11238
+ content: {
11239
+ /**
11240
+ * @example {
11241
+ * "error": {
11242
+ * "statusCode": 401,
11243
+ * "code": null,
11244
+ * "message": "Invalid or expired token",
11245
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11246
+ * "path": "/api/v1/organizations/{id}/me",
11247
+ * "method": "GET"
11248
+ * }
11249
+ * }
11250
+ */
11251
+ "application/json": components["schemas"]["ErrorResponseDto"];
11252
+ };
11253
+ };
11254
+ /** @description The caller holds no delegated key inside the organization and no developer key over it, or the token is not an admin, API key or identity token */
11255
+ 403: {
11256
+ headers: {
11257
+ [name: string]: unknown;
11258
+ };
11259
+ content: {
11260
+ /**
11261
+ * @example {
11262
+ * "error": {
11263
+ * "statusCode": 403,
11264
+ * "code": null,
11265
+ * "message": "The caller holds no delegated key inside the organization and no developer key over it, or the token is not an admin, API key or identity token",
11266
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11267
+ * "path": "/api/v1/organizations/{id}/tree",
11268
+ * "method": "GET"
11269
+ * }
11270
+ * }
11271
+ */
11272
+ "application/json": components["schemas"]["ErrorResponseDto"];
11273
+ };
11274
+ };
11275
+ /** @description Organization not found */
11276
+ 404: {
11277
+ headers: {
11278
+ [name: string]: unknown;
11279
+ };
11280
+ content: {
11281
+ /**
11282
+ * @example {
11283
+ * "error": {
11284
+ * "statusCode": 404,
11285
+ * "code": null,
11286
+ * "message": "Organization not found",
11287
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11288
+ * "path": "/api/v1/organizations/{id}/tree",
11289
+ * "method": "GET"
11290
+ * }
11291
+ * }
11292
+ */
11293
+ "application/json": components["schemas"]["ErrorResponseDto"];
11294
+ };
11295
+ };
11296
+ };
11297
+ };
11298
+ ApiOrganizationAccessController_listAccess: {
11299
+ parameters: {
11300
+ query?: {
11301
+ /** @description Page number (1-based) */
11302
+ page?: number;
11303
+ /** @description Items per page (1-100, default 20) */
11304
+ take?: number;
11305
+ /** @description Search term */
11306
+ q?: string;
11307
+ /** @description Sort field */
11308
+ sort_by?: "name" | "role" | "access_type" | "created_at";
11309
+ /** @description Sort order */
11310
+ order?: "asc" | "desc";
11311
+ /** @description Filter by role ID */
11312
+ role_id?: string;
11313
+ /** @description Filter by access type */
11314
+ access_type?: "direct" | "inherited";
11315
+ /** @description Filter by assignment status */
11316
+ status?: "active" | "scheduled" | "expired";
11317
+ /** @description Filter by source node ID */
11318
+ source_node_id?: string;
11319
+ };
11320
+ header?: never;
11321
+ path: {
11322
+ id: string;
11323
+ nodeId: string;
11324
+ };
11325
+ cookie?: never;
11326
+ };
11327
+ requestBody?: never;
11328
+ responses: {
11329
+ /** @description Assignments returned */
11330
+ 200: {
11331
+ headers: {
11332
+ [name: string]: unknown;
11333
+ };
11334
+ content: {
11335
+ "application/json": {
11336
+ items: components["schemas"]["IdentityAssignmentRowDto"][];
11337
+ pagination: components["schemas"]["PageMetaDto"];
11338
+ };
11339
+ };
11340
+ };
11341
+ /** @description The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header */
11342
+ 400: {
11343
+ headers: {
11344
+ [name: string]: unknown;
11345
+ };
11346
+ content: {
11347
+ /**
11348
+ * @example {
11349
+ * "error": {
11350
+ * "statusCode": 400,
11351
+ * "code": null,
11352
+ * "message": "The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header",
11353
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11354
+ * "path": "/api/v1/organizations/{id}/nodes/{nodeId}/access",
11355
+ * "method": "GET"
11356
+ * }
11357
+ * }
11358
+ */
11359
+ "application/json": components["schemas"]["ErrorResponseDto"];
11360
+ };
11361
+ };
11362
+ /** @description Invalid or expired token */
11363
+ 401: {
11364
+ headers: {
11365
+ [name: string]: unknown;
11366
+ };
11367
+ content: {
11368
+ /**
11369
+ * @example {
11370
+ * "error": {
11371
+ * "statusCode": 401,
11372
+ * "code": null,
11373
+ * "message": "Invalid or expired token",
11374
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11375
+ * "path": "/api/v1/organizations/{id}/me",
11376
+ * "method": "GET"
11377
+ * }
11378
+ * }
11379
+ */
11380
+ "application/json": components["schemas"]["ErrorResponseDto"];
11381
+ };
11382
+ };
11383
+ /** @description This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa) */
11384
+ 403: {
11385
+ headers: {
11386
+ [name: string]: unknown;
11387
+ };
11388
+ content: {
11389
+ /**
11390
+ * @example {
11391
+ * "error": {
11392
+ * "statusCode": 403,
11393
+ * "code": null,
11394
+ * "message": "This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa)",
11395
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11396
+ * "path": "/api/v1/organizations/{id}/nodes/{nodeId}/access",
11397
+ * "method": "GET"
11398
+ * }
11399
+ * }
11400
+ */
11401
+ "application/json": components["schemas"]["ErrorResponseDto"];
11402
+ };
11403
+ };
11404
+ /** @description The organization is not in this Environment, or the node is not inside it */
11405
+ 404: {
11406
+ headers: {
11407
+ [name: string]: unknown;
11408
+ };
11409
+ content: {
11410
+ /**
11411
+ * @example {
11412
+ * "error": {
11413
+ * "statusCode": 404,
11414
+ * "code": null,
11415
+ * "message": "The organization is not in this Environment, or the node is not inside it",
11416
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11417
+ * "path": "/api/v1/organizations/{id}/nodes/{nodeId}/access",
11418
+ * "method": "GET"
11419
+ * }
11420
+ * }
11421
+ */
11422
+ "application/json": components["schemas"]["ErrorResponseDto"];
11423
+ };
11424
+ };
11425
+ };
11426
+ };
11427
+ ApiOrganizationAccessController_accessSummary: {
11428
+ parameters: {
11429
+ query?: never;
11430
+ header?: never;
11431
+ path: {
11432
+ id: string;
11433
+ nodeId: string;
11434
+ };
11435
+ cookie?: never;
11436
+ };
11437
+ requestBody?: never;
11438
+ responses: {
11439
+ /** @description Summary returned */
11440
+ 200: {
11441
+ headers: {
11442
+ [name: string]: unknown;
11443
+ };
11444
+ content: {
11445
+ "application/json": {
11446
+ data: components["schemas"]["NodeIdentitiesSummaryDto"];
11447
+ };
11448
+ };
11449
+ };
11450
+ /** @description The request sent both an `X-API-Key` and an `Authorization` header; send one */
11451
+ 400: {
11452
+ headers: {
11453
+ [name: string]: unknown;
11454
+ };
11455
+ content: {
11456
+ /**
11457
+ * @example {
11458
+ * "error": {
11459
+ * "statusCode": 400,
11460
+ * "code": null,
11461
+ * "message": "The request sent both an `X-API-Key` and an `Authorization` header; send one",
11462
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11463
+ * "path": "/api/v1/organizations/{id}/me",
11464
+ * "method": "GET"
11465
+ * }
11466
+ * }
11467
+ */
11468
+ "application/json": components["schemas"]["ErrorResponseDto"];
11469
+ };
11470
+ };
11471
+ /** @description Invalid or expired token */
11472
+ 401: {
11473
+ headers: {
11474
+ [name: string]: unknown;
11475
+ };
11476
+ content: {
11477
+ /**
11478
+ * @example {
11479
+ * "error": {
11480
+ * "statusCode": 401,
11481
+ * "code": null,
11482
+ * "message": "Invalid or expired token",
11483
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11484
+ * "path": "/api/v1/organizations/{id}/me",
11485
+ * "method": "GET"
11486
+ * }
11487
+ * }
11488
+ */
11489
+ "application/json": components["schemas"]["ErrorResponseDto"];
11490
+ };
11491
+ };
11492
+ /** @description This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa) */
11493
+ 403: {
11494
+ headers: {
11495
+ [name: string]: unknown;
11496
+ };
11497
+ content: {
11498
+ /**
11499
+ * @example {
11500
+ * "error": {
11501
+ * "statusCode": 403,
11502
+ * "code": null,
11503
+ * "message": "This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa)",
11504
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11505
+ * "path": "/api/v1/organizations/{id}/nodes/{nodeId}/access",
11506
+ * "method": "GET"
11507
+ * }
11508
+ * }
11509
+ */
11510
+ "application/json": components["schemas"]["ErrorResponseDto"];
11511
+ };
11512
+ };
11513
+ /** @description The organization is not in this Environment, or the node is not inside it */
11514
+ 404: {
11515
+ headers: {
11516
+ [name: string]: unknown;
11517
+ };
11518
+ content: {
11519
+ /**
11520
+ * @example {
11521
+ * "error": {
11522
+ * "statusCode": 404,
11523
+ * "code": null,
11524
+ * "message": "The organization is not in this Environment, or the node is not inside it",
11525
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11526
+ * "path": "/api/v1/organizations/{id}/nodes/{nodeId}/access/summary",
11527
+ * "method": "GET"
11528
+ * }
11529
+ * }
11530
+ */
11531
+ "application/json": components["schemas"]["ErrorResponseDto"];
11532
+ };
11533
+ };
11534
+ };
11535
+ };
11536
+ ApiOrganizationAccessController_grantableRoles: {
11537
+ parameters: {
11538
+ query?: never;
11539
+ header?: never;
11540
+ path: {
11541
+ id: string;
11542
+ nodeId: string;
11543
+ };
11544
+ cookie?: never;
11545
+ };
11546
+ requestBody?: never;
11547
+ responses: {
11548
+ /** @description Roles returned */
11549
+ 200: {
11550
+ headers: {
11551
+ [name: string]: unknown;
11552
+ };
11553
+ content: {
11554
+ "application/json": {
11555
+ items: components["schemas"]["RoleResponseDto"][];
11556
+ };
11557
+ };
11558
+ };
11559
+ /** @description The request sent both an `X-API-Key` and an `Authorization` header; send one */
11560
+ 400: {
11561
+ headers: {
11562
+ [name: string]: unknown;
11563
+ };
11564
+ content: {
11565
+ /**
11566
+ * @example {
11567
+ * "error": {
11568
+ * "statusCode": 400,
11569
+ * "code": null,
11570
+ * "message": "The request sent both an `X-API-Key` and an `Authorization` header; send one",
11571
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11572
+ * "path": "/api/v1/organizations/{id}/me",
11573
+ * "method": "GET"
11574
+ * }
11575
+ * }
11576
+ */
11577
+ "application/json": components["schemas"]["ErrorResponseDto"];
11578
+ };
11579
+ };
11580
+ /** @description Invalid or expired token */
11581
+ 401: {
11582
+ headers: {
11583
+ [name: string]: unknown;
11584
+ };
11585
+ content: {
11586
+ /**
11587
+ * @example {
11588
+ * "error": {
11589
+ * "statusCode": 401,
11590
+ * "code": null,
11591
+ * "message": "Invalid or expired token",
11592
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11593
+ * "path": "/api/v1/organizations/{id}/me",
11594
+ * "method": "GET"
11595
+ * }
11596
+ * }
11597
+ */
11598
+ "application/json": components["schemas"]["ErrorResponseDto"];
11599
+ };
11600
+ };
11601
+ /** @description This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa) */
11602
+ 403: {
11603
+ headers: {
11604
+ [name: string]: unknown;
11605
+ };
11606
+ content: {
11607
+ /**
11608
+ * @example {
11609
+ * "error": {
11610
+ * "statusCode": 403,
11611
+ * "code": null,
11612
+ * "message": "This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa)",
11613
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11614
+ * "path": "/api/v1/organizations/{id}/nodes/{nodeId}/access",
11615
+ * "method": "GET"
11616
+ * }
11617
+ * }
11618
+ */
11619
+ "application/json": components["schemas"]["ErrorResponseDto"];
11620
+ };
11621
+ };
11622
+ /** @description The organization is not in this Environment, or the node is not inside it */
11623
+ 404: {
11624
+ headers: {
11625
+ [name: string]: unknown;
11626
+ };
11627
+ content: {
11628
+ /**
11629
+ * @example {
11630
+ * "error": {
11631
+ * "statusCode": 404,
11632
+ * "code": null,
11633
+ * "message": "The organization is not in this Environment, or the node is not inside it",
11634
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11635
+ * "path": "/api/v1/organizations/{id}/nodes/{nodeId}/grantable-roles",
11636
+ * "method": "GET"
11637
+ * }
11638
+ * }
11639
+ */
11640
+ "application/json": components["schemas"]["ErrorResponseDto"];
11641
+ };
11642
+ };
11643
+ };
11644
+ };
11645
+ ApiOrganizationAccessController_listMembersAt: {
11646
+ parameters: {
11647
+ query?: {
11648
+ /** @description Page number (1-based) */
11649
+ page?: number;
11650
+ /** @description Items per page (1-100, default 20) */
11651
+ take?: number;
11652
+ /** @description Search member names and emails */
11653
+ q?: string;
11654
+ /** @description Sort column. Defaults to `joined`, longest-standing member first. */
11655
+ sort_by?: "name" | "email" | "joined";
11656
+ /** @description Sort direction */
11657
+ order?: "asc" | "desc";
11658
+ };
11659
+ header?: never;
11660
+ path: {
11661
+ id: string;
11662
+ nodeId: string;
11663
+ };
11664
+ cookie?: never;
11665
+ };
11666
+ requestBody?: never;
11667
+ responses: {
11668
+ /** @description Members returned */
11669
+ 200: {
11670
+ headers: {
11671
+ [name: string]: unknown;
11672
+ };
11673
+ content: {
11674
+ "application/json": {
11675
+ items: components["schemas"]["OrganizationMemberCandidateResponseDto"][];
11676
+ pagination: components["schemas"]["PageMetaDto"];
11677
+ };
11678
+ };
11679
+ };
11680
+ /** @description The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header */
11681
+ 400: {
11682
+ headers: {
11683
+ [name: string]: unknown;
11684
+ };
11685
+ content: {
11686
+ /**
11687
+ * @example {
11688
+ * "error": {
11689
+ * "statusCode": 400,
11690
+ * "code": null,
11691
+ * "message": "The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header",
11692
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11693
+ * "path": "/api/v1/organizations/{id}/nodes/{nodeId}/members",
11694
+ * "method": "GET"
11695
+ * }
11696
+ * }
11697
+ */
11698
+ "application/json": components["schemas"]["ErrorResponseDto"];
11699
+ };
11700
+ };
11701
+ /** @description Invalid or expired token */
11702
+ 401: {
11703
+ headers: {
11704
+ [name: string]: unknown;
11705
+ };
11706
+ content: {
11707
+ /**
11708
+ * @example {
11709
+ * "error": {
11710
+ * "statusCode": 401,
11711
+ * "code": null,
11712
+ * "message": "Invalid or expired token",
11713
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11714
+ * "path": "/api/v1/organizations/{id}/me",
11715
+ * "method": "GET"
11716
+ * }
11717
+ * }
11718
+ */
11719
+ "application/json": components["schemas"]["ErrorResponseDto"];
11720
+ };
11721
+ };
11722
+ /** @description This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa) */
11723
+ 403: {
11724
+ headers: {
11725
+ [name: string]: unknown;
11726
+ };
11727
+ content: {
11728
+ /**
11729
+ * @example {
11730
+ * "error": {
11731
+ * "statusCode": 403,
11732
+ * "code": null,
11733
+ * "message": "This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa)",
11734
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11735
+ * "path": "/api/v1/organizations/{id}/nodes/{nodeId}/access",
11736
+ * "method": "GET"
11737
+ * }
11738
+ * }
11739
+ */
11740
+ "application/json": components["schemas"]["ErrorResponseDto"];
11741
+ };
11742
+ };
11743
+ /** @description The organization is not in this Environment, or the node is not inside it */
11744
+ 404: {
11745
+ headers: {
11746
+ [name: string]: unknown;
11747
+ };
11748
+ content: {
11749
+ /**
11750
+ * @example {
11751
+ * "error": {
11752
+ * "statusCode": 404,
11753
+ * "code": null,
11754
+ * "message": "The organization is not in this Environment, or the node is not inside it",
11755
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11756
+ * "path": "/api/v1/organizations/{id}/nodes/{nodeId}/members",
11757
+ * "method": "GET"
11758
+ * }
11759
+ * }
11760
+ */
11761
+ "application/json": components["schemas"]["ErrorResponseDto"];
11762
+ };
11763
+ };
11764
+ };
11765
+ };
11766
+ ApiOrganizationAccessController_createAssignment: {
11767
+ parameters: {
11768
+ query?: never;
11769
+ header?: never;
11770
+ path: {
11771
+ id: string;
11772
+ };
11773
+ cookie?: never;
11774
+ };
11775
+ requestBody: {
11776
+ content: {
11777
+ "application/json": components["schemas"]["CreateOrganizationAssignmentDto"];
11778
+ };
11779
+ };
11780
+ responses: {
11781
+ /** @description Assignment created */
11782
+ 201: {
11783
+ headers: {
11784
+ [name: string]: unknown;
11785
+ };
11786
+ content: {
11787
+ "application/json": {
11788
+ data: components["schemas"]["AssignmentResponseDto"];
11789
+ };
11790
+ };
11791
+ };
11792
+ /** @description The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header */
11793
+ 400: {
11794
+ headers: {
11795
+ [name: string]: unknown;
11796
+ };
11797
+ content: {
11798
+ /**
11799
+ * @example {
11800
+ * "error": {
11801
+ * "statusCode": 400,
11802
+ * "code": null,
11803
+ * "message": "The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header",
11804
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11805
+ * "path": "/api/v1/organizations/{id}/assignments",
11806
+ * "method": "POST"
11807
+ * }
11808
+ * }
11809
+ */
11810
+ "application/json": components["schemas"]["ErrorResponseDto"];
11811
+ };
11812
+ };
11813
+ /** @description Invalid or expired token */
11814
+ 401: {
11815
+ headers: {
11816
+ [name: string]: unknown;
11817
+ };
11818
+ content: {
11819
+ /**
11820
+ * @example {
11821
+ * "error": {
11822
+ * "statusCode": 401,
11823
+ * "code": null,
11824
+ * "message": "Invalid or expired token",
11825
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11826
+ * "path": "/api/v1/organizations/{id}/me",
11827
+ * "method": "GET"
11828
+ * }
11829
+ * }
11830
+ */
11831
+ "application/json": components["schemas"]["ErrorResponseDto"];
11832
+ };
11833
+ };
11834
+ /** @description The token is not an admin, API key or identity token, or the caller holds none of the keys the operation needs at the node, or is an identity outside the grant ceiling for the role (`assignment.grant_ceiling`) */
11835
+ 403: {
11836
+ headers: {
11837
+ [name: string]: unknown;
11838
+ };
11839
+ content: {
11840
+ /**
11841
+ * @example {
11842
+ * "error": {
11843
+ * "statusCode": 403,
11844
+ * "code": null,
11845
+ * "message": "The token is not an admin, API key or identity token, or the caller holds none of the keys the operation needs at the node, or is an identity outside the grant ceiling for the role (`assignment.grant_ceiling`)",
11846
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11847
+ * "path": "/api/v1/organizations/{id}/assignments",
11848
+ * "method": "POST"
11849
+ * }
11850
+ * }
11851
+ */
11852
+ "application/json": components["schemas"]["ErrorResponseDto"];
11853
+ };
11854
+ };
11855
+ /** @description The organization is not in this Environment, or the node is not inside it */
11856
+ 404: {
11857
+ headers: {
11858
+ [name: string]: unknown;
11859
+ };
11860
+ content: {
11861
+ /**
11862
+ * @example {
11863
+ * "error": {
11864
+ * "statusCode": 404,
11865
+ * "code": null,
11866
+ * "message": "The organization is not in this Environment, or the node is not inside it",
11867
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11868
+ * "path": "/api/v1/organizations/{id}/assignments",
11869
+ * "method": "POST"
11870
+ * }
11871
+ * }
11872
+ */
11873
+ "application/json": components["schemas"]["ErrorResponseDto"];
11874
+ };
11875
+ };
11876
+ /** @description The identity already holds this role at this node, or is not a member of the organization (`organization.membership_required`) */
11877
+ 409: {
11878
+ headers: {
11879
+ [name: string]: unknown;
11880
+ };
11881
+ content: {
11882
+ /**
11883
+ * @example {
11884
+ * "error": {
11885
+ * "statusCode": 409,
11886
+ * "code": null,
11887
+ * "message": "The identity already holds this role at this node, or is not a member of the organization (`organization.membership_required`)",
11888
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11889
+ * "path": "/api/v1/organizations/{id}/assignments",
11890
+ * "method": "POST"
11891
+ * }
11892
+ * }
11893
+ */
11894
+ "application/json": components["schemas"]["ErrorResponseDto"];
11895
+ };
11896
+ };
11897
+ };
11898
+ };
11899
+ ApiOrganizationAccessController_removeAssignment: {
11900
+ parameters: {
11901
+ query?: never;
11902
+ header?: never;
11903
+ path: {
11904
+ id: string;
11905
+ assignmentId: string;
11906
+ };
11907
+ cookie?: never;
11908
+ };
11909
+ requestBody?: never;
11910
+ responses: {
11911
+ /** @description Assignment removed */
11912
+ 204: {
11913
+ headers: {
11914
+ [name: string]: unknown;
11915
+ };
11916
+ content?: never;
11917
+ };
11918
+ /** @description The request sent both an `X-API-Key` and an `Authorization` header; send one */
11919
+ 400: {
11920
+ headers: {
11921
+ [name: string]: unknown;
11922
+ };
11923
+ content: {
11924
+ /**
11925
+ * @example {
11926
+ * "error": {
11927
+ * "statusCode": 400,
11928
+ * "code": null,
11929
+ * "message": "The request sent both an `X-API-Key` and an `Authorization` header; send one",
11930
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11931
+ * "path": "/api/v1/organizations/{id}/me",
11932
+ * "method": "GET"
11933
+ * }
11934
+ * }
11935
+ */
11936
+ "application/json": components["schemas"]["ErrorResponseDto"];
11937
+ };
11938
+ };
11939
+ /** @description Invalid or expired token */
11940
+ 401: {
11941
+ headers: {
11942
+ [name: string]: unknown;
11943
+ };
11944
+ content: {
11945
+ /**
11946
+ * @example {
11947
+ * "error": {
11948
+ * "statusCode": 401,
11949
+ * "code": null,
11950
+ * "message": "Invalid or expired token",
11951
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11952
+ * "path": "/api/v1/organizations/{id}/me",
11953
+ * "method": "GET"
11954
+ * }
11955
+ * }
11956
+ */
11957
+ "application/json": components["schemas"]["ErrorResponseDto"];
11958
+ };
11959
+ };
11960
+ /** @description The token is not an admin, API key or identity token, or the caller holds none of the keys the operation needs at the node */
11961
+ 403: {
11962
+ headers: {
11963
+ [name: string]: unknown;
11964
+ };
11965
+ content: {
11966
+ /**
11967
+ * @example {
11968
+ * "error": {
11969
+ * "statusCode": 403,
11970
+ * "code": null,
11971
+ * "message": "The token is not an admin, API key or identity token, or the caller holds none of the keys the operation needs at the node",
11972
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11973
+ * "path": "/api/v1/organizations/{id}/assignments/{assignmentId}",
11974
+ * "method": "DELETE"
11975
+ * }
11976
+ * }
11977
+ */
11978
+ "application/json": components["schemas"]["ErrorResponseDto"];
11979
+ };
11980
+ };
11981
+ /** @description The organization is not in this Environment, or the assignment is not at one of its nodes */
11982
+ 404: {
11983
+ headers: {
11984
+ [name: string]: unknown;
11985
+ };
11986
+ content: {
11987
+ /**
11988
+ * @example {
11989
+ * "error": {
11990
+ * "statusCode": 404,
11991
+ * "code": null,
11992
+ * "message": "The organization is not in this Environment, or the assignment is not at one of its nodes",
11993
+ * "timestamp": "2026-04-20T12:00:00.000Z",
11994
+ * "path": "/api/v1/organizations/{id}/assignments/{assignmentId}",
11995
+ * "method": "DELETE"
11996
+ * }
11997
+ * }
11998
+ */
11999
+ "application/json": components["schemas"]["ErrorResponseDto"];
12000
+ };
12001
+ };
12002
+ /** @description The member is the organization's last administrator (`organization.last_admin`); make someone else one first */
12003
+ 409: {
12004
+ headers: {
12005
+ [name: string]: unknown;
12006
+ };
12007
+ content: {
12008
+ /**
12009
+ * @example {
12010
+ * "error": {
12011
+ * "statusCode": 409,
10646
12012
  * "code": null,
10647
- * "message": "Node not found",
12013
+ * "message": "The member is the organization's last administrator (`organization.last_admin`); make someone else one first",
10648
12014
  * "timestamp": "2026-04-20T12:00:00.000Z",
10649
- * "path": "/api/v1/nodes/{id}/identities",
10650
- * "method": "GET"
12015
+ * "path": "/api/v1/organizations/{id}/assignments/{assignmentId}",
12016
+ * "method": "DELETE"
10651
12017
  * }
10652
12018
  * }
10653
12019
  */
@@ -10656,25 +12022,33 @@ interface operations {
10656
12022
  };
10657
12023
  };
10658
12024
  };
10659
- ApiNodesController_getIdentityAssignmentsSummary: {
12025
+ ApiOrganizationAccessController_updateAssignment: {
10660
12026
  parameters: {
10661
12027
  query?: never;
10662
- header?: never;
12028
+ header?: {
12029
+ /** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
12030
+ "If-Match"?: string;
12031
+ };
10663
12032
  path: {
10664
12033
  id: string;
12034
+ assignmentId: string;
10665
12035
  };
10666
12036
  cookie?: never;
10667
12037
  };
10668
- requestBody?: never;
12038
+ requestBody: {
12039
+ content: {
12040
+ "application/json": components["schemas"]["UpdateAssignmentDto"];
12041
+ };
12042
+ };
10669
12043
  responses: {
10670
- /** @description Identity counts by status returned */
12044
+ /** @description Assignment updated */
10671
12045
  200: {
10672
12046
  headers: {
10673
12047
  [name: string]: unknown;
10674
12048
  };
10675
12049
  content: {
10676
12050
  "application/json": {
10677
- data: components["schemas"]["NodeIdentitiesSummaryDto"];
12051
+ data: components["schemas"]["AssignmentResponseDto"];
10678
12052
  };
10679
12053
  };
10680
12054
  };
@@ -10691,8 +12065,8 @@ interface operations {
10691
12065
  * "code": null,
10692
12066
  * "message": "The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header",
10693
12067
  * "timestamp": "2026-04-20T12:00:00.000Z",
10694
- * "path": "/api/v1/nodes/{id}/identities/summary",
10695
- * "method": "GET"
12068
+ * "path": "/api/v1/organizations/{id}/assignments/{assignmentId}",
12069
+ * "method": "PATCH"
10696
12070
  * }
10697
12071
  * }
10698
12072
  */
@@ -10712,7 +12086,7 @@ interface operations {
10712
12086
  * "code": null,
10713
12087
  * "message": "Invalid or expired token",
10714
12088
  * "timestamp": "2026-04-20T12:00:00.000Z",
10715
- * "path": "/api/v1/nodes",
12089
+ * "path": "/api/v1/organizations/{id}/me",
10716
12090
  * "method": "GET"
10717
12091
  * }
10718
12092
  * }
@@ -10720,7 +12094,7 @@ interface operations {
10720
12094
  "application/json": components["schemas"]["ErrorResponseDto"];
10721
12095
  };
10722
12096
  };
10723
- /** @description The bearer token is not an admin or platform token, or the caller lacks the permission this operation checks: a scoped API key without that scope, an admin without the Account capability that covers it, or, for a node-scoped check, a node outside this Environment */
12097
+ /** @description The token is not an admin, API key or identity token, or the caller holds none of the keys the operation needs at the node, or is an identity outside the grant ceiling for the role (`assignment.grant_ceiling`) */
10724
12098
  403: {
10725
12099
  headers: {
10726
12100
  [name: string]: unknown;
@@ -10731,17 +12105,17 @@ interface operations {
10731
12105
  * "error": {
10732
12106
  * "statusCode": 403,
10733
12107
  * "code": null,
10734
- * "message": "The bearer token is not an admin or platform token, or the caller lacks the permission this operation checks: a scoped API key without that scope, an admin without the Account capability that covers it, or, for a node-scoped check, a node outside this Environment",
12108
+ * "message": "The token is not an admin, API key or identity token, or the caller holds none of the keys the operation needs at the node, or is an identity outside the grant ceiling for the role (`assignment.grant_ceiling`)",
10735
12109
  * "timestamp": "2026-04-20T12:00:00.000Z",
10736
- * "path": "/api/v1/nodes",
10737
- * "method": "GET"
12110
+ * "path": "/api/v1/organizations/{id}/assignments/{assignmentId}",
12111
+ * "method": "PATCH"
10738
12112
  * }
10739
12113
  * }
10740
12114
  */
10741
12115
  "application/json": components["schemas"]["ErrorResponseDto"];
10742
12116
  };
10743
12117
  };
10744
- /** @description Node not found */
12118
+ /** @description The organization is not in this Environment, or the assignment is not at one of its nodes */
10745
12119
  404: {
10746
12120
  headers: {
10747
12121
  [name: string]: unknown;
@@ -10752,10 +12126,31 @@ interface operations {
10752
12126
  * "error": {
10753
12127
  * "statusCode": 404,
10754
12128
  * "code": null,
10755
- * "message": "Node not found",
12129
+ * "message": "The organization is not in this Environment, or the assignment is not at one of its nodes",
10756
12130
  * "timestamp": "2026-04-20T12:00:00.000Z",
10757
- * "path": "/api/v1/nodes/{id}/identities/summary",
10758
- * "method": "GET"
12131
+ * "path": "/api/v1/organizations/{id}/assignments/{assignmentId}",
12132
+ * "method": "PATCH"
12133
+ * }
12134
+ * }
12135
+ */
12136
+ "application/json": components["schemas"]["ErrorResponseDto"];
12137
+ };
12138
+ };
12139
+ /** @description The identity already holds this role at this node, the assignment has been modified since the version named in If-Match was read (`assignment.version_mismatch`), or it is the last administrator's role at the organization node (`organization.last_admin`) */
12140
+ 409: {
12141
+ headers: {
12142
+ [name: string]: unknown;
12143
+ };
12144
+ content: {
12145
+ /**
12146
+ * @example {
12147
+ * "error": {
12148
+ * "statusCode": 409,
12149
+ * "code": null,
12150
+ * "message": "The identity already holds this role at this node, the assignment has been modified since the version named in If-Match was read (`assignment.version_mismatch`), or it is the last administrator's role at the organization node (`organization.last_admin`)",
12151
+ * "timestamp": "2026-04-20T12:00:00.000Z",
12152
+ * "path": "/api/v1/organizations/{id}/assignments/{assignmentId}",
12153
+ * "method": "PATCH"
10759
12154
  * }
10760
12155
  * }
10761
12156
  */
@@ -11165,8 +12560,7 @@ interface operations {
11165
12560
  ApiOrganizationsController_deleteOrganization: {
11166
12561
  parameters: {
11167
12562
  query?: never;
11168
- header: {
11169
- "if-match": string;
12563
+ header?: {
11170
12564
  /** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
11171
12565
  "If-Match"?: string;
11172
12566
  };
@@ -11294,8 +12688,7 @@ interface operations {
11294
12688
  ApiOrganizationsController_updateOrganization: {
11295
12689
  parameters: {
11296
12690
  query?: never;
11297
- header: {
11298
- "if-match": string;
12691
+ header?: {
11299
12692
  /** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
11300
12693
  "If-Match"?: string;
11301
12694
  };
@@ -11539,8 +12932,7 @@ interface operations {
11539
12932
  ApiOrganizationsController_updatePolicy: {
11540
12933
  parameters: {
11541
12934
  query?: never;
11542
- header: {
11543
- "if-match": string;
12935
+ header?: {
11544
12936
  /** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
11545
12937
  "If-Match"?: string;
11546
12938
  };
@@ -12850,14 +14242,14 @@ interface operations {
12850
14242
  take?: number;
12851
14243
  /** @description Search member names and emails */
12852
14244
  q?: string;
12853
- /** @description Sort column. Defaults to `created`, oldest membership first. */
12854
- sort_by?: "name" | "email" | "role" | "created";
14245
+ /** @description Sort column. Defaults to `joined`, longest-standing member first. */
14246
+ sort_by?: "name" | "email" | "joined";
12855
14247
  /** @description Sort direction */
12856
14248
  order?: "asc" | "desc";
12857
- /** @description Only members holding this role */
14249
+ /** @description Only members holding this role anywhere in the organization, at its node or beneath */
12858
14250
  role_id?: string;
12859
- /** @description Filter by the membership's effective window: active now, scheduled to start, or already expired */
12860
- status?: "active" | "scheduled" | "expired";
14251
+ /** @description Which memberships to list: `active` (the default), `deactivated` for members who left, or `all` */
14252
+ status?: "active" | "deactivated" | "all";
12861
14253
  };
12862
14254
  header?: never;
12863
14255
  path: {
@@ -12991,7 +14383,7 @@ interface operations {
12991
14383
  };
12992
14384
  };
12993
14385
  };
12994
- /** @description The request failed validation, or the role is a system role, which cannot be assigned; or the request sent both an `X-API-Key` and an `Authorization` header */
14386
+ /** @description The request failed validation, the role is a system role, which cannot be assigned, a place or dates came with no role (`invite.window_requires_role`), or the dates end before they start; or the request sent both an `X-API-Key` and an `Authorization` header */
12995
14387
  400: {
12996
14388
  headers: {
12997
14389
  [name: string]: unknown;
@@ -13002,7 +14394,7 @@ interface operations {
13002
14394
  * "error": {
13003
14395
  * "statusCode": 400,
13004
14396
  * "code": null,
13005
- * "message": "The request failed validation, or the role is a system role, which cannot be assigned; or the request sent both an `X-API-Key` and an `Authorization` header",
14397
+ * "message": "The request failed validation, the role is a system role, which cannot be assigned, a place or dates came with no role (`invite.window_requires_role`), or the dates end before they start; or the request sent both an `X-API-Key` and an `Authorization` header",
13006
14398
  * "timestamp": "2026-04-20T12:00:00.000Z",
13007
14399
  * "path": "/api/v1/organizations/{id}/members",
13008
14400
  * "method": "POST"
@@ -13054,7 +14446,7 @@ interface operations {
13054
14446
  "application/json": components["schemas"]["ErrorResponseDto"];
13055
14447
  };
13056
14448
  };
13057
- /** @description The organization, the identity or the role does not exist in this Environment */
14449
+ /** @description The organization, the identity or the role does not exist in this Environment, or `node_id` is not the organization or a place beneath it */
13058
14450
  404: {
13059
14451
  headers: {
13060
14452
  [name: string]: unknown;
@@ -13065,7 +14457,7 @@ interface operations {
13065
14457
  * "error": {
13066
14458
  * "statusCode": 404,
13067
14459
  * "code": null,
13068
- * "message": "The organization, the identity or the role does not exist in this Environment",
14460
+ * "message": "The organization, the identity or the role does not exist in this Environment, or `node_id` is not the organization or a place beneath it",
13069
14461
  * "timestamp": "2026-04-20T12:00:00.000Z",
13070
14462
  * "path": "/api/v1/organizations/{id}/members",
13071
14463
  * "method": "POST"
@@ -13075,7 +14467,7 @@ interface operations {
13075
14467
  "application/json": components["schemas"]["ErrorResponseDto"];
13076
14468
  };
13077
14469
  };
13078
- /** @description The identity is already a member of this organization */
14470
+ /** @description The identity is already a member of this organization (`organization.member_exists`); give them a role through the assignment routes */
13079
14471
  409: {
13080
14472
  headers: {
13081
14473
  [name: string]: unknown;
@@ -13086,7 +14478,7 @@ interface operations {
13086
14478
  * "error": {
13087
14479
  * "statusCode": 409,
13088
14480
  * "code": null,
13089
- * "message": "The identity is already a member of this organization",
14481
+ * "message": "The identity is already a member of this organization (`organization.member_exists`); give them a role through the assignment routes",
13090
14482
  * "timestamp": "2026-04-20T12:00:00.000Z",
13091
14483
  * "path": "/api/v1/organizations/{id}/members",
13092
14484
  * "method": "POST"
@@ -13224,140 +14616,6 @@ interface operations {
13224
14616
  };
13225
14617
  };
13226
14618
  };
13227
- ApiOrganizationsController_changeMemberRole: {
13228
- parameters: {
13229
- query?: never;
13230
- header?: never;
13231
- path: {
13232
- id: string;
13233
- identityId: string;
13234
- };
13235
- cookie?: never;
13236
- };
13237
- requestBody: {
13238
- content: {
13239
- "application/json": components["schemas"]["ChangeOrganizationMemberRoleDto"];
13240
- };
13241
- };
13242
- responses: {
13243
- /** @description Member role changed */
13244
- 200: {
13245
- headers: {
13246
- [name: string]: unknown;
13247
- };
13248
- content: {
13249
- "application/json": {
13250
- data: components["schemas"]["OrganizationMemberResponseDto"];
13251
- };
13252
- };
13253
- };
13254
- /** @description The request failed validation, or the role is inactive or a system role; or the request sent both an `X-API-Key` and an `Authorization` header */
13255
- 400: {
13256
- headers: {
13257
- [name: string]: unknown;
13258
- };
13259
- content: {
13260
- /**
13261
- * @example {
13262
- * "error": {
13263
- * "statusCode": 400,
13264
- * "code": null,
13265
- * "message": "The request failed validation, or the role is inactive or a system role; or the request sent both an `X-API-Key` and an `Authorization` header",
13266
- * "timestamp": "2026-04-20T12:00:00.000Z",
13267
- * "path": "/api/v1/organizations/{id}/members/{identityId}",
13268
- * "method": "PATCH"
13269
- * }
13270
- * }
13271
- */
13272
- "application/json": components["schemas"]["ErrorResponseDto"];
13273
- };
13274
- };
13275
- /** @description Invalid or expired token */
13276
- 401: {
13277
- headers: {
13278
- [name: string]: unknown;
13279
- };
13280
- content: {
13281
- /**
13282
- * @example {
13283
- * "error": {
13284
- * "statusCode": 401,
13285
- * "code": null,
13286
- * "message": "Invalid or expired token",
13287
- * "timestamp": "2026-04-20T12:00:00.000Z",
13288
- * "path": "/api/v1/organizations",
13289
- * "method": "GET"
13290
- * }
13291
- * }
13292
- */
13293
- "application/json": components["schemas"]["ErrorResponseDto"];
13294
- };
13295
- };
13296
- /** @description This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa) */
13297
- 403: {
13298
- headers: {
13299
- [name: string]: unknown;
13300
- };
13301
- content: {
13302
- /**
13303
- * @example {
13304
- * "error": {
13305
- * "statusCode": 403,
13306
- * "code": null,
13307
- * "message": "This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa)",
13308
- * "timestamp": "2026-04-20T12:00:00.000Z",
13309
- * "path": "/api/v1/organizations",
13310
- * "method": "GET"
13311
- * }
13312
- * }
13313
- */
13314
- "application/json": components["schemas"]["ErrorResponseDto"];
13315
- };
13316
- };
13317
- /** @description The organization or the role does not exist, or the identity is not a member of this organization */
13318
- 404: {
13319
- headers: {
13320
- [name: string]: unknown;
13321
- };
13322
- content: {
13323
- /**
13324
- * @example {
13325
- * "error": {
13326
- * "statusCode": 404,
13327
- * "code": null,
13328
- * "message": "The organization or the role does not exist, or the identity is not a member of this organization",
13329
- * "timestamp": "2026-04-20T12:00:00.000Z",
13330
- * "path": "/api/v1/organizations/{id}/members/{identityId}",
13331
- * "method": "PATCH"
13332
- * }
13333
- * }
13334
- */
13335
- "application/json": components["schemas"]["ErrorResponseDto"];
13336
- };
13337
- };
13338
- /** @description The member is the organization's last administrator (`organization.last_admin`); make someone else one first */
13339
- 409: {
13340
- headers: {
13341
- [name: string]: unknown;
13342
- };
13343
- content: {
13344
- /**
13345
- * @example {
13346
- * "error": {
13347
- * "statusCode": 409,
13348
- * "code": null,
13349
- * "message": "The member is the organization's last administrator (`organization.last_admin`); make someone else one first",
13350
- * "timestamp": "2026-04-20T12:00:00.000Z",
13351
- * "path": "/api/v1/organizations/{id}/members/{identityId}",
13352
- * "method": "PATCH"
13353
- * }
13354
- * }
13355
- */
13356
- "application/json": components["schemas"]["ErrorResponseDto"];
13357
- };
13358
- };
13359
- };
13360
- };
13361
14619
  ApiOrganizationsController_resetMemberMfa: {
13362
14620
  parameters: {
13363
14621
  query?: never;
@@ -13632,7 +14890,7 @@ interface operations {
13632
14890
  };
13633
14891
  };
13634
14892
  };
13635
- /** @description The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header */
14893
+ /** @description The request failed validation; a place beneath the organization was named with no role (`invite.malformed_assignment`); dates came with no role (`invite.window_requires_role`), end before they start, or have already ended (`invite.window_ended`); or the request sent both an `X-API-Key` and an `Authorization` header */
13636
14894
  400: {
13637
14895
  headers: {
13638
14896
  [name: string]: unknown;
@@ -13643,7 +14901,7 @@ interface operations {
13643
14901
  * "error": {
13644
14902
  * "statusCode": 400,
13645
14903
  * "code": null,
13646
- * "message": "The request failed validation: a body field, a query parameter or an id in the path is missing, malformed or out of range; or the request sent both an `X-API-Key` and an `Authorization` header",
14904
+ * "message": "The request failed validation; a place beneath the organization was named with no role (`invite.malformed_assignment`); dates came with no role (`invite.window_requires_role`), end before they start, or have already ended (`invite.window_ended`); or the request sent both an `X-API-Key` and an `Authorization` header",
13647
14905
  * "timestamp": "2026-04-20T12:00:00.000Z",
13648
14906
  * "path": "/api/v1/organizations/{id}/invites",
13649
14907
  * "method": "POST"
@@ -13674,7 +14932,7 @@ interface operations {
13674
14932
  "application/json": components["schemas"]["ErrorResponseDto"];
13675
14933
  };
13676
14934
  };
13677
- /** @description This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa) */
14935
+ /** @description The token is not an admin, API key or identity token, or the caller is an identity that does not hold, at the organization node or above, every permission the role carries (`assignment.grant_ceiling`); Console users and API keys are not bounded */
13678
14936
  403: {
13679
14937
  headers: {
13680
14938
  [name: string]: unknown;
@@ -13685,17 +14943,17 @@ interface operations {
13685
14943
  * "error": {
13686
14944
  * "statusCode": 403,
13687
14945
  * "code": null,
13688
- * "message": "This token is not authorized for this endpoint (wrong principal type — e.g., admin token on identity-only endpoint, or vice versa)",
14946
+ * "message": "The token is not an admin, API key or identity token, or the caller is an identity that does not hold, at the organization node or above, every permission the role carries (`assignment.grant_ceiling`); Console users and API keys are not bounded",
13689
14947
  * "timestamp": "2026-04-20T12:00:00.000Z",
13690
- * "path": "/api/v1/organizations",
13691
- * "method": "GET"
14948
+ * "path": "/api/v1/organizations/{id}/invites",
14949
+ * "method": "POST"
13692
14950
  * }
13693
14951
  * }
13694
14952
  */
13695
14953
  "application/json": components["schemas"]["ErrorResponseDto"];
13696
14954
  };
13697
14955
  };
13698
- /** @description Organization not found */
14956
+ /** @description The organization does not exist, or `node_id` is not the organization or a place beneath it */
13699
14957
  404: {
13700
14958
  headers: {
13701
14959
  [name: string]: unknown;
@@ -13706,7 +14964,7 @@ interface operations {
13706
14964
  * "error": {
13707
14965
  * "statusCode": 404,
13708
14966
  * "code": null,
13709
- * "message": "Organization not found",
14967
+ * "message": "The organization does not exist, or `node_id` is not the organization or a place beneath it",
13710
14968
  * "timestamp": "2026-04-20T12:00:00.000Z",
13711
14969
  * "path": "/api/v1/organizations/{id}/invites",
13712
14970
  * "method": "POST"
@@ -13716,7 +14974,7 @@ interface operations {
13716
14974
  "application/json": components["schemas"]["ErrorResponseDto"];
13717
14975
  };
13718
14976
  };
13719
- /** @description A pending invitation already exists for this email, or the identity already has active access to this Environment */
14977
+ /** @description A pending invitation already exists for this email at this place, or the identity is already an active member of the organization (`organization.member_exists`); give a member a role through the assignment routes */
13720
14978
  409: {
13721
14979
  headers: {
13722
14980
  [name: string]: unknown;
@@ -13727,7 +14985,7 @@ interface operations {
13727
14985
  * "error": {
13728
14986
  * "statusCode": 409,
13729
14987
  * "code": null,
13730
- * "message": "A pending invitation already exists for this email, or the identity already has active access to this Environment",
14988
+ * "message": "A pending invitation already exists for this email at this place, or the identity is already an active member of the organization (`organization.member_exists`); give a member a role through the assignment routes",
13731
14989
  * "timestamp": "2026-04-20T12:00:00.000Z",
13732
14990
  * "path": "/api/v1/organizations/{id}/invites",
13733
14991
  * "method": "POST"
@@ -13757,7 +15015,7 @@ interface operations {
13757
15015
  };
13758
15016
  content: {
13759
15017
  "application/json": {
13760
- items: components["schemas"]["RoleResponseDto"][];
15018
+ items: components["schemas"]["OrganizationRoleResponseDto"][];
13761
15019
  };
13762
15020
  };
13763
15021
  };
@@ -17031,8 +18289,7 @@ interface operations {
17031
18289
  ApiRolesController_deleteRole: {
17032
18290
  parameters: {
17033
18291
  query?: never;
17034
- header: {
17035
- "if-match": string;
18292
+ header?: {
17036
18293
  /** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
17037
18294
  "If-Match"?: string;
17038
18295
  };
@@ -17160,8 +18417,7 @@ interface operations {
17160
18417
  ApiRolesController_updateRole: {
17161
18418
  parameters: {
17162
18419
  query?: never;
17163
- header: {
17164
- "if-match": string;
18420
+ header?: {
17165
18421
  /** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
17166
18422
  "If-Match"?: string;
17167
18423
  };
@@ -17810,7 +19066,7 @@ interface operations {
17810
19066
  "application/json": components["schemas"]["ErrorResponseDto"];
17811
19067
  };
17812
19068
  };
17813
- /** @description The identity already has this role at this node, already holds its one role at this organization, or the node sits beneath an organization the identity has no membership in effect at */
19069
+ /** @description The identity already has this role at this node, or the node sits beneath an organization the identity is not an active member of (`organization.membership_required`) */
17814
19070
  409: {
17815
19071
  headers: {
17816
19072
  [name: string]: unknown;
@@ -17821,7 +19077,7 @@ interface operations {
17821
19077
  * "error": {
17822
19078
  * "statusCode": 409,
17823
19079
  * "code": null,
17824
- * "message": "The identity already has this role at this node, already holds its one role at this organization, or the node sits beneath an organization the identity has no membership in effect at",
19080
+ * "message": "The identity already has this role at this node, or the node sits beneath an organization the identity is not an active member of (`organization.membership_required`)",
17825
19081
  * "timestamp": "2026-04-20T12:00:00.000Z",
17826
19082
  * "path": "/api/v1/assignments",
17827
19083
  * "method": "POST"
@@ -17935,12 +19191,36 @@ interface operations {
17935
19191
  "application/json": components["schemas"]["ErrorResponseDto"];
17936
19192
  };
17937
19193
  };
19194
+ /** @description The member is the organization's last administrator (`organization.last_admin`); make someone else one first */
19195
+ 409: {
19196
+ headers: {
19197
+ [name: string]: unknown;
19198
+ };
19199
+ content: {
19200
+ /**
19201
+ * @example {
19202
+ * "error": {
19203
+ * "statusCode": 409,
19204
+ * "code": null,
19205
+ * "message": "The member is the organization's last administrator (`organization.last_admin`); make someone else one first",
19206
+ * "timestamp": "2026-04-20T12:00:00.000Z",
19207
+ * "path": "/api/v1/assignments/{id}",
19208
+ * "method": "DELETE"
19209
+ * }
19210
+ * }
19211
+ */
19212
+ "application/json": components["schemas"]["ErrorResponseDto"];
19213
+ };
19214
+ };
17938
19215
  };
17939
19216
  };
17940
19217
  ApiAssignmentsController_updateAssignment: {
17941
19218
  parameters: {
17942
19219
  query?: never;
17943
- header?: never;
19220
+ header?: {
19221
+ /** @description Optimistic-lock version of the resource. Send the `version` field returned on read; the server rejects with 409 if the row has changed since. */
19222
+ "If-Match"?: string;
19223
+ };
17944
19224
  path: {
17945
19225
  id: string;
17946
19226
  };
@@ -18047,7 +19327,7 @@ interface operations {
18047
19327
  "application/json": components["schemas"]["ErrorResponseDto"];
18048
19328
  };
18049
19329
  };
18050
- /** @description Identity already has this role at this node */
19330
+ /** @description The identity already holds this role at this node, the assignment has been modified since the version named in If-Match was read (`assignment.version_mismatch`), or the role is the last administrator's at an organization node (`organization.last_admin`) */
18051
19331
  409: {
18052
19332
  headers: {
18053
19333
  [name: string]: unknown;
@@ -18058,7 +19338,7 @@ interface operations {
18058
19338
  * "error": {
18059
19339
  * "statusCode": 409,
18060
19340
  * "code": null,
18061
- * "message": "Identity already has this role at this node",
19341
+ * "message": "The identity already holds this role at this node, the assignment has been modified since the version named in If-Match was read (`assignment.version_mismatch`), or the role is the last administrator's at an organization node (`organization.last_admin`)",
18062
19342
  * "timestamp": "2026-04-20T12:00:00.000Z",
18063
19343
  * "path": "/api/v1/assignments/{id}",
18064
19344
  * "method": "PATCH"
@@ -18174,6 +19454,27 @@ interface operations {
18174
19454
  "application/json": components["schemas"]["ErrorResponseDto"];
18175
19455
  };
18176
19456
  };
19457
+ /** @description The member is the organization's last administrator (`organization.last_admin`); make someone else one first */
19458
+ 409: {
19459
+ headers: {
19460
+ [name: string]: unknown;
19461
+ };
19462
+ content: {
19463
+ /**
19464
+ * @example {
19465
+ * "error": {
19466
+ * "statusCode": 409,
19467
+ * "code": null,
19468
+ * "message": "The member is the organization's last administrator (`organization.last_admin`); make someone else one first",
19469
+ * "timestamp": "2026-04-20T12:00:00.000Z",
19470
+ * "path": "/api/v1/assignments/bulk-remove",
19471
+ * "method": "POST"
19472
+ * }
19473
+ * }
19474
+ */
19475
+ "application/json": components["schemas"]["ErrorResponseDto"];
19476
+ };
19477
+ };
18177
19478
  };
18178
19479
  };
18179
19480
  ApiAssignmentsController_bulkChangeRole: {
@@ -18284,7 +19585,7 @@ interface operations {
18284
19585
  "application/json": components["schemas"]["ErrorResponseDto"];
18285
19586
  };
18286
19587
  };
18287
- /** @description Identity already has this role at this node */
19588
+ /** @description The identity already holds this role at this node, the assignment has been modified since the version named in If-Match was read (`assignment.version_mismatch`), or the role is the last administrator's at an organization node (`organization.last_admin`) */
18288
19589
  409: {
18289
19590
  headers: {
18290
19591
  [name: string]: unknown;
@@ -18295,7 +19596,7 @@ interface operations {
18295
19596
  * "error": {
18296
19597
  * "statusCode": 409,
18297
19598
  * "code": null,
18298
- * "message": "Identity already has this role at this node",
19599
+ * "message": "The identity already holds this role at this node, the assignment has been modified since the version named in If-Match was read (`assignment.version_mismatch`), or the role is the last administrator's at an organization node (`organization.last_admin`)",
18299
19600
  * "timestamp": "2026-04-20T12:00:00.000Z",
18300
19601
  * "path": "/api/v1/assignments/bulk-change-role",
18301
19602
  * "method": "POST"
@@ -19241,8 +20542,7 @@ interface operations {
19241
20542
  ApiHierarchySchemaController_updateSchema: {
19242
20543
  parameters: {
19243
20544
  query?: never;
19244
- header: {
19245
- "if-match": string;
20545
+ header?: {
19246
20546
  /** @description Optimistic-lock token. Pass the `version` you read from the Environment — request fails 409 when the row has moved on. */
19247
20547
  "If-Match"?: string;
19248
20548
  };
@@ -21646,7 +22946,12 @@ declare class Assignments {
21646
22946
  * answer, read the current assignments before retrying.
21647
22947
  */
21648
22948
  create(input: RequestBody<"ApiAssignmentsController_assignRole">): Promise<ResponseBody<"ApiAssignmentsController_assignRole">>;
21649
- update(id: string, input: RequestBody<"ApiAssignmentsController_updateAssignment">): Promise<ResponseBody<"ApiAssignmentsController_updateAssignment">>;
22949
+ /**
22950
+ * Change the role or the window of a grant. Pass the `version` the
22951
+ * assignment was read with as `ifMatch`; a stale one answers 409
22952
+ * `assignment.version_mismatch` rather than overwriting a newer change.
22953
+ */
22954
+ update(id: string, input: RequestBody<"ApiAssignmentsController_updateAssignment">, options?: ConcurrencyOptions): Promise<ResponseBody<"ApiAssignmentsController_updateAssignment">>;
21650
22955
  delete(id: string): Promise<void>;
21651
22956
  /**
21652
22957
  * Grant many at once. Answers 207 with a per-item result rather than failing
@@ -21750,8 +23055,8 @@ type ItemOf$3<T> = T extends {
21750
23055
  } ? Item : never;
21751
23056
 
21752
23057
  /**
21753
- * Tenant organizations: one per business customer, a role per membership,
21754
- * each with its own authentication policy and identity provider. Every
23058
+ * Tenant organizations: one per business customer, membership apart from
23059
+ * the roles held inside it, each with its own authentication policy and identity provider. Every
21755
23060
  * call here needs the Environment's organizations container switched on.
21756
23061
  */
21757
23062
  declare class Organizations {
@@ -21776,8 +23081,12 @@ declare class Organizations {
21776
23081
  deleteAll(): Promise<void>;
21777
23082
  listMembers(id: string, query?: QueryParams<"ApiOrganizationsController_listMembers">): Paginator<OrganizationMemberItem>;
21778
23083
  addMember(id: string, input: RequestBody<"ApiOrganizationsController_addMember">): Promise<ResponseBody<"ApiOrganizationsController_addMember">>;
21779
- changeMemberRole(id: string, identityId: string, input: RequestBody<"ApiOrganizationsController_changeMemberRole">): Promise<ResponseBody<"ApiOrganizationsController_changeMemberRole">>;
21780
- /** Revokes that organization's one role; the identity and its other memberships are untouched. */
23084
+ /**
23085
+ * Deactivates the membership and revokes every role the member holds at
23086
+ * the organization's nodes; the identity and its other memberships are
23087
+ * untouched. A role in the organization is changed through the
23088
+ * organization's assignment routes, not here.
23089
+ */
21781
23090
  removeMember(id: string, identityId: string): Promise<void>;
21782
23091
  /**
21783
23092
  * Clears a member's second factor, for one who lost their authenticator:
@@ -22579,23 +23888,28 @@ interface CanopyTokenClaims {
22579
23888
  * The organization this session is acting in — present only on identity
22580
23889
  * tokens from an Environment with the organizations container on, for an
22581
23890
  * identity that belongs to at least one organization. Always minted
22582
- * together with `org_role`; read the pair through {@link orgContext}
23891
+ * together with `org_roles`; read the pair through {@link orgContext}
22583
23892
  * rather than separately.
22584
23893
  */
22585
23894
  org_id?: string;
22586
- /** The name of the single role the identity holds in `org_id`. */
22587
- org_role?: string;
23895
+ /**
23896
+ * The names of the roles the identity holds at the organization's own node,
23897
+ * sorted; empty for a member who holds none there. Membership is admission,
23898
+ * not a role: a member may hold roles only beneath the organization, or
23899
+ * none at all.
23900
+ */
23901
+ org_roles?: string[];
22588
23902
  [claim: string]: unknown;
22589
23903
  }
22590
23904
  /**
22591
23905
  * The organization context a verified token carries: which organization the
22592
- * session is acting in, and the one role it holds there.
23906
+ * session is acting in, and the roles it holds at that organization's node.
22593
23907
  */
22594
23908
  interface CanopyOrgContext {
22595
23909
  /** The organization's id — also a hierarchy node id, usable as `node_id`. */
22596
23910
  orgId: string;
22597
- /** The role's name (not its id): what `org_role` carries. */
22598
- orgRole: string;
23911
+ /** The roles' names (not ids) held at the organization node: what `org_roles` carries. Empty for a member holding none there. */
23912
+ orgRoles: string[];
22599
23913
  }
22600
23914
  /**
22601
23915
  * The organization context of a verified token, or `null` when it has none.
@@ -22603,16 +23917,18 @@ interface CanopyOrgContext {
22603
23917
  * `null` is an ordinary answer, not a failure: it is every token from an
22604
23918
  * Environment without the organizations container on, and every identity
22605
23919
  * that belongs to no organization yet. Branch on it rather than on the raw claims —
22606
- * Canopy mints `org_id` and `org_role` together, and this helper refuses a
23920
+ * Canopy mints `org_id` and `org_roles` together, and this helper refuses a
22607
23921
  * half-present pair instead of letting one claim be read as though the other
22608
- * were there.
23922
+ * were there. An empty `orgRoles` is a member of the organization holding no
23923
+ * role at its node; authorize such a session by evaluating, never by the
23924
+ * list's length.
22609
23925
  *
22610
23926
  * ```ts
22611
23927
  * const claims = await verifier.verify(token);
22612
23928
  * const org = orgContext(claims);
22613
23929
  *
22614
23930
  * if (org) {
22615
- * // acting inside org.orgId as org.orgRole
23931
+ * // acting inside org.orgId, holding org.orgRoles at its node
22616
23932
  * }
22617
23933
  * ```
22618
23934
  */