@fleetless/contracts 6.0.0 → 6.1.0-next.2

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/artifacts/openapi.json +692 -1
  3. package/artifacts/routes.json +101 -0
  4. package/artifacts/schema/addon-catalogue-entry.schema.json +81 -0
  5. package/artifacts/schema/addon-key.schema.json +11 -0
  6. package/artifacts/schema/admin-plan-change-request.schema.json +189 -0
  7. package/artifacts/schema/asset-plan-limit-details.schema.json +115 -0
  8. package/artifacts/schema/audit-actor.schema.json +2 -1
  9. package/artifacts/schema/audit-event.schema.json +2 -1
  10. package/artifacts/schema/audit-list-response.schema.json +2 -1
  11. package/artifacts/schema/org-addons.schema.json +44 -0
  12. package/artifacts/schema/org-lock.schema.json +25 -0
  13. package/artifacts/schema/org-locked-details.schema.json +18 -0
  14. package/artifacts/schema/org-plan-usage.schema.json +51 -0
  15. package/artifacts/schema/org-plan.schema.json +500 -0
  16. package/artifacts/schema/pending-plan-change.schema.json +123 -0
  17. package/artifacts/schema/plan-catalogue-entry.schema.json +249 -0
  18. package/artifacts/schema/plan-change-keep.schema.json +49 -0
  19. package/artifacts/schema/plan-change-reason.schema.json +10 -0
  20. package/artifacts/schema/plan-change-request.schema.json +77 -0
  21. package/artifacts/schema/plan-currency.schema.json +8 -0
  22. package/artifacts/schema/plan-features.schema.json +44 -0
  23. package/artifacts/schema/plan-id.schema.json +10 -0
  24. package/artifacts/schema/plan-limit-details.schema.json +94 -0
  25. package/artifacts/schema/plan-limits.schema.json +121 -0
  26. package/artifacts/schema/plan-overrides.schema.json +111 -0
  27. package/artifacts/schema/plan-prices.schema.json +37 -0
  28. package/artifacts/schema/plan-required-details.schema.json +45 -0
  29. package/dist/audit.d.ts +10 -0
  30. package/dist/audit.js +8 -1
  31. package/dist/errors.d.ts +138 -1
  32. package/dist/errors.js +104 -0
  33. package/dist/index.d.ts +6 -2
  34. package/dist/index.js +11 -1
  35. package/dist/plans.d.ts +507 -0
  36. package/dist/plans.js +487 -0
  37. package/dist/realtime.d.ts +2 -0
  38. package/dist/realtime.js +6 -0
  39. package/dist/routes.d.ts +5 -1
  40. package/dist/routes.js +59 -0
  41. package/package.json +1 -1
@@ -9450,6 +9450,121 @@
9450
9450
  }
9451
9451
  }
9452
9452
  }
