@datocms/cma-client 5.4.16 → 5.4.18

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.
@@ -81,6 +81,16 @@ export type RoleIdentity = string;
81
81
  * via the `definition` "type".
82
82
  */
83
83
  export type RoleType = 'role';
84
+ /**
85
+ * ID of environment. Can only contain lowercase letters, numbers and dashes
86
+ *
87
+ * This interface was referenced by `Environment`'s JSON-Schema
88
+ * via the `definition` "identity".
89
+ *
90
+ * This interface was referenced by `Environment`'s JSON-Schema
91
+ * via the `definition` "id".
92
+ */
93
+ export type EnvironmentIdentity = string;
84
94
  /**
85
95
  * RFC 4122 UUID of item type expressed in URL-safe base64 format
86
96
  *
@@ -101,16 +111,6 @@ export type ItemTypeIdentity = string;
101
111
  * via the `definition` "id".
102
112
  */
103
113
  export type WorkflowIdentity = string;
104
- /**
105
- * ID of environment. Can only contain lowercase letters, numbers and dashes
106
- *
107
- * This interface was referenced by `Environment`'s JSON-Schema
108
- * via the `definition` "identity".
109
- *
110
- * This interface was referenced by `Environment`'s JSON-Schema
111
- * via the `definition` "id".
112
- */
113
- export type EnvironmentIdentity = string;
114
114
  /**
115
115
  * RFC 4122 UUID of upload collection expressed in URL-safe base64 format
116
116
  *
@@ -268,9 +268,14 @@ export type AccessTokenInstancesTargetSchema = AccessToken[];
268
268
  */