9453
+ },
9454
+ "/api/org/plan": {
9455
+ "get": {
9456
+ "operationId": "get_api_org_plan",
9457
+ "summary": "Reads the org's plan: its limits, its usage against them, its add-ons and any change already queued.",
9458
+ "tags": [
9459
+ "org"
9460
+ ],
9461
+ "security": [
9462
+ {
9463
+ "developerSession": []
9464
+ }
9465
+ ],
9466
+ "parameters": [],
9467
+ "responses": {
9468
+ "200": {
9469
+ "description": "Success.",
9470
+ "content": {
9471
+ "application/json": {
9472
+ "schema": {
9473
+ "$ref": "#/components/schemas/org-plan"
9474
+ }
9475
+ }
9476
+ }
9477
+ },
9478
+ "default": {
9479
+ "description": "An error envelope. Codes this route is known to answer: `unauthorized`, `token_expired`, `token_revoked`.",
9480
+ "content": {
9481
+ "application/json": {
9482
+ "schema": {
9483
+ "$ref": "#/components/schemas/api-error"
9484
+ }
9485
+ }
9486
+ }
9487
+ }
9488
+ },
9489
+ "description": "The one read the console's Plan & billing page, its usage and limit gauges, and every upgrade prompt and feature gate draw from — nothing else computes `limits` or `usage` on its own. `limits` is already the effective ceiling, the catalogue row raised by `addons` or replaced by an operator's override, so a consumer never recomputes it from the catalogue. `usage` is counted fresh on every call, never cached. `switch` is present only for an organization still on the beta that has not yet landed on a priced plan."
9490
+ }
9491
+ },
9492
+ "/api/org/plan/change": {
9493
+ "put": {
9494
+ "operationId": "put_api_org_plan_change",
9495
+ "summary": "Moves the org's plan down — a lower plan or a cancellation to Basic — queuing the change rather than applying it at once.",
9496
+ "tags": [
9497
+ "org"
9498
+ ],
9499
+ "security": [
9500
+ {
9501
+ "developerSession": []
9502
+ }
9503
+ ],
9504
+ "parameters": [],
9505
+ "responses": {
9506
+ "200": {
9507
+ "description": "Success.",
9508
+ "content": {
9509
+ "application/json": {
9510
+ "schema": {
9511
+ "$ref": "#/components/schemas/org-plan"
9512
+ }
9513
+ }
9514
+ }
9515
+ },
9516
+ "default": {
9517
+ "description": "An error envelope. Codes this route is known to answer: `unauthorized`, `token_expired`, `token_revoked`, `tier_required`, `validation_error`, `plan_limit`, `target_state_conflict`.",
9518
+ "content": {
9519
+ "application/json": {
9520
+ "schema": {
9521
+ "$ref": "#/components/schemas/api-error"
9522
+ }
9523
+ }
9524
+ }
9525
+ }
9526
+ },
9527
+ "description": "Owner tier, and **downward only**: this route moves the org to a lower plan or cancels it outright to Basic. It never moves the org up — until payment exists, an upgrade or an add-on is not this route's job at all, and is handled today as a Feedback request that Fleetless then applies through the admin route. `409 target_state_conflict` names `target_plan` with rule `not_lower` when the chosen plan is not below the org's current one; with rule `locked_basic_only` when the org is locked (`orgLock`) and the chosen plan is anything but Basic; and with rule `migration_basic_only` when the org is still on the beta, awaiting the switch to priced plans, and the chosen plan is anything but Basic — that choice is exactly what the org lands on at the switch. An owner is never named in `keep` and always stays, but still counts against the target plan's `seats`; `409 plan_limit` names `seats` when the owners alone already exceed it, and names whichever other limit `keep` still exceeds otherwise. `keep` is `null` when the org's current usage already fits the target plan outright and nothing is deleted; named, it lists exactly the robots, apps, app users and developers that stay. The choice is stored as `pending_change` and takes effect at `period_ends_at` — **everything of the chosen kind not named in `keep` is deleted at that instant, never before** — except a choice made while the org is locked, which takes effect at once, and a beta org's choice, which takes effect at the switch date instead. Anything created while the choice is pending is checked against the target plan too and, when it passes, is folded into `keep`, so exactly what the confirmation counted is what is actually deleted. A later `PUT` replaces a still-pending choice outright.",
9528
+ "requestBody": {
9529
+ "required": true,
9530
+ "content": {
9531
+ "application/json": {
9532
+ "schema": {
9533
+ "$ref": "#/components/schemas/plan-change-request"
9534
+ }
9535
+ }
9536
+ }
9537
+ }
9538
+ },
9539
+ "delete": {
9540
+ "operationId": "delete_api_org_plan_change",
9541
+ "summary": "Withdraws a plan change that was queued but has not taken effect yet.",
9542
+ "tags": [
9543
+ "org"
9544
+ ],
9545
+ "security": [
9546
+ {
9547
+ "developerSession": []
9548
+ }
9549
+ ],
9550
+ "parameters": [],
9551
+ "responses": {
9552
+ "204": {
9553
+ "description": "Success."
9554
+ },
9555
+ "default": {
9556
+ "description": "An error envelope. Codes this route is known to answer: `unauthorized`, `token_expired`, `token_revoked`, `tier_required`, `not_found`.",
9557
+ "content": {
9558
+ "application/json": {
9559
+ "schema": {
9560
+ "$ref": "#/components/schemas/api-error"
9561
+ }
9562
+ }
9563
+ }
9564
+ }
9565
+ },
9566
+ "description": "Owner tier. `404 not_found` when the org has no `pending_change` to withdraw. The org stays on its current plan, unchanged, as if the choice had never been made; a developer who wants a different one sends a new `PUT`, which would have replaced this one outright anyway."
9567
+ }
9453
9568
  }
9454
9569
  },
9455
9570
  "components": {
@@ -11390,7 +11505,8 @@
11390
11505
  "end_user",
11391
11506
  "app_user",
11392
11507
  "server_key",
11393
- "bridge"
11508
+ "bridge",
11509
+ "fleetless"
11394
11510
  ]
11395
11511
  },
11396
11512
  "id": {
@@ -17837,6 +17953,505 @@
17837
17953
  ],
17838
17954
  "additionalProperties": false
17839
17955
  },
17956
+ "org-plan": {
17957
+ "type": "object",
17958
+ "properties": {
17959
+ "plan": {
17960
+ "type": "string",
17961
+ "enum": [
17962
+ "basic",
17963
+ "plus",
17964
+ "pro",
17965
+ "enterprise"
17966
+ ],
17967
+ "description": "The org's current plan."
17968
+ },
17969
+ "currency": {
17970
+ "type": "string",
17971
+ "enum": [
17972
+ "eur",
17973
+ "usd"
17974
+ ],
17975
+ "description": "The currency the org's prices are shown and billed in."
17976
+ },
17977
+ "period_ends_at": {
17978
+ "type": "string",
17979
+ "format": "date-time",
17980
+ "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
17981
+ "description": "The end of the organization's current billing period; while no payment period exists yet, the end of the current UTC calendar month. A pending downward plan change normally takes effect at this exact instant — except one chosen while the org was locked, which lands at once, and the platform's own move off the beta, which lands at its switch date instead."
17982
+ },
17983
+ "addons": {
17984
+ "type": "object",
17985
+ "properties": {
17986
+ "seats": {
17987
+ "type": "integer",
17988
+ "minimum": 0,
17989
+ "maximum": 9007199254740991,
17990
+ "description": "Extra developer seats, one each."
17991
+ },
17992
+ "robots": {
17993
+ "type": "integer",
17994
+ "minimum": 0,
17995
+ "maximum": 9007199254740991,
17996
+ "description": "Extra robots, one each."
17997
+ },
17998
+ "apps": {
17999
+ "type": "integer",
18000
+ "minimum": 0,
18001
+ "maximum": 9007199254740991,
18002
+ "description": "Extra apps, one each."
18003
+ },
18004
+ "app_user_packs": {
18005
+ "type": "integer",
18006
+ "minimum": 0,
18007
+ "maximum": 9007199254740991,
18008
+ "description": "Packs of five extra app users."
18009
+ },
18010
+ "live_video_packs": {
18011
+ "type": "integer",
18012
+ "minimum": 0,
18013
+ "maximum": 9007199254740991,
18014
+ "description": "Packs of 250 extra hours of app-user live video per month."
18015
+ }
18016
+ },
18017
+ "required": [
18018
+ "seats",
18019
+ "robots",
18020
+ "apps",
18021
+ "app_user_packs",
18022
+ "live_video_packs"
18023
+ ],
18024
+ "additionalProperties": false,
18025
+ "description": "The add-ons the org has bought. All zero on a plan without the `addons` feature."
18026
+ },
18027
+ "limits": {
18028
+ "type": "object",
18029
+ "properties": {
18030
+ "seats": {
18031
+ "anyOf": [
18032
+ {
18033
+ "type": "integer",
18034
+ "exclusiveMinimum": 0,
18035
+ "maximum": 9007199254740991
18036
+ },
18037
+ {
18038
+ "type": "null"
18039
+ }
18040
+ ],
18041
+ "description": "Developers, owners included, plus pending team invitations."
18042
+ },
18043
+ "robots": {
18044
+ "anyOf": [
18045
+ {
18046
+ "type": "integer",
18047
+ "exclusiveMinimum": 0,
18048
+ "maximum": 9007199254740991
18049
+ },
18050
+ {
18051
+ "type": "null"
18052
+ }
18053
+ ],
18054
+ "description": "Robots in the org."
18055
+ },
18056
+ "apps": {
18057
+ "anyOf": [
18058
+ {
18059
+ "type": "integer",
18060
+ "exclusiveMinimum": 0,
18061
+ "maximum": 9007199254740991
18062
+ },
18063
+ {
18064
+ "type": "null"
18065
+ }
18066
+ ],
18067
+ "description": "Apps in the org."
18068
+ },
18069
+ "app_users": {
18070
+ "anyOf": [
18071
+ {
18072
+ "type": "integer",
18073
+ "exclusiveMinimum": 0,
18074
+ "maximum": 9007199254740991
18075
+ },
18076
+ {
18077
+ "type": "null"
18078
+ }
18079
+ ],
18080
+ "description": "App users across every app of the org, plus pending app-user invitations."
18081
+ },
18082
+ "live_video_ms_per_month": {
18083
+ "anyOf": [
18084
+ {
18085
+ "type": "integer",
18086
+ "exclusiveMinimum": 0,
18087
+ "maximum": 9007199254740991
18088
+ },
18089
+ {
18090
+ "type": "null"
18091
+ }
18092
+ ],
18093
+ "description": "Live video watched by app users in one UTC calendar month, in milliseconds, across the org. Console sessions do not count."
18094
+ },
18095
+ "asset_bytes_per_robot": {
18096
+ "anyOf": [
18097
+ {
18098
+ "type": "integer",
18099
+ "exclusiveMinimum": 0,
18100
+ "maximum": 9007199254740991
18101
+ },
18102
+ {
18103
+ "type": "null"
18104
+ }
18105
+ ],
18106
+ "description": "Asset storage per robot, in bytes (decimal: 1 GB = 1,000,000,000). The org stores up to robots × this value in total."
18107
+ },
18108
+ "history_days": {
18109
+ "anyOf": [
18110
+ {
18111
+ "type": "integer",
18112
+ "exclusiveMinimum": 0,
18113
+ "maximum": 9007199254740991
18114
+ },
18115
+ {
18116
+ "type": "null"
18117
+ }
18118
+ ],
18119
+ "description": "Days the org's robot history is kept."
18120
+ },
18121
+ "audit_days": {
18122
+ "anyOf": [
18123
+ {
18124
+ "type": "integer",
18125
+ "exclusiveMinimum": 0,
18126
+ "maximum": 9007199254740991
18127
+ },
18128
+ {
18129
+ "type": "null"
18130
+ }
18131
+ ],
18132
+ "description": "Days the org's audit log is kept."
18133
+ }
18134
+ },
18135
+ "required": [
18136
+ "seats",
18137
+ "robots",
18138
+ "apps",
18139
+ "app_users",
18140
+ "live_video_ms_per_month",
18141
+ "asset_bytes_per_robot",
18142
+ "history_days",
18143
+ "audit_days"
18144
+ ],
18145
+ "additionalProperties": false,
18146
+ "description": "The org's effective limits: the plan's, raised by its add-ons, or an operator's override in their place. `null` means unlimited for a count, and 90 days for `history_days` and `audit_days`."
18147
+ },
18148
+ "features": {
18149
+ "type": "object",
18150
+ "properties": {
18151
+ "app_mcp": {
18152
+ "type": "boolean",
18153
+ "description": "An app's own MCP endpoint, for its app users."
18154
+ },
18155
+ "two_factor": {
18156
+ "type": "boolean",
18157
+ "description": "Two-factor sign-in for developers."
18158
+ },
18159
+ "require_two_factor": {
18160
+ "type": "boolean",
18161
+ "description": "An owner may require two-factor sign-in for every developer of the org."
18162
+ },
18163
+ "app_oidc": {
18164
+ "type": "boolean",
18165
+ "description": "An app may let its users sign in through an OpenID Connect identity provider."
18166
+ },
18167
+ "hosted_logo": {
18168
+ "type": "boolean",
18169
+ "description": "An app's hosted pages show its logo and accent colour, not only its name."
18170
+ },
18171
+ "audit_export": {
18172
+ "type": "boolean",
18173
+ "description": "The audit log can be exported as CSV."
18174
+ },
18175
+ "addons": {
18176
+ "type": "boolean",
18177
+ "description": "Add-ons can be bought on top of the plan."
18178
+ }
18179
+ },
18180
+ "required": [
18181
+ "app_mcp",
18182
+ "two_factor",
18183
+ "require_two_factor",
18184
+ "app_oidc",
18185
+ "hosted_logo",
18186
+ "audit_export",
18187
+ "addons"
18188
+ ],
18189
+ "additionalProperties": false,
18190
+ "description": "What the org's plan unlocks."
18191
+ },
18192
+ "usage": {
18193
+ "type": "object",
18194
+ "properties": {
18195
+ "seats": {
18196
+ "type": "integer",
18197
+ "minimum": 0,
18198
+ "maximum": 9007199254740991,
18199
+ "description": "Developers, owners included, plus pending team invitations."
18200
+ },
18201
+ "robots": {
18202
+ "type": "integer",
18203
+ "minimum": 0,
18204
+ "maximum": 9007199254740991,
18205
+ "description": "Robots in the org."
18206
+ },
18207
+ "apps": {
18208
+ "type": "integer",
18209
+ "minimum": 0,
18210
+ "maximum": 9007199254740991,
18211
+ "description": "Apps in the org."
18212
+ },
18213
+ "app_users": {
18214
+ "type": "integer",
18215
+ "minimum": 0,
18216
+ "maximum": 9007199254740991,
18217
+ "description": "App users across every app, plus pending app-user invitations."
18218
+ },
18219
+ "live_video_ms_this_month": {
18220
+ "type": "integer",
18221
+ "minimum": 0,
18222
+ "maximum": 9007199254740991,
18223
+ "description": "Live video watched by app users in the current UTC calendar month, in milliseconds. Console sessions do not count."
18224
+ },
18225
+ "asset_bytes": {
18226
+ "type": "integer",
18227
+ "minimum": 0,
18228
+ "maximum": 9007199254740991,
18229
+ "description": "Bytes the assets of every robot of the org occupy, together."
18230
+ }
18231
+ },
18232
+ "required": [
18233
+ "seats",
18234
+ "robots",
18235
+ "apps",
18236
+ "app_users",
18237
+ "live_video_ms_this_month",
18238
+ "asset_bytes"
18239
+ ],
18240
+ "additionalProperties": false,
18241
+ "description": "What the org uses now, counted the way each limit counts it."
18242
+ },
18243
+ "pending_change": {
18244
+ "anyOf": [
18245
+ {
18246
+ "type": "object",
18247
+ "properties": {
18248
+ "target_plan": {
18249
+ "type": "string",
18250
+ "enum": [
18251
+ "basic",
18252
+ "plus",
18253
+ "pro",
18254
+ "enterprise"
18255
+ ],
18256
+ "description": "The plan the org moves to."
18257
+ },
18258
+ "reason": {
18259
+ "type": "string",
18260
+ "enum": [
18261
+ "downgrade",
18262
+ "cancel",
18263
+ "migration",
18264
+ "lock"
18265
+ ],
18266
+ "description": "Why the change is pending: `downgrade`, `cancel`, `migration` or `lock`."
18267
+ },
18268
+ "effective_at": {
18269
+ "anyOf": [
18270
+ {
18271
+ "type": "string",
18272
+ "format": "date-time",
18273
+ "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
18274
+ },
18275
+ {
18276
+ "type": "null"
18277
+ }
18278
+ ],
18279
+ "description": "When the change takes effect. `null` only for a move off the beta whose date is not set yet."
18280
+ },
18281
+ "keep": {
18282
+ "anyOf": [
18283
+ {
18284
+ "type": "object",
18285
+ "properties": {
18286
+ "robots": {
18287
+ "type": "array",
18288
+ "items": {
18289
+ "type": "string",
18290
+ "format": "uuid",
18291
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
18292
+ },
18293
+ "description": "The robots that stay, by id. Every other robot is deleted when the change takes effect."
18294
+ },
18295
+ "apps": {
18296
+ "type": "array",
18297
+ "items": {
18298
+ "type": "string",
18299
+ "format": "uuid",
18300
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
18301
+ },
18302
+ "description": "The apps that stay, by id. Every other app is deleted when the change takes effect."
18303
+ },
18304
+ "app_users": {
18305
+ "type": "array",
18306
+ "items": {
18307
+ "type": "string",
18308
+ "format": "uuid",
18309
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
18310
+ },
18311
+ "description": "The app users that stay, by id, across every app. Every other app user is deleted when the change takes effect."
18312
+ },
18313
+ "developers": {
18314
+ "type": "array",
18315
+ "items": {
18316
+ "type": "string",
18317
+ "format": "uuid",
18318
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
18319
+ },
18320
+ "description": "The developers that stay, by user id, owners never among them: every owner stays. Every other developer is removed from the org when the change takes effect."
18321
+ }
18322
+ },
18323
+ "required": [
18324
+ "robots",
18325
+ "apps",
18326
+ "app_users",
18327
+ "developers"
18328
+ ],
18329
+ "additionalProperties": false
18330
+ },
18331
+ {
18332
+ "type": "null"
18333
+ }
18334
+ ],
18335
+ "description": "What stays. `null` when the org already fits the target plan and nothing is deleted."
18336
+ },
18337
+ "history_days_after": {
18338
+ "type": "integer",
18339
+ "exclusiveMinimum": 0,
18340
+ "maximum": 9007199254740991,
18341
+ "description": "Days of history and audit log the org keeps on the target plan."
18342
+ },
18343
+ "chosen_by": {
18344
+ "type": "string",
18345
+ "format": "uuid",
18346
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
18347
+ "description": "The user id of the owner who chose the change, or the nil UUID when Fleetless queued it."
18348
+ },
18349
+ "chosen_at": {
18350
+ "type": "string",
18351
+ "format": "date-time",
18352
+ "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
18353
+ "description": "When the change was chosen."
18354
+ }
18355
+ },
18356
+ "required": [
18357
+ "target_plan",
18358
+ "reason",
18359
+ "effective_at",
18360
+ "keep",
18361
+ "history_days_after",
18362
+ "chosen_by",
18363
+ "chosen_at"
18364
+ ],
18365
+ "additionalProperties": false
18366
+ },
18367
+ {
18368
+ "type": "null"
18369
+ }
18370
+ ],
18371
+ "description": "A move to a lower plan that has not taken effect yet, or `null`."
18372
+ },
18373
+ "lock": {
18374
+ "anyOf": [
18375
+ {
18376
+ "type": "object",
18377
+ "properties": {
18378
+ "reason": {
18379
+ "type": "string",
18380
+ "enum": [
18381
+ "payment",
18382
+ "migration"
18383
+ ],
18384
+ "description": "`payment`: a payment is missing. `migration`: the org did not choose what stays when the beta ended."
18385
+ },
18386
+ "since": {
18387
+ "type": "string",
18388
+ "format": "date-time",
18389
+ "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
18390
+ "description": "When the org was locked."
18391
+ }
18392
+ },
18393
+ "required": [
18394
+ "reason",
18395
+ "since"
18396
+ ],
18397
+ "additionalProperties": false
18398
+ },
18399
+ {
18400
+ "type": "null"
18401
+ }
18402
+ ],
18403
+ "description": "Why and since when the org is locked, or `null` when it is not."
18404
+ },
18405
+ "switch": {
18406
+ "anyOf": [
18407
+ {
18408
+ "type": "object",
18409
+ "properties": {
18410
+ "at": {
18411
+ "anyOf": [
18412
+ {
18413
+ "type": "string",
18414
+ "format": "date-time",
18415
+ "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
18416
+ },
18417
+ {
18418
+ "type": "null"
18419
+ }
18420
+ ],
18421
+ "description": "When the org moves from the beta onto its plan. `null` while the date is not set."
18422
+ },
18423
+ "needs_choice": {
18424
+ "type": "boolean",
18425
+ "description": "Whether the org uses more than Basic allows, so an owner has to choose what stays before `at`."
18426
+ }
18427
+ },
18428
+ "required": [
18429
+ "at",
18430
+ "needs_choice"
18431
+ ],
18432
+ "additionalProperties": false
18433
+ },
18434
+ {
18435
+ "type": "null"
18436
+ }
18437
+ ],
18438
+ "description": "Set only while the org is still on the beta; `null` for every other org."
18439
+ }
18440
+ },
18441
+ "required": [
18442
+ "plan",
18443
+ "currency",
18444
+ "period_ends_at",
18445
+ "addons",
18446
+ "limits",
18447
+ "features",
18448
+ "usage",
18449
+ "pending_change",
18450
+ "lock",
18451
+ "switch"
18452
+ ],
18453
+ "additionalProperties": false
18454
+ },
17840
18455
  "org-quota-usage": {
17841
18456
  "type": "object",
17842
18457
  "properties": {
@@ -18309,6 +18924,82 @@
18309
18924
  ],
18310
18925
  "additionalProperties": false
18311
18926
  },