269
269
  export type AccessTokenDestroyHrefSchema = {
270
270
  /**
271
- * New owner for resources previously owned by the deleted access token. This argument specifies the new owner type.
271
+ * New owner for resources previously owned by the deleted access token. This argument specifies the new owner type. Use `account` or `organization` to reassign to the project's owner — `client.site.find().owner` returns the right type/id pair to pass.
272
272
  */
273
- destination_user_type?: 'account' | 'user' | 'access_token' | 'sso_user';
273
+ destination_user_type?:
274
+ | 'account'
275
+ | 'organization'
276
+ | 'user'
277
+ | 'access_token'
278
+ | 'sso_user';
274
279
  /**
275
280
  * New owner for resources previously owned by the deleted access token. This argument specifies the new owner ID.
276
281
  */
@@ -2058,7 +2063,82 @@ export type SiteSelfHrefSchema = {
2058
2063
  */
2059
2064
  export type WorkflowInstancesTargetSchema = Workflow[];
2060
2065
  /**
2061
- * A Role represents a specific set of actions an editor (or an API token) can perform on your administrative area.
2066
+ * A Role groups the permissions that govern what a credential can do in a project. The same role definition is applied to **collaborators**, **SSO users**, and **API tokens** alike design roles around what the *credential* should be allowed to do, not who is holding it.
2067
+ *
2068
+ * > [!PROTIP] 📘 Same role, different identities
2069
+ * > Ask "what is the *credential* allowed to do?" — not "what is this *person* allowed to do?". For API tokens specifically, the role's permissions are further constrained by the token's API surface flags (`can_access_cda`, `can_access_cda_preview`, `can_access_cma`); see the [API token](/docs/content-management-api/resources/access-token) resource for details.
2070
+ *
2071
+ * ## How permissions are computed
2072
+ *
2073
+ * Most of the granular permissions on a role come as a `positive_<resource>_permissions` / `negative_<resource>_permissions` pair: build triggers, search indexes, records (`item_type`), uploads. They all follow the same rule:
2074
+ *
2075
+ * > Effective permissions = `(inherited ∪ positive_*) − negative_*`
2076
+ *
2077
+ * Positive entries (and entries pulled in via `relationships.inherits_permissions_from`) grant access. Negative entries always win when they overlap. The idiomatic recipe for "almost everything" is a single `action: "all"` positive entry plus targeted negative entries to subtract — instead of enumerating each allowed action.
2078
+ *
2079
+ * > [!WARNING] ⚠️ Send `positive_*` and `negative_*` together
2080
+ * > For each resource family (records, uploads, build triggers, search indexes), the matching `positive_*` and `negative_*` arrays must be **both present or both absent** in a create/update payload. On **update**, sent arrays *replace* the stored ones wholesale, so always read the role first and pass back the existing entries on the side you're not changing — sending `[]` to satisfy the constraint will erase everything that was there. (On create, `[]` is fine since there's nothing to lose.) The [Update endpoint](/docs/content-management-api/resources/role/update) documents an SDK helper that handles this diff for records and uploads.
2081
+ *
2082
+ * The computed result is exposed on every role response under `meta.final_permissions`; the raw declared values stay on `attributes.*`. See [Effective vs declared permissions](#effective-vs-declared-permissions) below.
2083
+ *
2084
+ * ## Project-level permissions
2085
+ *
2086
+ * These attributes gate access to project-wide capabilities. They apply uniformly across the whole project; granular control over individual records and uploads lives under [Per-environment content permissions](#per-environment-content-permissions).
2087
+ *
2088
+ * - **Project-wide flags.** Boolean attributes named `can_*` (`can_edit_schema`, `can_manage_environments`, `can_manage_access_tokens`, …) cover the schema, environments, users, webhooks, and so on — see the property table for the full list.
2089
+ * - **Environment access.** `environments_access` controls *which* environments the credential can enter at all (`all`, `primary_only`, `sandbox_only`, or `none`). Use `none` when the role is meant only to be inherited from.
2090
+ * - **Build triggers.** The role may **manually fire** the build triggers listed in `positive_build_trigger_permissions`, minus those listed in `negative_build_trigger_permissions`. Use `build_trigger: null` on an entry to cover every trigger at once. Creating, editing, or deleting trigger definitions is gated separately by `can_manage_build_triggers`.
2091
+ * - **Search indexes.** The role may **manually re-index** the search indexes listed in `positive_search_index_permissions`, minus those listed in `negative_search_index_permissions`. Use `search_index: null` on an entry to cover every index. Managing the index definitions themselves is gated separately by `can_manage_search_indexes`.
2092
+ *
2093
+ * ## Per-environment content permissions
2094
+ *
2095
+ * The role's access to **records** and **uploads** is governed by two positive/negative array pairs. Every entry is **scoped to a single environment** via the required `environment` field — to grant the same permission across multiple environments, repeat the entry once per environment id (or use `inherits_permissions_from` together with `environments_access`). The computation is the same `(inherited ∪ positive_*) − negative_*` rule from [How permissions are computed](#how-permissions-are-computed), evaluated per environment.
2096
+ *
2097
+ * ###### Records
2098
+ *
2099
+ * Permission entries live in `positive_item_type_permissions` (and the `negative_*` counterpart). Each entry is a discriminated union keyed by `action`:
2100
+ *
2101
+ * - `all` — every action below
2102
+ * - `read` — read records
2103
+ * - `create` — create new records
2104
+ * - `update` — edit existing records
2105
+ * - `publish` — publish/unpublish records
2106
+ * - `duplicate` — duplicate records
2107
+ * - `delete` — destroy records
2108
+ * - `edit_creator` — change a record's `creator` relationship
2109
+ * - `take_over` — wrest a record from another user currently editing it
2110
+ * - `move_to_stage` — move a record between workflow stages
2111
+ *
2112
+ * Per entry you can also restrict by:
2113
+ *
2114
+ * - `item_type` — restrict to a specific model (`null` = all models)
2115
+ * - `workflow` — restrict to records associated with a workflow (mutually exclusive with `item_type`)
2116
+ * - `on_creator` — `anyone`, `self` (records the credential created), or `role` (records created by anyone with this role)
2117
+ * - `localization_scope` + `locale` — for `create`/`update`/`publish`/`all`: restrict to localized vs non-localized content, optionally pinning to one locale (on `all` the scope is forced to `"all"`)
2118
+ * - `on_stage` / `to_stage` — for workflow-aware actions: restrict to records currently on a stage, or to moves towards a stage
2119
+ *
2120
+ * The shape of each entry depends on the `action` — see the property tables on each endpoint for which sub-fields are valid per branch.
2121
+ *
2122
+ * > [!WARNING] ⚠️ Some restrictors require an Enterprise plan
2123
+ * > Workflow-aware permissions — the `move_to_stage` action and the `workflow` / `on_stage` / `to_stage` restrictors — require [Workflows](https://www.datocms.com/features/workflows), an Enterprise feature. Per-content-scope restrictions are also gated: only `localization_scope: "all"` is available on every plan, while `"localized"` (with its companion `locale`) and `"not_localized"` both require Enterprise. Setting any of these on a non-Enterprise project will return an error — check the [pricing page](https://www.datocms.com/pricing) before relying on them.
2124
+ *
2125
+ * ###### Uploads
2126
+ *
2127
+ * Permission entries live in `positive_upload_permissions` (and the `negative_*` counterpart). Same discriminated-union shape as records, with the upload-relevant actions (`read`, `create`, `update`, `delete`, `edit_creator`, `replace_asset`, `move`, `all`), scoped by `upload_collection` instead of `item_type`. The `move` action also accepts `move_to_upload_collection` to restrict the destination of the move.
2128
+ *
2129
+ * ## Inheriting from other roles
2130
+ *
2131
+ * `relationships.inherits_permissions_from` accepts a list of role ids whose permissions are unioned into this role's positive set before the negative set is subtracted (per [How permissions are computed](#how-permissions-are-computed)). This is how built-in roles are typically extended without copying their full permission tree — duplicate the closest built-in role, then add a `negative_*` entry to take something away, or set `inherits_permissions_from` and add only the positive entries that differ.
2132
+ *
2133
+ * ## Effective vs declared permissions
2134
+ *
2135
+ * Two views of a role's permissions are surfaced on the response:
2136
+ *
2137
+ * - **`attributes.*`** — the permissions declared *on this role directly*. This is what was sent on create/update; it does not reflect anything inherited from `relationships.inherits_permissions_from`.
2138
+ * - **`meta.final_permissions`** — the **effective** permissions after walking the inheritance chain and applying the rule from [How permissions are computed](#how-permissions-are-computed). This is the set actually enforced when a credential bound to this role makes a request.
2139
+ *
2140
+ * When debugging "why can't this user do X?", read `meta.final_permissions`, not `attributes`.
2141
+ *
2062
2142
  *
2063
2143
  * This interface was referenced by `DatoApi`'s JSON-Schema
2064
2144
  * via the `definition` "role".
@@ -2075,11 +2155,11 @@ export type Role = {
2075
2155
  */
2076
2156
  can_edit_favicon: boolean;
2077
2157
  /**
2078
- * Can change project global properties
2158
+ * Can change project-wide settings (project name, internal subdomain, frontend preview URL, deployment settings)
2079
2159
  */
2080
2160
  can_edit_site: boolean;
2081
2161
  /**
2082
- * Can create and edit models and plugins
2162
+ * Can create and edit the project schema: models, block models, fields, fieldsets, validators, and plugins
2083
2163
  */
2084
2164
  can_edit_schema: boolean;
2085
2165
  /**
@@ -2087,11 +2167,11 @@ export type Role = {
2087
2167
  */
2088
2168
  can_manage_menu: boolean;
2089
2169
  /**
2090
- * Can change locales, timezone and UI theme
2170
+ * Can edit per-environment settings of the environments this role has access to: locales, timezone, and UI theme. This is *not* about creating or switching environments — see `can_manage_environments` for that, and `environments_access` for which environments this role can enter at all.
2091
2171
  */
2092
2172
  can_edit_environment: boolean;
2093
2173
  /**
2094
- * Can promote environments to primary and manage maintenance mode
2174
+ * Can promote a sandbox environment to primary (atomic swap) and toggle the project's maintenance mode. Distinct from `can_manage_environments`, which covers creating/forking/deleting sandboxes.
2095
2175
  */
2096
2176
  can_promote_environments: boolean;
2097
2177
  /**
@@ -2123,7 +2203,7 @@ export type Role = {
2123
2203
  */
2124
2204
  can_manage_webhooks: boolean;
2125
2205
  /**
2126
- * Can create and delete sandbox environments and promote them to primary environment
2206
+ * Can create, fork, and delete sandbox environments. Promotion to primary is gated separately by `can_promote_environments`.
2127
2207
  */
2128
2208
  can_manage_environments: boolean;
2129
2209
  /**
@@ -2155,161 +2235,75 @@ export type Role = {
2155
2235
  */
2156
2236
  can_access_search_index_events_log: boolean;
2157
2237
  /**
2158
- * Allowed actions on a model (or all) for a role
2159
- */
2160
- positive_item_type_permissions: {
2161
- item_type?: ItemTypeIdentity | null;
2162
- workflow?: WorkflowIdentity | null;
2163
- on_stage?: null | string;
2164
- to_stage?: null | string;
2165
- environment: EnvironmentIdentity;
2166
- /**
2167
- * Permitted action
2168
- */
2169
- action:
2170
- | 'all'
2171
- | 'read'
2172
- | 'update'
2173
- | 'create'
2174
- | 'duplicate'
2175
- | 'delete'
2176
- | 'publish'
2177
- | 'edit_creator'
2178
- | 'take_over'
2179
- | 'move_to_stage';
2180
- /**
2181
- * Permitted creator
2182
- */
2183
- on_creator?: 'anyone' | 'self' | 'role' | null;
2184
- /**
2185
- * Permitted content scope
2186
- */
2187
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
2188
- /**
2189
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
2190
- */
2191
- locale?: string | null;
2192
- }[];
2238
+ * Allowed actions on a model (or all) for a role.
2239
+ *
2240
+ * The shape of each entry depends on the `action` (discriminated union). Idiomatic recipes:
2241
+ * - To grant every action, use a single `action: "all"` entry with `localization_scope: "all"`.
2242
+ * - To grant a subset (e.g. create+read+update but not delete), prefer a single `action: "all"` entry plus `negative_item_type_permissions` entries for the actions to exclude — instead of listing each allowed action separately.
2243
+ */
2244
+ positive_item_type_permissions: (
2245
+ | RoleItemTypePermissionAll
2246
+ | RoleItemTypePermissionRead
2247
+ | RoleItemTypePermissionCreate
2248
+ | RoleItemTypePermissionUpdateOrPublish
2249
+ | RoleItemTypePermissionDuplicate
2250
+ | RoleItemTypePermissionDeleteOrEditCreatorOrTakeOver
2251
+ | RoleItemTypePermissionMoveToStage
2252
+ )[];
2193
2253
  /**
2194
- * Prohibited actions on a model (or all) for a role
2254
+ * Prohibited actions on a model (or all) for a role. Negative permissions take precedence and are typically paired with a broader positive `action: "all"` entry to subtract specific actions (e.g. forbid `delete`).
2195
2255
  */
2196
- negative_item_type_permissions: {
2197
- item_type?: ItemTypeIdentity | null;
2198
- workflow?: WorkflowIdentity | null;
2199
- on_stage?: null | string;
2200
- to_stage?: null | string;
2201
- environment: EnvironmentIdentity;
2202
- /**
2203
- * Permitted action
2204
- */
2205
- action:
2206
- | 'all'
2207
- | 'read'
2208
- | 'update'
2209
- | 'create'
2210
- | 'duplicate'
2211
- | 'delete'
2212
- | 'publish'
2213
- | 'edit_creator'
2214
- | 'take_over'
2215
- | 'move_to_stage';
2216
- /**
2217
- * Permitted creator
2218
- */
2219
- on_creator?: 'anyone' | 'self' | 'role' | null;
2220
- /**
2221
- * Permitted content scope
2222
- */
2223
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
2224
- /**
2225
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
2226
- */
2227
- locale?: string | null;
2228
- }[];
2256
+ negative_item_type_permissions: (
2257
+ | RoleItemTypePermissionAll
2258
+ | RoleItemTypePermissionRead
2259
+ | RoleItemTypePermissionCreate
2260
+ | RoleItemTypePermissionUpdateOrPublish
2261
+ | RoleItemTypePermissionDuplicate
2262
+ | RoleItemTypePermissionDeleteOrEditCreatorOrTakeOver
2263
+ | RoleItemTypePermissionMoveToStage
2264
+ )[];
2229
2265
  /**
2230
- * Allowed actions on a model (or all) for a role
2266
+ * Allowed actions on uploads (or all) for a role.
2267
+ *
2268
+ * The shape of each entry depends on the `action` (discriminated union). To grant a subset, prefer a single `action: "all"` entry plus `negative_upload_permissions` entries for the actions to exclude.
2231
2269
  */
2232
- positive_upload_permissions: {
2233
- environment: EnvironmentIdentity;
2234
- /**
2235
- * Permitted action
2236
- */
2237
- action:
2238
- | 'all'
2239
- | 'read'
2240
- | 'update'
2241
- | 'create'
2242
- | 'delete'
2243
- | 'edit_creator'
2244
- | 'replace_asset'
2245
- | 'move';
2246
- /**
2247
- * Permitted creator
2248
- */
2249
- on_creator?: 'anyone' | 'self' | 'role' | null;
2250
- /**
2251
- * Permitted content scope
2252
- */
2253
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
2254
- /**
2255
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
2256
- */
2257
- locale?: string | null;
2258
- upload_collection?: UploadCollectionIdentity | null;
2259
- move_to_upload_collection?: UploadCollectionIdentity | null;
2260
- }[];
2270
+ positive_upload_permissions: (
2271
+ | RoleUploadPermissionAll
2272
+ | RoleUploadPermissionUpdate
2273
+ | RoleUploadPermissionCreate
2274
+ | RoleUploadPermissionReadOrDeleteOrEditCreatorOrReplaceAsset
2275
+ | RoleUploadPermissionMove
2276
+ )[];
2261
2277
  /**
2262
- * Prohibited actions on a model (or all) for a role
2278
+ * Prohibited actions on uploads (or all) for a role. Negative permissions take precedence and are typically paired with a broader positive `action: "all"` entry to subtract specific actions.
2263
2279
  */
2264
- negative_upload_permissions: {
2265
- environment: EnvironmentIdentity;
2266
- /**
2267
- * Permitted action
2268
- */
2269
- action:
2270
- | 'all'
2271
- | 'read'
2272
- | 'update'
2273
- | 'create'
2274
- | 'delete'
2275
- | 'edit_creator'
2276
- | 'replace_asset'
2277
- | 'move';
2278
- /**
2279
- * Permitted creator
2280
- */
2281
- on_creator?: 'anyone' | 'self' | 'role' | null;
2282
- /**
2283
- * Permitted content scope
2284
- */
2285
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
2286
- /**
2287
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
2288
- */
2289
- locale?: string | null;
2290
- upload_collection?: UploadCollectionIdentity | null;
2291
- move_to_upload_collection?: UploadCollectionIdentity | null;
2292
- }[];
2280
+ negative_upload_permissions: (
2281
+ | RoleUploadPermissionAll
2282
+ | RoleUploadPermissionUpdate
2283
+ | RoleUploadPermissionCreate
2284
+ | RoleUploadPermissionReadOrDeleteOrEditCreatorOrReplaceAsset
2285
+ | RoleUploadPermissionMove
2286
+ )[];
2293
2287
  /**
2294
- * Allowed build triggers for a role
2288
+ * Build triggers this role is allowed to **manually fire**. An entry with `build_trigger: null` covers every build trigger. Note: this does not control creating/editing build triggers themselves that is gated by `can_manage_build_triggers`.
2295
2289
  */
2296
2290
  positive_build_trigger_permissions: {
2297
2291
  build_trigger?: BuildTriggerIdentity | null;
2298
2292
  }[];
2299
2293
  /**
2300
- * Prohibited build triggers for a role
2294
+ * Build triggers this role is **forbidden** from manually firing. Negative entries take precedence over positive ones; pair with a `build_trigger: null` positive entry to allow all-but-N.
2301
2295
  */
2302
2296
  negative_build_trigger_permissions: {
2303
2297
  build_trigger?: BuildTriggerIdentity | null;
2304
2298
  }[];
2305
2299
  /**
2306
- * Search indexes that can be triggered by a role
2300
+ * Search indexes this role is allowed to **manually re-index**. An entry with `search_index: null` covers every search index. Note: this does not control creating/editing search indexes themselves — that is gated by `can_manage_search_indexes`.
2307
2301
  */
2308
2302
  positive_search_index_permissions: {
2309
2303
  search_index?: SearchIndexIdentity | null;
2310
2304
  }[];
2311
2305
  /**
2312
- * Search indexes that can't be triggered by a role
2306
+ * Search indexes this role is **forbidden** from manually re-indexing. Negative entries take precedence over positive ones; pair with a `search_index: null` positive entry to allow all-but-N.
2313
2307
  */
2314
2308
  negative_search_index_permissions: {
2315
2309
  search_index?: SearchIndexIdentity | null;
@@ -2322,6 +2316,350 @@ export type RoleUpdateTargetSchema = Role;
2322
2316
  export type RoleSelfTargetSchema = Role;
2323
2317
  export type RoleDestroyTargetSchema = Role;
2324
2318
  export type RoleDuplicateTargetSchema = Role;
2319
+ /**
2320
+ * Item-type permission entry granting all actions on a model. Requires `localization_scope: "all"`.
2321
+ *
2322
+ * This interface was referenced by `Role`'s JSON-Schema
2323
+ * via the `definition` "item_type_permission_all".
2324
+ */
2325
+ export type RoleItemTypePermissionAll = {
2326
+ /**
2327
+ * Permitted action
2328
+ */
2329
+ action: 'all';
2330
+ environment: EnvironmentIdentity;
2331
+ /**
2332
+ * Restricts the permission to a specific model. When `null`, the permission applies to all models.
2333
+ */
2334
+ item_type?: ItemTypeIdentity | null;
2335
+ /**
2336
+ * Restricts the permission to records associated with a specific workflow. Mutually exclusive with `item_type`.
2337
+ */
2338
+ workflow?: WorkflowIdentity | null;
2339
+ /**
2340
+ * Restrict to records currently on a workflow stage.
2341
+ */
2342
+ on_stage?: string | null;
2343
+ /**
2344
+ * Restrict to moves towards a specific workflow stage.
2345
+ */
2346
+ to_stage?: string | null;
2347
+ /**
2348
+ * Permitted creator
2349
+ */
2350
+ on_creator: 'anyone' | 'self' | 'role';
2351
+ /**
2352
+ * For `action: "all"` this must be `"all"`.
2353
+ */
2354
+ localization_scope: 'all';
2355
+ [k: string]: unknown;
2356
+ };
2357
+ /**
2358
+ * Item-type permission entry granting `read` on records. `localization_scope` and `locale` must be omitted (or null).
2359
+ *
2360
+ * This interface was referenced by `Role`'s JSON-Schema
2361
+ * via the `definition` "item_type_permission_read".
2362
+ */
2363
+ export type RoleItemTypePermissionRead = {
2364
+ /**
2365
+ * Permitted action
2366
+ */
2367
+ action: 'read';
2368
+ environment: EnvironmentIdentity;
2369
+ /**
2370
+ * Restricts the permission to a specific model. When `null`, the permission applies to all models.
2371
+ */
2372
+ item_type?: ItemTypeIdentity | null;
2373
+ /**
2374
+ * Restricts the permission to records associated with a specific workflow. Mutually exclusive with `item_type`.
2375
+ */
2376
+ workflow?: WorkflowIdentity | null;
2377
+ /**
2378
+ * Permitted creator
2379
+ */
2380
+ on_creator: 'anyone' | 'self' | 'role';
2381
+ [k: string]: unknown;
2382
+ };
2383
+ /**
2384
+ * Item-type permission entry granting `create` on records. Requires `localization_scope`; if `localization_scope: "localized"`, `locale` is also required. `on_creator`, `on_stage`, and `to_stage` are not applicable and must be omitted (or null).
2385
+ *
2386
+ * This interface was referenced by `Role`'s JSON-Schema
2387
+ * via the `definition` "item_type_permission_create".
2388
+ */
2389
+ export type RoleItemTypePermissionCreate = {
2390
+ /**
2391
+ * Permitted action
2392
+ */
2393
+ action: 'create';
2394
+ environment: EnvironmentIdentity;
2395
+ /**
2396
+ * Restricts the permission to a specific model. When `null`, the permission applies to all models.
2397
+ */
2398
+ item_type?: ItemTypeIdentity | null;
2399
+ /**
2400
+ * Restricts the permission to records associated with a specific workflow. Mutually exclusive with `item_type`.
2401
+ */
2402
+ workflow?: WorkflowIdentity | null;
2403
+ /**
2404
+ * Permitted content scope
2405
+ */
2406
+ localization_scope: 'all' | 'localized' | 'not_localized';
2407
+ /**
2408
+ * Required (non-null) when `localization_scope` is `"localized"`; must be omitted otherwise.
2409
+ */
2410
+ locale?: string | null;
2411
+ [k: string]: unknown;
2412
+ };
2413
+ /**
2414
+ * Item-type permission entry granting `update` or `publish` on records. Requires `localization_scope`; if `localization_scope: "localized"`, `locale` is also required.
2415
+ *
2416
+ * This interface was referenced by `Role`'s JSON-Schema
2417
+ * via the `definition` "item_type_permission_update_or_publish".
2418
+ */
2419
+ export type RoleItemTypePermissionUpdateOrPublish = {
2420
+ /**
2421
+ * Permitted action
2422
+ */
2423
+ action: 'update' | 'publish';
2424
+ environment: EnvironmentIdentity;
2425
+ /**
2426
+ * Restricts the permission to a specific model. When `null`, the permission applies to all models.
2427
+ */
2428
+ item_type?: ItemTypeIdentity | null;
2429
+ /**
2430
+ * Restricts the permission to records associated with a specific workflow. Mutually exclusive with `item_type`.
2431
+ */
2432
+ workflow?: WorkflowIdentity | null;
2433
+ /**
2434
+ * Restrict to records currently on a workflow stage.
2435
+ */
2436
+ on_stage?: string | null;
2437
+ /**
2438
+ * Permitted creator
2439
+ */
2440
+ on_creator: 'anyone' | 'self' | 'role';
2441
+ /**
2442
+ * Permitted content scope
2443
+ */
2444
+ localization_scope: 'all' | 'localized' | 'not_localized';
2445
+ /**
2446
+ * Required (non-null) when `localization_scope` is `"localized"`; must be omitted otherwise.
2447
+ */
2448
+ locale?: string | null;
2449
+ [k: string]: unknown;
2450
+ };
2451
+ /**
2452
+ * Item-type permission entry granting `duplicate` on records. `on_creator`, `localization_scope` and `locale` are not applicable and must be omitted (or null).
2453
+ *
2454
+ * This interface was referenced by `Role`'s JSON-Schema
2455
+ * via the `definition` "item_type_permission_duplicate".
2456
+ */
2457
+ export type RoleItemTypePermissionDuplicate = {
2458
+ /**
2459
+ * Permitted action
2460
+ */
2461
+ action: 'duplicate';
2462
+ environment: EnvironmentIdentity;
2463
+ /**
2464
+ * Restricts the permission to a specific model. When `null`, the permission applies to all models.
2465
+ */
2466
+ item_type?: ItemTypeIdentity | null;
2467
+ /**
2468
+ * Restricts the permission to records associated with a specific workflow. Mutually exclusive with `item_type`.
2469
+ */
2470
+ workflow?: WorkflowIdentity | null;
2471
+ /**
2472
+ * Restrict to records currently on a workflow stage.
2473
+ */
2474
+ on_stage?: string | null;
2475
+ [k: string]: unknown;
2476
+ };
2477
+ /**
2478
+ * Item-type permission entry granting `delete`, `edit_creator`, or `take_over` on records. `localization_scope` and `locale` must be omitted (or null).
2479
+ *
2480
+ * This interface was referenced by `Role`'s JSON-Schema
2481
+ * via the `definition` "item_type_permission_delete_or_edit_creator_or_take_over".
2482
+ */
2483
+ export type RoleItemTypePermissionDeleteOrEditCreatorOrTakeOver = {
2484
+ /**
2485
+ * Permitted action
2486
+ */
2487
+ action: 'delete' | 'edit_creator' | 'take_over';
2488
+ environment: EnvironmentIdentity;
2489
+ /**
2490
+ * Restricts the permission to a specific model. When `null`, the permission applies to all models.
2491
+ */
2492
+ item_type?: ItemTypeIdentity | null;
2493
+ /**
2494
+ * Restricts the permission to records associated with a specific workflow. Mutually exclusive with `item_type`.
2495
+ */
2496
+ workflow?: WorkflowIdentity | null;
2497
+ /**
2498
+ * Restrict to records currently on a workflow stage.
2499
+ */
2500
+ on_stage?: string | null;
2501
+ /**
2502
+ * Permitted creator
2503
+ */
2504
+ on_creator: 'anyone' | 'self' | 'role';
2505
+ [k: string]: unknown;
2506
+ };
2507
+ /**
2508
+ * Item-type permission entry granting `move_to_stage` on records. `localization_scope` and `locale` must be omitted (or null).
2509
+ *
2510
+ * This interface was referenced by `Role`'s JSON-Schema
2511
+ * via the `definition` "item_type_permission_move_to_stage".
2512
+ */
2513
+ export type RoleItemTypePermissionMoveToStage = {
2514
+ /**
2515
+ * Permitted action
2516
+ */
2517
+ action: 'move_to_stage';
2518
+ environment: EnvironmentIdentity;
2519
+ /**
2520
+ * Restricts the permission to a specific model. When `null`, the permission applies to all models.
2521
+ */
2522
+ item_type?: ItemTypeIdentity | null;
2523
+ /**
2524
+ * Restricts the permission to records associated with a specific workflow. Mutually exclusive with `item_type`.
2525
+ */
2526
+ workflow?: WorkflowIdentity | null;
2527
+ /**
2528
+ * Restrict to records currently on a workflow stage.
2529
+ */
2530
+ on_stage?: string | null;
2531
+ /**
2532
+ * Restrict to moves towards a specific workflow stage.
2533
+ */
2534
+ to_stage?: string | null;
2535
+ /**
2536
+ * Permitted creator
2537
+ */
2538
+ on_creator: 'anyone' | 'self' | 'role';
2539
+ [k: string]: unknown;
2540
+ };
2541
+ /**
2542
+ * Upload permission entry granting all actions on uploads. Requires `localization_scope: "all"`.
2543
+ *
2544
+ * This interface was referenced by `Role`'s JSON-Schema
2545
+ * via the `definition` "upload_permission_all".
2546
+ */
2547
+ export type RoleUploadPermissionAll = {
2548
+ /**
2549
+ * Permitted action
2550
+ */
2551
+ action: 'all';
2552
+ environment: EnvironmentIdentity;
2553
+ /**
2554
+ * Restricts the permission to a specific upload collection. When `null`, the permission applies to all collections.
2555
+ */
2556
+ upload_collection?: UploadCollectionIdentity | null;
2557
+ /**
2558
+ * Permitted creator
2559
+ */
2560
+ on_creator: 'anyone' | 'self' | 'role';
2561
+ /**
2562
+ * For `action: "all"` this must be `"all"`.
2563
+ */
2564
+ localization_scope: 'all';
2565
+ [k: string]: unknown;
2566
+ };
2567
+ /**
2568
+ * Upload permission entry granting `update` on uploads. Requires `localization_scope`; if `localization_scope: "localized"`, `locale` is also required.
2569
+ *
2570
+ * This interface was referenced by `Role`'s JSON-Schema
2571
+ * via the `definition` "upload_permission_update".
2572
+ */
2573
+ export type RoleUploadPermissionUpdate = {
2574
+ /**
2575
+ * Permitted action
2576
+ */
2577
+ action: 'update';
2578
+ environment: EnvironmentIdentity;
2579
+ /**
2580
+ * Restricts the permission to a specific upload collection. When `null`, the permission applies to all collections.
2581
+ */
2582
+ upload_collection?: UploadCollectionIdentity | null;
2583
+ /**
2584
+ * Permitted creator
2585
+ */
2586
+ on_creator: 'anyone' | 'self' | 'role';
2587
+ /**
2588
+ * Permitted content scope
2589
+ */
2590
+ localization_scope: 'all' | 'localized' | 'not_localized';
2591
+ /**
2592
+ * Required (non-null) when `localization_scope` is `"localized"`; must be omitted otherwise.
2593
+ */
2594
+ locale?: string | null;
2595
+ [k: string]: unknown;
2596
+ };
2597
+ /**
2598
+ * Upload permission entry granting `create` on uploads. `on_creator`, `localization_scope` and `locale` are not applicable and must be omitted (or null).
2599
+ *
2600
+ * This interface was referenced by `Role`'s JSON-Schema
2601
+ * via the `definition` "upload_permission_create".
2602
+ */
2603
+ export type RoleUploadPermissionCreate = {
2604
+ /**
2605
+ * Permitted action
2606
+ */
2607
+ action: 'create';
2608
+ environment: EnvironmentIdentity;
2609
+ /**
2610
+ * Restricts the permission to a specific upload collection. When `null`, the permission applies to all collections.
2611
+ */
2612
+ upload_collection?: UploadCollectionIdentity | null;
2613
+ [k: string]: unknown;
2614
+ };
2615
+ /**
2616
+ * Upload permission entry granting `read`, `delete`, `edit_creator`, or `replace_asset` on uploads. `localization_scope` and `locale` must be omitted (or null).
2617
+ *
2618
+ * This interface was referenced by `Role`'s JSON-Schema
2619
+ * via the `definition` "upload_permission_read_or_delete_or_edit_creator_or_replace_asset".
2620
+ */
2621
+ export type RoleUploadPermissionReadOrDeleteOrEditCreatorOrReplaceAsset = {
2622
+ /**
2623
+ * Permitted action
2624
+ */
2625
+ action: 'read' | 'delete' | 'edit_creator' | 'replace_asset';
2626
+ environment: EnvironmentIdentity;
2627
+ /**
2628
+ * Restricts the permission to a specific upload collection. When `null`, the permission applies to all collections.
2629
+ */
2630
+ upload_collection?: UploadCollectionIdentity | null;
2631
+ /**
2632
+ * Permitted creator
2633
+ */
2634
+ on_creator: 'anyone' | 'self' | 'role';
2635
+ [k: string]: unknown;
2636
+ };
2637
+ /**
2638
+ * Upload permission entry granting `move` on uploads. `localization_scope` and `locale` must be omitted (or null). `move_to_upload_collection` is only valid here.
2639
+ *
2640
+ * This interface was referenced by `Role`'s JSON-Schema
2641
+ * via the `definition` "upload_permission_move".
2642
+ */
2643
+ export type RoleUploadPermissionMove = {
2644
+ /**
2645
+ * Permitted action
2646
+ */
2647
+ action: 'move';
2648
+ environment: EnvironmentIdentity;
2649
+ /**
2650
+ * Restricts the permission to a specific upload collection. When `null`, the permission applies to all collections.
2651
+ */
2652
+ upload_collection?: UploadCollectionIdentity | null;
2653
+ /**
2654
+ * Restricts the destination upload collection of the move action. When `null`, any destination is allowed.
2655
+ */
2656
+ move_to_upload_collection?: UploadCollectionIdentity | null;
2657
+ /**
2658
+ * Permitted creator
2659
+ */
2660
+ on_creator: 'anyone' | 'self' | 'role';
2661
+ [k: string]: unknown;
2662
+ };
2325
2663
  /**
2326
2664
  * JSON API data
2327
2665
  *
@@ -2348,11 +2686,11 @@ export type RoleMeta = {
2348
2686
  */
2349
2687
  can_edit_favicon: boolean;
2350
2688
  /**
2351
- * Can change project global properties
2689
+ * Can change project-wide settings (project name, internal subdomain, frontend preview URL, deployment settings)
2352
2690
  */
2353
2691
  can_edit_site: boolean;
2354
2692
  /**
2355
- * Can create and edit models and plugins
2693
+ * Can create and edit the project schema: models, block models, fields, fieldsets, validators, and plugins
2356
2694
  */
2357
2695
  can_edit_schema: boolean;
2358
2696
  /**
@@ -2360,11 +2698,11 @@ export type RoleMeta = {
2360
2698
  */
2361
2699
  can_manage_menu: boolean;
2362
2700
  /**
2363
- * Can change locales, timezone and UI theme
2701
+ * Can edit per-environment settings of the environments this role has access to: locales, timezone, and UI theme. This is *not* about creating or switching environments — see `can_manage_environments` for that, and `environments_access` for which environments this role can enter at all.
2364
2702
  */
2365
2703
  can_edit_environment: boolean;
2366
2704
  /**
2367
- * Can promote environments to primary and manage maintenance mode
2705
+ * Can promote a sandbox environment to primary (atomic swap) and toggle the project's maintenance mode. Distinct from `can_manage_environments`, which covers creating/forking/deleting sandboxes.
2368
2706
  */
2369
2707
  can_promote_environments: boolean;
2370
2708
  /**
@@ -2396,7 +2734,7 @@ export type RoleMeta = {
2396
2734
  */
2397
2735
  can_manage_webhooks: boolean;
2398
2736
  /**
2399
- * Can create and delete sandbox environments and promote them to primary environment
2737
+ * Can create, fork, and delete sandbox environments. Promotion to primary is gated separately by `can_promote_environments`.
2400
2738
  */
2401
2739
  can_manage_environments: boolean;
2402
2740
  /**
@@ -2428,161 +2766,75 @@ export type RoleMeta = {
2428
2766
  */
2429
2767
  can_access_search_index_events_log: boolean;
2430
2768
  /**
2431
- * Allowed actions on a model (or all) for a role
2432
- */
2433
- positive_item_type_permissions: {
2434
- item_type?: ItemTypeIdentity | null;
2435
- workflow?: WorkflowIdentity | null;
2436
- on_stage?: null | string;
2437
- to_stage?: null | string;
2438
- environment: EnvironmentIdentity;
2439
- /**
2440
- * Permitted action
2441
- */
2442
- action:
2443
- | 'all'
2444
- | 'read'
2445
- | 'update'
2446
- | 'create'
2447
- | 'duplicate'
2448
- | 'delete'
2449
- | 'publish'
2450
- | 'edit_creator'
2451
- | 'take_over'
2452
- | 'move_to_stage';
2453
- /**
2454
- * Permitted creator
2455
- */
2456
- on_creator?: 'anyone' | 'self' | 'role' | null;
2457
- /**
2458
- * Permitted content scope
2459
- */
2460
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
2461
- /**
2462
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
2463
- */
2464
- locale?: string | null;
2465
- }[];
2769
+ * Allowed actions on a model (or all) for a role.
2770
+ *
2771
+ * The shape of each entry depends on the `action` (discriminated union). Idiomatic recipes:
2772
+ * - To grant every action, use a single `action: "all"` entry with `localization_scope: "all"`.
2773
+ * - To grant a subset (e.g. create+read+update but not delete), prefer a single `action: "all"` entry plus `negative_item_type_permissions` entries for the actions to exclude — instead of listing each allowed action separately.
2774
+ */
2775
+ positive_item_type_permissions: (
2776
+ | RoleItemTypePermissionAll
2777
+ | RoleItemTypePermissionRead
2778
+ | RoleItemTypePermissionCreate
2779
+ | RoleItemTypePermissionUpdateOrPublish
2780
+ | RoleItemTypePermissionDuplicate
2781
+ | RoleItemTypePermissionDeleteOrEditCreatorOrTakeOver
2782
+ | RoleItemTypePermissionMoveToStage
2783
+ )[];
2466
2784
  /**
2467
- * Prohibited actions on a model (or all) for a role
2785
+ * Prohibited actions on a model (or all) for a role. Negative permissions take precedence and are typically paired with a broader positive `action: "all"` entry to subtract specific actions (e.g. forbid `delete`).
2468
2786
  */
2469
- negative_item_type_permissions: {
2470
- item_type?: ItemTypeIdentity | null;
2471
- workflow?: WorkflowIdentity | null;
2472
- on_stage?: null | string;
2473
- to_stage?: null | string;
2474
- environment: EnvironmentIdentity;
2475
- /**
2476
- * Permitted action
2477
- */
2478
- action:
2479
- | 'all'
2480
- | 'read'
2481
- | 'update'
2482
- | 'create'
2483
- | 'duplicate'
2484
- | 'delete'
2485
- | 'publish'
2486
- | 'edit_creator'
2487
- | 'take_over'
2488
- | 'move_to_stage';
2489
- /**
2490
- * Permitted creator
2491
- */
2492
- on_creator?: 'anyone' | 'self' | 'role' | null;
2493
- /**
2494
- * Permitted content scope
2495
- */
2496
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
2497
- /**
2498
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
2499
- */
2500
- locale?: string | null;
2501
- }[];
2787
+ negative_item_type_permissions: (
2788
+ | RoleItemTypePermissionAll
2789
+ | RoleItemTypePermissionRead
2790
+ | RoleItemTypePermissionCreate
2791
+ | RoleItemTypePermissionUpdateOrPublish
2792
+ | RoleItemTypePermissionDuplicate
2793
+ | RoleItemTypePermissionDeleteOrEditCreatorOrTakeOver
2794
+ | RoleItemTypePermissionMoveToStage
2795
+ )[];
2502
2796
  /**
2503
- * Allowed actions on a model (or all) for a role
2797
+ * Allowed actions on uploads (or all) for a role.
2798
+ *
2799
+ * The shape of each entry depends on the `action` (discriminated union). To grant a subset, prefer a single `action: "all"` entry plus `negative_upload_permissions` entries for the actions to exclude.
2504
2800
  */
2505
- positive_upload_permissions: {
2506
- environment: EnvironmentIdentity;
2507
- /**
2508
- * Permitted action
2509
- */
2510
- action:
2511
- | 'all'
2512
- | 'read'
2513
- | 'update'
2514
- | 'create'
2515
- | 'delete'
2516
- | 'edit_creator'
2517
- | 'replace_asset'
2518
- | 'move';
2519
- /**
2520
- * Permitted creator
2521
- */
2522
- on_creator?: 'anyone' | 'self' | 'role' | null;
2523
- /**
2524
- * Permitted content scope
2525
- */
2526
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
2527
- /**
2528
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
2529
- */
2530
- locale?: string | null;
2531
- upload_collection?: UploadCollectionIdentity | null;
2532
- move_to_upload_collection?: UploadCollectionIdentity | null;
2533
- }[];
2801
+ positive_upload_permissions: (
2802
+ | RoleUploadPermissionAll
2803
+ | RoleUploadPermissionUpdate
2804
+ | RoleUploadPermissionCreate
2805
+ | RoleUploadPermissionReadOrDeleteOrEditCreatorOrReplaceAsset
2806
+ | RoleUploadPermissionMove
2807
+ )[];
2534
2808
  /**
2535
- * Prohibited actions on a model (or all) for a role
2809
+ * Prohibited actions on uploads (or all) for a role. Negative permissions take precedence and are typically paired with a broader positive `action: "all"` entry to subtract specific actions.
2536
2810
  */
2537
- negative_upload_permissions: {
2538
- environment: EnvironmentIdentity;
2539
- /**
2540
- * Permitted action
2541
- */
2542
- action:
2543
- | 'all'
2544
- | 'read'
2545
- | 'update'
2546
- | 'create'
2547
- | 'delete'
2548
- | 'edit_creator'
2549
- | 'replace_asset'
2550
- | 'move';
2551
- /**
2552
- * Permitted creator
2553
- */
2554
- on_creator?: 'anyone' | 'self' | 'role' | null;
2555
- /**
2556
- * Permitted content scope
2557
- */
2558
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
2559
- /**
2560
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
2561
- */
2562
- locale?: string | null;
2563
- upload_collection?: UploadCollectionIdentity | null;
2564
- move_to_upload_collection?: UploadCollectionIdentity | null;
2565
- }[];
2811
+ negative_upload_permissions: (
2812
+ | RoleUploadPermissionAll
2813
+ | RoleUploadPermissionUpdate
2814
+ | RoleUploadPermissionCreate
2815
+ | RoleUploadPermissionReadOrDeleteOrEditCreatorOrReplaceAsset
2816
+ | RoleUploadPermissionMove
2817
+ )[];
2566
2818
  /**
2567
- * Allowed build triggers for a role
2819
+ * Build triggers this role is allowed to **manually fire**. An entry with `build_trigger: null` covers every build trigger. Note: this does not control creating/editing build triggers themselves that is gated by `can_manage_build_triggers`.
2568
2820
  */
2569
2821
  positive_build_trigger_permissions: {
2570
2822
  build_trigger?: BuildTriggerIdentity | null;
2571
2823
  }[];
2572
2824
  /**
2573
- * Prohibited build triggers for a role
2825
+ * Build triggers this role is **forbidden** from manually firing. Negative entries take precedence over positive ones; pair with a `build_trigger: null` positive entry to allow all-but-N.
2574
2826
  */
2575
2827
  negative_build_trigger_permissions: {
2576
2828
  build_trigger?: BuildTriggerIdentity | null;
2577
2829
  }[];
2578
2830
  /**
2579
- * Search indexes that can be triggered by a role
2831
+ * Search indexes this role is allowed to **manually re-index**. An entry with `search_index: null` covers every search index. Note: this does not control creating/editing search indexes themselves — that is gated by `can_manage_search_indexes`.
2580
2832
  */
2581
2833
  positive_search_index_permissions: {
2582
2834
  search_index?: SearchIndexIdentity | null;
2583
2835
  }[];
2584
2836
  /**
2585
- * Search indexes that can't be triggered by a role
2837
+ * Search indexes this role is **forbidden** from manually re-indexing. Negative entries take precedence over positive ones; pair with a `search_index: null` positive entry to allow all-but-N.
2586
2838
  */
2587
2839
  negative_search_index_permissions: {
2588
2840
  search_index?: SearchIndexIdentity | null;
@@ -2605,11 +2857,11 @@ export type RoleAttributes = {
2605
2857
  */
2606
2858
  can_edit_favicon: boolean;
2607
2859
  /**
2608
- * Can change project global properties
2860
+ * Can change project-wide settings (project name, internal subdomain, frontend preview URL, deployment settings)
2609
2861
  */
2610
2862
  can_edit_site: boolean;
2611
2863
  /**
2612
- * Can create and edit models and plugins
2864
+ * Can create and edit the project schema: models, block models, fields, fieldsets, validators, and plugins
2613
2865
  */
2614
2866
  can_edit_schema: boolean;
2615
2867
  /**
@@ -2617,11 +2869,11 @@ export type RoleAttributes = {
2617
2869
  */
2618
2870
  can_manage_menu: boolean;
2619
2871
  /**
2620
- * Can change locales, timezone and UI theme
2872
+ * Can edit per-environment settings of the environments this role has access to: locales, timezone, and UI theme. This is *not* about creating or switching environments — see `can_manage_environments` for that, and `environments_access` for which environments this role can enter at all.
2621
2873
  */
2622
2874
  can_edit_environment: boolean;
2623
2875
  /**
2624
- * Can promote environments to primary and manage maintenance mode
2876
+ * Can promote a sandbox environment to primary (atomic swap) and toggle the project's maintenance mode. Distinct from `can_manage_environments`, which covers creating/forking/deleting sandboxes.
2625
2877
  */
2626
2878
  can_promote_environments: boolean;
2627
2879
  /**
@@ -2653,7 +2905,7 @@ export type RoleAttributes = {
2653
2905
  */
2654
2906
  can_manage_webhooks: boolean;
2655
2907
  /**
2656
- * Can create and delete sandbox environments and promote them to primary environment
2908
+ * Can create, fork, and delete sandbox environments. Promotion to primary is gated separately by `can_promote_environments`.
2657
2909
  */
2658
2910
  can_manage_environments: boolean;
2659
2911
  /**
@@ -2685,161 +2937,75 @@ export type RoleAttributes = {
2685
2937
  */
2686
2938
  can_access_search_index_events_log: boolean;
2687
2939
  /**
2688
- * Allowed actions on a model (or all) for a role
2689
- */
2690
- positive_item_type_permissions: {
2691
- item_type?: ItemTypeIdentity | null;
2692
- workflow?: WorkflowIdentity | null;
2693
- on_stage?: null | string;
2694
- to_stage?: null | string;
2695
- environment: EnvironmentIdentity;
2696
- /**
2697
- * Permitted action
2698
- */
2699
- action:
2700
- | 'all'
2701
- | 'read'
2702
- | 'update'
2703
- | 'create'
2704
- | 'duplicate'
2705
- | 'delete'
2706
- | 'publish'
2707
- | 'edit_creator'
2708
- | 'take_over'
2709
- | 'move_to_stage';
2710
- /**
2711
- * Permitted creator
2712
- */
2713
- on_creator?: 'anyone' | 'self' | 'role' | null;
2714
- /**
2715
- * Permitted content scope
2716
- */
2717
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
2718
- /**
2719
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
2720
- */
2721
- locale?: string | null;
2722
- }[];
2940
+ * Allowed actions on a model (or all) for a role.
2941
+ *
2942
+ * The shape of each entry depends on the `action` (discriminated union). Idiomatic recipes:
2943
+ * - To grant every action, use a single `action: "all"` entry with `localization_scope: "all"`.
2944
+ * - To grant a subset (e.g. create+read+update but not delete), prefer a single `action: "all"` entry plus `negative_item_type_permissions` entries for the actions to exclude — instead of listing each allowed action separately.
2945
+ */
2946
+ positive_item_type_permissions: (
2947
+ | RoleItemTypePermissionAll
2948
+ | RoleItemTypePermissionRead
2949
+ | RoleItemTypePermissionCreate
2950
+ | RoleItemTypePermissionUpdateOrPublish
2951
+ | RoleItemTypePermissionDuplicate
2952
+ | RoleItemTypePermissionDeleteOrEditCreatorOrTakeOver
2953
+ | RoleItemTypePermissionMoveToStage
2954
+ )[];
2723
2955
  /**
2724
- * Prohibited actions on a model (or all) for a role
2956
+ * Prohibited actions on a model (or all) for a role. Negative permissions take precedence and are typically paired with a broader positive `action: "all"` entry to subtract specific actions (e.g. forbid `delete`).
2725
2957
  */
2726
- negative_item_type_permissions: {
2727
- item_type?: ItemTypeIdentity | null;
2728
- workflow?: WorkflowIdentity | null;
2729
- on_stage?: null | string;
2730
- to_stage?: null | string;
2731
- environment: EnvironmentIdentity;
2732
- /**
2733
- * Permitted action
2734
- */
2735
- action:
2736
- | 'all'
2737
- | 'read'
2738
- | 'update'
2739
- | 'create'
2740
- | 'duplicate'
2741
- | 'delete'
2742
- | 'publish'
2743
- | 'edit_creator'
2744
- | 'take_over'
2745
- | 'move_to_stage';
2746
- /**
2747
- * Permitted creator
2748
- */
2749
- on_creator?: 'anyone' | 'self' | 'role' | null;
2750
- /**
2751
- * Permitted content scope
2752
- */
2753
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
2754
- /**
2755
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
2756
- */
2757
- locale?: string | null;
2758
- }[];
2958
+ negative_item_type_permissions: (
2959
+ | RoleItemTypePermissionAll
2960
+ | RoleItemTypePermissionRead
2961
+ | RoleItemTypePermissionCreate
2962
+ | RoleItemTypePermissionUpdateOrPublish
2963
+ | RoleItemTypePermissionDuplicate
2964
+ | RoleItemTypePermissionDeleteOrEditCreatorOrTakeOver
2965
+ | RoleItemTypePermissionMoveToStage
2966
+ )[];
2759
2967
  /**
2760
- * Allowed actions on a model (or all) for a role
2968
+ * Allowed actions on uploads (or all) for a role.
2969
+ *
2970
+ * The shape of each entry depends on the `action` (discriminated union). To grant a subset, prefer a single `action: "all"` entry plus `negative_upload_permissions` entries for the actions to exclude.
2761
2971
  */
2762
- positive_upload_permissions: {
2763
- environment: EnvironmentIdentity;
2764
- /**
2765
- * Permitted action
2766
- */
2767
- action:
2768
- | 'all'
2769
- | 'read'
2770
- | 'update'
2771
- | 'create'
2772
- | 'delete'
2773
- | 'edit_creator'
2774
- | 'replace_asset'
2775
- | 'move';
2776
- /**
2777
- * Permitted creator
2778
- */
2779
- on_creator?: 'anyone' | 'self' | 'role' | null;
2780
- /**
2781
- * Permitted content scope
2782
- */
2783
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
2784
- /**
2785
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
2786
- */
2787
- locale?: string | null;
2788
- upload_collection?: UploadCollectionIdentity | null;
2789
- move_to_upload_collection?: UploadCollectionIdentity | null;
2790
- }[];
2972
+ positive_upload_permissions: (
2973
+ | RoleUploadPermissionAll
2974
+ | RoleUploadPermissionUpdate
2975
+ | RoleUploadPermissionCreate
2976
+ | RoleUploadPermissionReadOrDeleteOrEditCreatorOrReplaceAsset
2977
+ | RoleUploadPermissionMove
2978
+ )[];
2791
2979
  /**
2792
- * Prohibited actions on a model (or all) for a role
2980
+ * Prohibited actions on uploads (or all) for a role. Negative permissions take precedence and are typically paired with a broader positive `action: "all"` entry to subtract specific actions.
2793
2981
  */
2794
- negative_upload_permissions: {
2795
- environment: EnvironmentIdentity;
2796
- /**
2797
- * Permitted action
2798
- */
2799
- action:
2800
- | 'all'
2801
- | 'read'
2802
- | 'update'
2803
- | 'create'
2804
- | 'delete'
2805
- | 'edit_creator'
2806
- | 'replace_asset'
2807
- | 'move';
2808
- /**
2809
- * Permitted creator
2810
- */
2811
- on_creator?: 'anyone' | 'self' | 'role' | null;
2812
- /**
2813
- * Permitted content scope
2814
- */
2815
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
2816
- /**
2817
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
2818
- */
2819
- locale?: string | null;
2820
- upload_collection?: UploadCollectionIdentity | null;
2821
- move_to_upload_collection?: UploadCollectionIdentity | null;
2822
- }[];
2982
+ negative_upload_permissions: (
2983
+ | RoleUploadPermissionAll
2984
+ | RoleUploadPermissionUpdate
2985
+ | RoleUploadPermissionCreate
2986
+ | RoleUploadPermissionReadOrDeleteOrEditCreatorOrReplaceAsset
2987
+ | RoleUploadPermissionMove
2988
+ )[];
2823
2989
  /**
2824
- * Allowed build triggers for a role
2990
+ * Build triggers this role is allowed to **manually fire**. An entry with `build_trigger: null` covers every build trigger. Note: this does not control creating/editing build triggers themselves that is gated by `can_manage_build_triggers`.
2825
2991
  */
2826
2992
  positive_build_trigger_permissions: {
2827
2993
  build_trigger?: BuildTriggerIdentity | null;
2828
2994
  }[];
2829
2995
  /**
2830
- * Prohibited build triggers for a role
2996
+ * Build triggers this role is **forbidden** from manually firing. Negative entries take precedence over positive ones; pair with a `build_trigger: null` positive entry to allow all-but-N.
2831
2997
  */
2832
2998
  negative_build_trigger_permissions: {
2833
2999
  build_trigger?: BuildTriggerIdentity | null;
2834
3000
  }[];
2835
3001
  /**
2836
- * Search indexes that can be triggered by a role
3002
+ * Search indexes this role is allowed to **manually re-index**. An entry with `search_index: null` covers every search index. Note: this does not control creating/editing search indexes themselves — that is gated by `can_manage_search_indexes`.
2837
3003
  */
2838
3004
  positive_search_index_permissions: {
2839
3005
  search_index?: SearchIndexIdentity | null;
2840
3006
  }[];
2841
3007
  /**
2842
- * Search indexes that can't be triggered by a role
3008
+ * Search indexes this role is **forbidden** from manually re-indexing. Negative entries take precedence over positive ones; pair with a `search_index: null` positive entry to allow all-but-N.
2843
3009
  */
2844
3010
  negative_search_index_permissions: {
2845
3011
  search_index?: SearchIndexIdentity | null;
@@ -2869,11 +3035,11 @@ export type RoleCreateSchema = {
2869
3035
  */
2870
3036
  can_edit_favicon?: boolean;
2871
3037
  /**
2872
- * Can change project global properties
3038
+ * Can change project-wide settings (project name, internal subdomain, frontend preview URL, deployment settings)
2873
3039
  */
2874
3040
  can_edit_site?: boolean;
2875
3041
  /**
2876
- * Can create and edit models and plugins
3042
+ * Can create and edit the project schema: models, block models, fields, fieldsets, validators, and plugins
2877
3043
  */
2878
3044
  can_edit_schema?: boolean;
2879
3045
  /**
@@ -2881,11 +3047,11 @@ export type RoleCreateSchema = {
2881
3047
  */
2882
3048
  can_manage_menu?: boolean;
2883
3049
  /**
2884
- * Can change locales, timezone and UI theme
3050
+ * Can edit per-environment settings of the environments this role has access to: locales, timezone, and UI theme. This is *not* about creating or switching environments — see `can_manage_environments` for that, and `environments_access` for which environments this role can enter at all.
2885
3051
  */
2886
3052
  can_edit_environment?: boolean;
2887
3053
  /**
2888
- * Can promote environments to primary and manage maintenance mode
3054
+ * Can promote a sandbox environment to primary (atomic swap) and toggle the project's maintenance mode. Distinct from `can_manage_environments`, which covers creating/forking/deleting sandboxes.
2889
3055
  */
2890
3056
  can_promote_environments?: boolean;
2891
3057
  /**
@@ -2917,7 +3083,7 @@ export type RoleCreateSchema = {
2917
3083
  */
2918
3084
  can_manage_webhooks?: boolean;
2919
3085
  /**
2920
- * Can create and delete sandbox environments and promote them to primary environment
3086
+ * Can create, fork, and delete sandbox environments. Promotion to primary is gated separately by `can_promote_environments`.
2921
3087
  */
2922
3088
  can_manage_environments?: boolean;
2923
3089
  /**
@@ -2949,161 +3115,75 @@ export type RoleCreateSchema = {
2949
3115
  */
2950
3116
  can_access_search_index_events_log?: boolean;
2951
3117
  /**
2952
- * Allowed actions on a model (or all) for a role
2953
- */
2954
- positive_item_type_permissions?: {
2955
- item_type?: ItemTypeIdentity | null;
2956
- workflow?: WorkflowIdentity | null;
2957
- on_stage?: null | string;
2958
- to_stage?: null | string;
2959
- environment: EnvironmentIdentity;
2960
- /**
2961
- * Permitted action
2962
- */
2963
- action:
2964
- | 'all'
2965
- | 'read'
2966
- | 'update'
2967
- | 'create'
2968
- | 'duplicate'
2969
- | 'delete'
2970
- | 'publish'
2971
- | 'edit_creator'
2972
- | 'take_over'
2973
- | 'move_to_stage';
2974
- /**
2975
- * Permitted creator
2976
- */
2977
- on_creator?: 'anyone' | 'self' | 'role' | null;
2978
- /**
2979
- * Permitted content scope
2980
- */
2981
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
2982
- /**
2983
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
2984
- */
2985
- locale?: string | null;
2986
- }[];
3118
+ * Allowed actions on a model (or all) for a role.
3119
+ *
3120
+ * The shape of each entry depends on the `action` (discriminated union). Idiomatic recipes:
3121
+ * - To grant every action, use a single `action: "all"` entry with `localization_scope: "all"`.
3122
+ * - To grant a subset (e.g. create+read+update but not delete), prefer a single `action: "all"` entry plus `negative_item_type_permissions` entries for the actions to exclude — instead of listing each allowed action separately.
3123
+ */
3124
+ positive_item_type_permissions?: (
3125
+ | RoleItemTypePermissionAll
3126
+ | RoleItemTypePermissionRead
3127
+ | RoleItemTypePermissionCreate
3128
+ | RoleItemTypePermissionUpdateOrPublish
3129
+ | RoleItemTypePermissionDuplicate
3130
+ | RoleItemTypePermissionDeleteOrEditCreatorOrTakeOver
3131
+ | RoleItemTypePermissionMoveToStage
3132
+ )[];
2987
3133
  /**
2988
- * Prohibited actions on a model (or all) for a role
3134
+ * Prohibited actions on a model (or all) for a role. Negative permissions take precedence and are typically paired with a broader positive `action: "all"` entry to subtract specific actions (e.g. forbid `delete`).
2989
3135
  */
2990
- negative_item_type_permissions?: {
2991
- item_type?: ItemTypeIdentity | null;
2992
- workflow?: WorkflowIdentity | null;
2993
- on_stage?: null | string;
2994
- to_stage?: null | string;
2995
- environment: EnvironmentIdentity;
2996
- /**
2997
- * Permitted action
2998
- */
2999
- action:
3000
- | 'all'
3001
- | 'read'
3002
- | 'update'
3003
- | 'create'
3004
- | 'duplicate'
3005
- | 'delete'
3006
- | 'publish'
3007
- | 'edit_creator'
3008
- | 'take_over'
3009
- | 'move_to_stage';
3010
- /**
3011
- * Permitted creator
3012
- */
3013
- on_creator?: 'anyone' | 'self' | 'role' | null;
3014
- /**
3015
- * Permitted content scope
3016
- */
3017
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
3018
- /**
3019
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
3020
- */
3021
- locale?: string | null;
3022
- }[];
3136
+ negative_item_type_permissions?: (
3137
+ | RoleItemTypePermissionAll
3138
+ | RoleItemTypePermissionRead
3139
+ | RoleItemTypePermissionCreate
3140
+ | RoleItemTypePermissionUpdateOrPublish
3141
+ | RoleItemTypePermissionDuplicate
3142
+ | RoleItemTypePermissionDeleteOrEditCreatorOrTakeOver
3143
+ | RoleItemTypePermissionMoveToStage
3144
+ )[];
3023
3145
  /**
3024
- * Allowed actions on a model (or all) for a role
3146
+ * Allowed actions on uploads (or all) for a role.
3147
+ *
3148
+ * The shape of each entry depends on the `action` (discriminated union). To grant a subset, prefer a single `action: "all"` entry plus `negative_upload_permissions` entries for the actions to exclude.
3025
3149
  */
3026
- positive_upload_permissions?: {
3027
- environment: EnvironmentIdentity;
3028
- /**
3029
- * Permitted action
3030
- */
3031
- action:
3032
- | 'all'
3033
- | 'read'
3034
- | 'update'
3035
- | 'create'
3036
- | 'delete'
3037
- | 'edit_creator'
3038
- | 'replace_asset'
3039
- | 'move';
3040
- /**
3041
- * Permitted creator
3042
- */
3043
- on_creator?: 'anyone' | 'self' | 'role' | null;
3044
- /**
3045
- * Permitted content scope
3046
- */
3047
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
3048
- /**
3049
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
3050
- */
3051
- locale?: string | null;
3052
- upload_collection?: UploadCollectionIdentity | null;
3053
- move_to_upload_collection?: UploadCollectionIdentity | null;
3054
- }[];
3150
+ positive_upload_permissions?: (
3151
+ | RoleUploadPermissionAll
3152
+ | RoleUploadPermissionUpdate
3153
+ | RoleUploadPermissionCreate
3154
+ | RoleUploadPermissionReadOrDeleteOrEditCreatorOrReplaceAsset
3155
+ | RoleUploadPermissionMove
3156
+ )[];
3055
3157
  /**
3056
- * Prohibited actions on a model (or all) for a role
3158
+ * Prohibited actions on uploads (or all) for a role. Negative permissions take precedence and are typically paired with a broader positive `action: "all"` entry to subtract specific actions.
3057
3159
  */
3058
- negative_upload_permissions?: {
3059
- environment: EnvironmentIdentity;
3060
- /**
3061
- * Permitted action
3062
- */
3063
- action:
3064
- | 'all'
3065
- | 'read'
3066
- | 'update'
3067
- | 'create'
3068
- | 'delete'
3069
- | 'edit_creator'
3070
- | 'replace_asset'
3071
- | 'move';
3072
- /**
3073
- * Permitted creator
3074
- */
3075
- on_creator?: 'anyone' | 'self' | 'role' | null;
3076
- /**
3077
- * Permitted content scope
3078
- */
3079
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
3080
- /**
3081
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
3082
- */
3083
- locale?: string | null;
3084
- upload_collection?: UploadCollectionIdentity | null;
3085
- move_to_upload_collection?: UploadCollectionIdentity | null;
3086
- }[];
3160
+ negative_upload_permissions?: (
3161
+ | RoleUploadPermissionAll
3162
+ | RoleUploadPermissionUpdate
3163
+ | RoleUploadPermissionCreate
3164
+ | RoleUploadPermissionReadOrDeleteOrEditCreatorOrReplaceAsset
3165
+ | RoleUploadPermissionMove
3166
+ )[];
3087
3167
  /**
3088
- * Allowed build triggers for a role
3168
+ * Build triggers this role is allowed to **manually fire**. An entry with `build_trigger: null` covers every build trigger. Note: this does not control creating/editing build triggers themselves that is gated by `can_manage_build_triggers`.
3089
3169
  */
3090
3170
  positive_build_trigger_permissions?: {
3091
3171
  build_trigger?: BuildTriggerIdentity | null;
3092
3172
  }[];
3093
3173
  /**
3094
- * Prohibited build triggers for a role
3174
+ * Build triggers this role is **forbidden** from manually firing. Negative entries take precedence over positive ones; pair with a `build_trigger: null` positive entry to allow all-but-N.
3095
3175
  */
3096
3176
  negative_build_trigger_permissions?: {
3097
3177
  build_trigger?: BuildTriggerIdentity | null;
3098
3178
  }[];
3099
3179
  /**
3100
- * Search indexes that can be triggered by a role
3180
+ * Search indexes this role is allowed to **manually re-index**. An entry with `search_index: null` covers every search index. Note: this does not control creating/editing search indexes themselves — that is gated by `can_manage_search_indexes`.
3101
3181
  */
3102
3182
  positive_search_index_permissions?: {
3103
3183
  search_index?: SearchIndexIdentity | null;
3104
3184
  }[];
3105
3185
  /**
3106
- * Search indexes that can't be triggered by a role
3186
+ * Search indexes this role is **forbidden** from manually re-indexing. Negative entries take precedence over positive ones; pair with a `search_index: null` positive entry to allow all-but-N.
3107
3187
  */
3108
3188
  negative_search_index_permissions?: {
3109
3189
  search_index?: SearchIndexIdentity | null;
@@ -3127,11 +3207,11 @@ export type RoleUpdateSchema = {
3127
3207
  */
3128
3208
  can_edit_favicon?: boolean;
3129
3209
  /**
3130
- * Can change project global properties
3210
+ * Can change project-wide settings (project name, internal subdomain, frontend preview URL, deployment settings)
3131
3211
  */
3132
3212
  can_edit_site?: boolean;
3133
3213
  /**
3134
- * Can create and edit models and plugins
3214
+ * Can create and edit the project schema: models, block models, fields, fieldsets, validators, and plugins
3135
3215
  */
3136
3216
  can_edit_schema?: boolean;
3137
3217
  /**
@@ -3139,11 +3219,11 @@ export type RoleUpdateSchema = {
3139
3219
  */
3140
3220
  can_manage_menu?: boolean;
3141
3221
  /**
3142
- * Can change locales, timezone and UI theme
3222
+ * Can edit per-environment settings of the environments this role has access to: locales, timezone, and UI theme. This is *not* about creating or switching environments — see `can_manage_environments` for that, and `environments_access` for which environments this role can enter at all.
3143
3223
  */
3144
3224
  can_edit_environment?: boolean;
3145
3225
  /**
3146
- * Can promote environments to primary and manage maintenance mode
3226
+ * Can promote a sandbox environment to primary (atomic swap) and toggle the project's maintenance mode. Distinct from `can_manage_environments`, which covers creating/forking/deleting sandboxes.
3147
3227
  */
3148
3228
  can_promote_environments?: boolean;
3149
3229
  /**
@@ -3175,7 +3255,7 @@ export type RoleUpdateSchema = {
3175
3255
  */
3176
3256
  can_manage_webhooks?: boolean;
3177
3257
  /**
3178
- * Can create and delete sandbox environments and promote them to primary environment
3258
+ * Can create, fork, and delete sandbox environments. Promotion to primary is gated separately by `can_promote_environments`.
3179
3259
  */
3180
3260
  can_manage_environments?: boolean;
3181
3261
  /**
@@ -3207,161 +3287,75 @@ export type RoleUpdateSchema = {
3207
3287
  */
3208
3288
  can_access_search_index_events_log?: boolean;
3209
3289
  /**
3210
- * Allowed actions on a model (or all) for a role
3211
- */
3212
- positive_item_type_permissions?: {
3213
- item_type?: ItemTypeIdentity | null;
3214
- workflow?: WorkflowIdentity | null;
3215
- on_stage?: null | string;
3216
- to_stage?: null | string;
3217
- environment: EnvironmentIdentity;
3218
- /**
3219
- * Permitted action
3220
- */
3221
- action:
3222
- | 'all'
3223
- | 'read'
3224
- | 'update'
3225
- | 'create'
3226
- | 'duplicate'
3227
- | 'delete'
3228
- | 'publish'
3229
- | 'edit_creator'
3230
- | 'take_over'
3231
- | 'move_to_stage';
3232
- /**
3233
- * Permitted creator
3234
- */
3235
- on_creator?: 'anyone' | 'self' | 'role' | null;
3236
- /**
3237
- * Permitted content scope
3238
- */
3239
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
3240
- /**
3241
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
3242
- */
3243
- locale?: string | null;
3244
- }[];
3290
+ * Allowed actions on a model (or all) for a role.
3291
+ *
3292
+ * The shape of each entry depends on the `action` (discriminated union). Idiomatic recipes:
3293
+ * - To grant every action, use a single `action: "all"` entry with `localization_scope: "all"`.
3294
+ * - To grant a subset (e.g. create+read+update but not delete), prefer a single `action: "all"` entry plus `negative_item_type_permissions` entries for the actions to exclude — instead of listing each allowed action separately.
3295
+ */
3296
+ positive_item_type_permissions?: (
3297
+ | RoleItemTypePermissionAll
3298
+ | RoleItemTypePermissionRead
3299
+ | RoleItemTypePermissionCreate
3300
+ | RoleItemTypePermissionUpdateOrPublish
3301
+ | RoleItemTypePermissionDuplicate
3302
+ | RoleItemTypePermissionDeleteOrEditCreatorOrTakeOver
3303
+ | RoleItemTypePermissionMoveToStage
3304
+ )[];
3245
3305
  /**
3246
- * Prohibited actions on a model (or all) for a role
3306
+ * Prohibited actions on a model (or all) for a role. Negative permissions take precedence and are typically paired with a broader positive `action: "all"` entry to subtract specific actions (e.g. forbid `delete`).
3247
3307
  */
3248
- negative_item_type_permissions?: {
3249
- item_type?: ItemTypeIdentity | null;
3250
- workflow?: WorkflowIdentity | null;
3251
- on_stage?: null | string;
3252
- to_stage?: null | string;
3253
- environment: EnvironmentIdentity;
3254
- /**
3255
- * Permitted action
3256
- */
3257
- action:
3258
- | 'all'
3259
- | 'read'
3260
- | 'update'
3261
- | 'create'
3262
- | 'duplicate'
3263
- | 'delete'
3264
- | 'publish'
3265
- | 'edit_creator'
3266
- | 'take_over'
3267
- | 'move_to_stage';
3268
- /**
3269
- * Permitted creator
3270
- */
3271
- on_creator?: 'anyone' | 'self' | 'role' | null;
3272
- /**
3273
- * Permitted content scope
3274
- */
3275
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
3276
- /**
3277
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
3278
- */
3279
- locale?: string | null;
3280
- }[];
3308
+ negative_item_type_permissions?: (
3309
+ | RoleItemTypePermissionAll
3310
+ | RoleItemTypePermissionRead
3311
+ | RoleItemTypePermissionCreate
3312
+ | RoleItemTypePermissionUpdateOrPublish
3313
+ | RoleItemTypePermissionDuplicate
3314
+ | RoleItemTypePermissionDeleteOrEditCreatorOrTakeOver
3315
+ | RoleItemTypePermissionMoveToStage
3316
+ )[];
3281
3317
  /**
3282
- * Allowed actions on a model (or all) for a role
3318
+ * Allowed actions on uploads (or all) for a role.
3319
+ *
3320
+ * The shape of each entry depends on the `action` (discriminated union). To grant a subset, prefer a single `action: "all"` entry plus `negative_upload_permissions` entries for the actions to exclude.
3283
3321
  */
3284
- positive_upload_permissions?: {
3285
- environment: EnvironmentIdentity;
3286
- /**
3287
- * Permitted action
3288
- */
3289
- action:
3290
- | 'all'
3291
- | 'read'
3292
- | 'update'
3293
- | 'create'
3294
- | 'delete'
3295
- | 'edit_creator'
3296
- | 'replace_asset'
3297
- | 'move';
3298
- /**
3299
- * Permitted creator
3300
- */
3301
- on_creator?: 'anyone' | 'self' | 'role' | null;
3302
- /**
3303
- * Permitted content scope
3304
- */
3305
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
3306
- /**
3307
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
3308
- */
3309
- locale?: string | null;
3310
- upload_collection?: UploadCollectionIdentity | null;
3311
- move_to_upload_collection?: UploadCollectionIdentity | null;
3312
- }[];
3322
+ positive_upload_permissions?: (
3323
+ | RoleUploadPermissionAll
3324
+ | RoleUploadPermissionUpdate
3325
+ | RoleUploadPermissionCreate
3326
+ | RoleUploadPermissionReadOrDeleteOrEditCreatorOrReplaceAsset
3327
+ | RoleUploadPermissionMove
3328
+ )[];
3313
3329
  /**
3314
- * Prohibited actions on a model (or all) for a role
3330
+ * Prohibited actions on uploads (or all) for a role. Negative permissions take precedence and are typically paired with a broader positive `action: "all"` entry to subtract specific actions.
3315
3331
  */
3316
- negative_upload_permissions?: {
3317
- environment: EnvironmentIdentity;
3318
- /**
3319
- * Permitted action
3320
- */
3321
- action:
3322
- | 'all'
3323
- | 'read'
3324
- | 'update'
3325
- | 'create'
3326
- | 'delete'
3327
- | 'edit_creator'
3328
- | 'replace_asset'
3329
- | 'move';
3330
- /**
3331
- * Permitted creator
3332
- */
3333
- on_creator?: 'anyone' | 'self' | 'role' | null;
3334
- /**
3335
- * Permitted content scope
3336
- */
3337
- localization_scope?: 'all' | 'localized' | 'not_localized' | null;
3338
- /**
3339
- * Permitted localized content in this locale. Required when `localization_scope` is `localized`
3340
- */
3341
- locale?: string | null;
3342
- upload_collection?: UploadCollectionIdentity | null;
3343
- move_to_upload_collection?: UploadCollectionIdentity | null;
3344
- }[];
3332
+ negative_upload_permissions?: (
3333
+ | RoleUploadPermissionAll
3334
+ | RoleUploadPermissionUpdate
3335
+ | RoleUploadPermissionCreate
3336
+ | RoleUploadPermissionReadOrDeleteOrEditCreatorOrReplaceAsset
3337
+ | RoleUploadPermissionMove
3338
+ )[];
3345
3339
  /**
3346
- * Allowed build triggers for a role
3340
+ * Build triggers this role is allowed to **manually fire**. An entry with `build_trigger: null` covers every build trigger. Note: this does not control creating/editing build triggers themselves that is gated by `can_manage_build_triggers`.
3347
3341
  */
3348
3342
  positive_build_trigger_permissions?: {
3349
3343
  build_trigger?: BuildTriggerIdentity | null;
3350
3344
  }[];
3351
3345
  /**
3352
- * Prohibited build triggers for a role
3346
+ * Build triggers this role is **forbidden** from manually firing. Negative entries take precedence over positive ones; pair with a `build_trigger: null` positive entry to allow all-but-N.
3353
3347
  */
3354
3348
  negative_build_trigger_permissions?: {
3355
3349
  build_trigger?: BuildTriggerIdentity | null;
3356
3350
  }[];
3357
3351
  /**
3358
- * Search indexes that can be triggered by a role
3352
+ * Search indexes this role is allowed to **manually re-index**. An entry with `search_index: null` covers every search index. Note: this does not control creating/editing search indexes themselves — that is gated by `can_manage_search_indexes`.
3359
3353
  */
3360
3354
  positive_search_index_permissions?: {
3361
3355
  search_index?: SearchIndexIdentity | null;
3362
3356
  }[];
3363
3357
  /**
3364
- * Search indexes that can't be triggered by a role
3358
+ * Search indexes this role is **forbidden** from manually re-indexing. Negative entries take precedence over positive ones; pair with a `search_index: null` positive entry to allow all-but-N.
3365
3359
  */
3366
3360
  negative_search_index_permissions?: {
3367
3361
  search_index?: SearchIndexIdentity | null;
@@ -3574,7 +3568,16 @@ export type SsoUserRelationships = {
3574
3568
  role: RoleData | null;
3575
3569
  };
3576
3570
  /**
3577
- * An API token allows access to our API. It is linked to a Role, which describes what actions can be performed.
3571
+ * An API token authenticates programmatic access to a project. Each token combines two layers of access control:
3572
+ *
3573
+ * 1. A **Role** that defines what actions are permitted (the same Role resource used for human collaborators).
3574
+ * 2. A set of **API surface flags** (`can_access_cda`, `can_access_cda_preview`, `can_access_cma`) that gate which APIs the token can hit at all.
3575
+ *
3576
+ * The token's effective capabilities are the *intersection* of the two.
3577
+ *
3578
+ * > [!PROTIP] 💡 A CDA-only token can safely reuse a write-capable Role
3579
+ * > A token with only `can_access_cda: true` is safe to attach to a Role that grants `update`/`publish`/`delete` — the Content Delivery API exposes no write endpoints, so those actions have no surface to act on. This makes it practical to share a single Role definition between an editor (acting via the dashboard / CMA) and a public read token (used by a frontend / CDA) for the same project.
3580
+ *
3578
3581
  *
3579
3582
  * This interface was referenced by `DatoApi`'s JSON-Schema
3580
3583
  * via the `definition` "access_token".
@@ -3587,21 +3590,24 @@ export type AccessToken = {
3587
3590
  */
3588
3591
  name: string;
3589
3592
  /**
3590
- * The actual API token (or null if the current user has no permission to read the token)
3593
+ * The secret value used as the `Authorization: Bearer <token>` credential. Returned on every endpoint (create, update, retrieve, list, rotate) to callers whose current role has `can_manage_access_tokens`; otherwise `null`.
3591
3594
  */
3592
3595
  token?: null | string;
3593
3596
  /**
3594
- * Whether this API token can access the Content Delivery API published content endpoint
3597
+ * Whether this API token can call the Content Delivery API (`graphql.datocms.com`) to fetch **published** content.
3595
3598
  */
3596
3599
  can_access_cda: boolean;
3597
3600
  /**
3598
- * Whether this API token can access the Content Delivery API draft content endpoint
3601
+ * Whether this API token can call the Content Delivery API with the `X-Include-Drafts: true` header to fetch **draft** (current, unpublished) content. There is no separate endpoint — the CDA is a single GraphQL endpoint and this flag governs whether requesting drafts is allowed.
3599
3602
  */
3600
3603
  can_access_cda_preview: boolean;
3601
3604
  /**
3602
3605
  * Whether this API token can access the Content Management API
3603
3606
  */
3604
3607
  can_access_cma: boolean;
3608
+ /**
3609
+ * Internal marker for the project's built-in factory tokens (e.g. read-only API token), seeded by DatoCMS when the project is created. Read-only attribute. When non-null, attribute updates are rejected with `NON_EDITABLE_ACCESS_TOKEN`, but the token can still be deleted and regenerated. `null` for any token created via this API.
3610
+ */
3605
3611
  hardcoded_type: null | string;
3606
3612
  /**
3607
3613
  * When this API token was last used to access the Content Management API
@@ -3654,21 +3660,24 @@ export type AccessTokenAttributes = {
3654
3660
  */
3655
3661
  name: string;
3656
3662
  /**
3657
- * The actual API token (or null if the current user has no permission to read the token)
3663
+ * The secret value used as the `Authorization: Bearer <token>` credential. Returned on every endpoint (create, update, retrieve, list, rotate) to callers whose current role has `can_manage_access_tokens`; otherwise `null`.
3658
3664
  */
3659
3665
  token?: null | string;
3660
3666
  /**
3661
- * Whether this API token can access the Content Delivery API published content endpoint
3667
+ * Whether this API token can call the Content Delivery API (`graphql.datocms.com`) to fetch **published** content.
3662
3668
  */
3663
3669
  can_access_cda: boolean;
3664
3670
  /**
3665
- * Whether this API token can access the Content Delivery API draft content endpoint
3671
+ * Whether this API token can call the Content Delivery API with the `X-Include-Drafts: true` header to fetch **draft** (current, unpublished) content. There is no separate endpoint — the CDA is a single GraphQL endpoint and this flag governs whether requesting drafts is allowed.
3666
3672
  */
3667
3673
  can_access_cda_preview: boolean;
3668
3674
  /**
3669
3675
  * Whether this API token can access the Content Management API
3670
3676
  */
3671
3677
  can_access_cma: boolean;
3678
+ /**
3679
+ * Internal marker for the project's built-in factory tokens (e.g. read-only API token), seeded by DatoCMS when the project is created. Read-only attribute. When non-null, attribute updates are rejected with `NON_EDITABLE_ACCESS_TOKEN`, but the token can still be deleted and regenerated. `null` for any token created via this API.
3680
+ */
3672
3681
  hardcoded_type: null | string;
3673
3682
  /**
3674
3683
  * When this API token was last used to access the Content Management API
@@ -3713,18 +3722,18 @@ export type AccessTokenCreateSchema = {
3713
3722
  */
3714
3723
  name: string;
3715
3724
  /**
3716
- * Whether this API token can access the Content Delivery API published content endpoint
3725
+ * Whether this API token can call the Content Delivery API (`graphql.datocms.com`) to fetch **published** content.
3717
3726
  */
3718
3727
  can_access_cda: boolean;
3719
3728
  /**
3720
- * Whether this API token can access the Content Delivery API draft content endpoint
3729
+ * Whether this API token can call the Content Delivery API with the `X-Include-Drafts: true` header to fetch **draft** (current, unpublished) content. There is no separate endpoint — the CDA is a single GraphQL endpoint and this flag governs whether requesting drafts is allowed.
3721
3730
  */
3722
3731
  can_access_cda_preview: boolean;
3723
3732
  /**
3724
3733
  * Whether this API token can access the Content Management API
3725
3734
  */
3726
3735
  can_access_cma: boolean;
3727
- role: RoleData | null;
3736
+ role: RoleData;
3728
3737
  };
3729
3738
  /**
3730
3739
  * This interface was referenced by `AccessToken`'s JSON-Schema
@@ -3738,18 +3747,18 @@ export type AccessTokenUpdateSchema = {
3738
3747
  */
3739
3748
  name: string;
3740
3749
  /**
3741
- * Whether this API token can access the Content Delivery API published content endpoint
3750
+ * Whether this API token can call the Content Delivery API (`graphql.datocms.com`) to fetch **published** content.
3742
3751
  */
3743
3752
  can_access_cda: boolean;
3744
3753
  /**
3745
- * Whether this API token can access the Content Delivery API draft content endpoint
3754
+ * Whether this API token can call the Content Delivery API with the `X-Include-Drafts: true` header to fetch **draft** (current, unpublished) content. There is no separate endpoint — the CDA is a single GraphQL endpoint and this flag governs whether requesting drafts is allowed.
3746
3755
  */
3747
3756
  can_access_cda_preview: boolean;
3748
3757
  /**
3749
3758
  * Whether this API token can access the Content Management API
3750
3759
  */
3751
3760
  can_access_cma: boolean;
3752
- role: RoleData | null;
3761
+ role?: RoleData;
3753
3762
  };
3754
3763
  /**
3755
3764
  * DatoCMS account