18927
+ "plan-change-request": {
18928
+ "type": "object",
18929
+ "properties": {
18930
+ "target_plan": {
18931
+ "type": "string",
18932
+ "enum": [
18933
+ "basic",
18934
+ "plus",
18935
+ "pro",
18936
+ "enterprise"
18937
+ ],
18938
+ "description": "The lower plan to move to; `basic` cancels."
18939
+ },
18940
+ "keep": {
18941
+ "anyOf": [
18942
+ {
18943
+ "type": "object",
18944
+ "properties": {
18945
+ "robots": {
18946
+ "type": "array",
18947
+ "items": {
18948
+ "type": "string",
18949
+ "format": "uuid",
18950
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
18951
+ },
18952
+ "description": "The robots that stay, by id. Every other robot is deleted when the change takes effect."
18953
+ },
18954
+ "apps": {
18955
+ "type": "array",
18956
+ "items": {
18957
+ "type": "string",
18958
+ "format": "uuid",
18959
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
18960
+ },
18961
+ "description": "The apps that stay, by id. Every other app is deleted when the change takes effect."
18962
+ },
18963
+ "app_users": {
18964
+ "type": "array",
18965
+ "items": {
18966
+ "type": "string",
18967
+ "format": "uuid",
18968
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
18969
+ },
18970
+ "description": "The app users that stay, by id, across every app. Every other app user is deleted when the change takes effect."
18971
+ },
18972
+ "developers": {
18973
+ "type": "array",
18974
+ "items": {
18975
+ "type": "string",
18976
+ "format": "uuid",
18977
+ "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
18978
+ },
18979
+ "description": "The developers that stay, by user id, owners never among them: every owner stays. Every other developer is removed from the org when the change takes effect."
18980
+ }
18981
+ },
18982
+ "required": [
18983
+ "robots",
18984
+ "apps",
18985
+ "app_users",
18986
+ "developers"
18987
+ ],
18988
+ "additionalProperties": false
18989
+ },
18990
+ {
18991
+ "type": "null"
18992
+ }
18993
+ ],
18994
+ "description": "What stays. `null` when the org already fits the target plan, so nothing is deleted."
18995
+ }
18996
+ },
18997
+ "required": [
18998
+ "target_plan",
18999
+ "keep"
19000
+ ],
19001
+ "additionalProperties": false
19002
+ },
18312
19003
  "protected-resource-metadata": {
18313
19004
  "type": "object",
18314
19005
  "properties": {