@shipeasy/openapi 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +9 -7
- package/dist/index.js +504 -2672
- package/dist/resources/alert-rules.d.ts +48 -0
- package/dist/resources/alert-rules.js +66 -0
- package/dist/resources/configs.d.ts +6 -2
- package/dist/resources/configs.js +67 -2375
- package/dist/resources/experiments.d.ts +100 -2
- package/dist/resources/experiments.js +158 -105
- package/dist/resources/gates.d.ts +51 -8
- package/dist/resources/gates.js +102 -70
- package/dist/resources/index.d.ts +166 -10
- package/dist/resources/index.js +503 -2671
- package/dist/resources/killswitches.d.ts +6 -2
- package/dist/resources/killswitches.js +113 -2412
- package/dist/resources/universes.d.ts +7 -4
- package/dist/resources/universes.js +30 -20
- package/dist/schemas/alert-rules.d.ts +43 -0
- package/dist/schemas/alert-rules.js +27 -0
- package/dist/schemas/configs.d.ts +154 -0
- package/dist/schemas/configs.js +134 -0
- package/dist/schemas/constants.d.ts +6 -0
- package/dist/schemas/constants.js +7 -0
- package/dist/schemas/experiments.d.ts +245 -0
- package/dist/schemas/experiments.js +216 -0
- package/dist/schemas/folder.d.ts +10 -0
- package/dist/schemas/folder.js +8 -0
- package/dist/schemas/gates.d.ts +304 -0
- package/dist/schemas/gates.js +172 -0
- package/dist/schemas/index.d.ts +11 -0
- package/dist/schemas/index.js +729 -0
- package/dist/schemas/killswitches.d.ts +110 -0
- package/dist/schemas/killswitches.js +226 -0
- package/dist/schemas/metric-name.d.ts +5 -0
- package/dist/schemas/metric-name.js +6 -0
- package/dist/schemas/pagination.d.ts +37 -0
- package/dist/schemas/pagination.js +44 -0
- package/dist/schemas/universes.d.ts +35 -0
- package/dist/schemas/universes.js +55 -0
- package/openapi.json +1257 -228
- package/package.json +13 -10
package/openapi.json
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
"name": "Experiments",
|
|
32
|
-
"description": "A/B/n experiments: randomised group assignment plus the analysis pipeline (t-test, sequential testing, SRM detection) on top of a universe.\n\n**Identity.** Stable `name` (a-z, 0-9, `_`/`-`, max 64 chars). Immutable after create.\n\n**Lifecycle.** `draft → running → stopped → archived`. Transition via `POST /{id}/status`.
|
|
32
|
+
"description": "A/B/n experiments: randomised group assignment plus the analysis pipeline (t-test, sequential testing, SRM detection) on top of a universe.\n\n**Identity.** Stable `name` (a-z, 0-9, `_`/`-`, max 64 chars). Immutable after create.\n\n**Lifecycle.** `draft → running → stopped → archived`. Transition via `POST /{id}/status`. An archived experiment that never started can be restored with `archived → draft`; restarting an archived experiment directly is not allowed.\n\n**Allocation.** `allocation_pct` (basis points, 0–10000) is the share of the targeted audience enrolled; `groups[].weight` (must sum to 10000) splits the enrolled audience. `targeting_gate` narrows the eligible audience before allocation.\n\n**Immutable while running.** `allocation_pct`, `groups`, `salt`, `universe`, `params` cannot be edited on a running experiment — stop it first.\n\n**Metrics.** Attach via `POST /{id}/metrics`. Each metric has a role: `goal` drives the decision, `guardrail` blocks ship on regression, `secondary` is informational.\n\n**Analysis.** Daily cron writes results to D1. Read via `GET /{id}/results` (latest per metric/group/day) or `GET /{id}/timeseries` (full history). `POST /{id}/reanalyze` requeues the analysis pass."
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
"name": "Configs",
|
|
@@ -50,7 +50,9 @@
|
|
|
50
50
|
"operationId": "listGates",
|
|
51
51
|
"summary": "List feature gates",
|
|
52
52
|
"description": "Returns a single page of gates ordered by `updated_at desc, id desc`. Use the `cursor` query parameter to paginate.\n\n**Use case:** Snapshot every gate in the project — for example to render an admin overview or to drive a CI check that asserts no gate is left at 100% in staging.",
|
|
53
|
-
"tags": [
|
|
53
|
+
"tags": [
|
|
54
|
+
"Gates"
|
|
55
|
+
],
|
|
54
56
|
"parameters": [
|
|
55
57
|
{
|
|
56
58
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -81,7 +83,11 @@
|
|
|
81
83
|
{
|
|
82
84
|
"attr": "country",
|
|
83
85
|
"op": "in",
|
|
84
|
-
"value": [
|
|
86
|
+
"value": [
|
|
87
|
+
"US",
|
|
88
|
+
"CA",
|
|
89
|
+
"GB"
|
|
90
|
+
]
|
|
85
91
|
},
|
|
86
92
|
{
|
|
87
93
|
"attr": "plan",
|
|
@@ -128,7 +134,9 @@
|
|
|
128
134
|
"operationId": "createGate",
|
|
129
135
|
"summary": "Create a feature gate",
|
|
130
136
|
"description": "Creates a new gate. Default `enabled: true` at the supplied `rollout_pct` (`0` = fully dark).\n\nOnly `name` is required. Request fields use snake_case (`owner_email`); the GET response returns camelCase (`ownerEmail`, `groupName`).\n\nReturns `409` if `name` already exists in the project (case-sensitive).\n\n**Use cases**\n\n- **Dark create + ramp later** — `{ \"name\": \"checkout_v2\" }` at 0% rollout. Ramp via PATCH after deploy validation.\n- **Targeted rollout** — supply `rules` to gate the caller (e.g. only `plan = pro` users) plus a `rollout_pct` to bucket within that audience.\n- **Gatekeeper stack** — supply `stack` instead of `rules`/`rollout_pct` for `internal ∪ beta ∪ public` fall-through. Stack entries evaluated top-to-bottom; first match wins.\n- **Dashboard metadata** — populate `title`, `description`, `folder`, `group`, `owner_email` so the admin UI is self-documenting from day one.\n- **Disabled on create** — pre-provision with `enabled: false` for a future launch; flip on with `POST /{id}/enable` at go-live.",
|
|
131
|
-
"tags": [
|
|
137
|
+
"tags": [
|
|
138
|
+
"Gates"
|
|
139
|
+
],
|
|
132
140
|
"parameters": [
|
|
133
141
|
{
|
|
134
142
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -159,7 +167,11 @@
|
|
|
159
167
|
{
|
|
160
168
|
"attr": "country",
|
|
161
169
|
"op": "in",
|
|
162
|
-
"value": [
|
|
170
|
+
"value": [
|
|
171
|
+
"US",
|
|
172
|
+
"CA",
|
|
173
|
+
"GB"
|
|
174
|
+
]
|
|
163
175
|
},
|
|
164
176
|
{
|
|
165
177
|
"attr": "plan",
|
|
@@ -273,7 +285,9 @@
|
|
|
273
285
|
"operationId": "updateGate",
|
|
274
286
|
"summary": "Update a feature gate",
|
|
275
287
|
"description": "Partial update — only supplied fields change. Array fields (`rules`, `stack`) **replace** wholesale; there is no merge or append.\n\n`name` and the gate id are immutable. The response carries only `{ id }` — re-fetch via `GET /api/admin/gates` for the new row.\n\n**Use cases**\n\n- **Ramp rollout** — `{ \"rollout_pct\": 5000 }` for 50%. Basis points (0–10000); `100` = 1%.\n- **Kill switch** — `{ \"enabled\": false }`. Forces evaluation to `false` for every caller regardless of rules/rollout. Re-enable with `POST /{id}/enable` or `{ \"enabled\": true }`.\n- **Modify a rule's `in` set** — send the full new `rules` array. To add `'GB'` to `['US','CA']`: `{ \"rules\": [{ \"attr\": \"country\", \"op\": \"in\", \"value\": [\"US\",\"CA\",\"GB\"] }] }`. No per-rule patch endpoint.\n- **Add targeting from scratch** — `{ \"rules\": [{ \"attr\": \"email\", \"op\": \"regex\", \"value\": \"@acme\\\\.com$\" }] }`.\n- **Switch to gatekeeper stack** — send a non-null `stack`. To revert to flat eval, send `{ \"stack\": null }`.\n- **Update metadata** — any subset of `title`, `description`, `folder`, `group`, `owner_email`.",
|
|
276
|
-
"tags": [
|
|
288
|
+
"tags": [
|
|
289
|
+
"Gates"
|
|
290
|
+
],
|
|
277
291
|
"parameters": [
|
|
278
292
|
{
|
|
279
293
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -318,7 +332,12 @@
|
|
|
318
332
|
{
|
|
319
333
|
"attr": "country",
|
|
320
334
|
"op": "in",
|
|
321
|
-
"value": [
|
|
335
|
+
"value": [
|
|
336
|
+
"US",
|
|
337
|
+
"CA",
|
|
338
|
+
"GB",
|
|
339
|
+
"AU"
|
|
340
|
+
]
|
|
322
341
|
},
|
|
323
342
|
{
|
|
324
343
|
"attr": "plan",
|
|
@@ -408,7 +427,9 @@
|
|
|
408
427
|
"operationId": "deleteGate",
|
|
409
428
|
"summary": "Delete a feature gate",
|
|
410
429
|
"description": "Soft-deletes the gate. Returns 409 if the gate is still referenced by a running experiment as a targeting gate — stop the experiment first.\n\n**Use case:** Tear down a gate after a feature has fully shipped and the rollout flag is no longer needed.",
|
|
411
|
-
"tags": [
|
|
430
|
+
"tags": [
|
|
431
|
+
"Gates"
|
|
432
|
+
],
|
|
412
433
|
"parameters": [
|
|
413
434
|
{
|
|
414
435
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -463,7 +484,9 @@
|
|
|
463
484
|
"operationId": "enableGate",
|
|
464
485
|
"summary": "Enable a gate",
|
|
465
486
|
"description": "Sets `enabled: true`. The current `rollout_pct` is preserved.\n\n**Use case:** Re-enable a previously disabled gate without re-issuing a full update.",
|
|
466
|
-
"tags": [
|
|
487
|
+
"tags": [
|
|
488
|
+
"Gates"
|
|
489
|
+
],
|
|
467
490
|
"parameters": [
|
|
468
491
|
{
|
|
469
492
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -519,7 +542,9 @@
|
|
|
519
542
|
"operationId": "disableGate",
|
|
520
543
|
"summary": "Disable a gate",
|
|
521
544
|
"description": "Sets `enabled: false` so the gate evaluates to `false` for every caller, regardless of `rollout_pct` or `rules`. Use as a quick kill switch.\n\n**Use case:** Flip a gate off in production without redeploying — the canonical kill-switch flow.",
|
|
522
|
-
"tags": [
|
|
545
|
+
"tags": [
|
|
546
|
+
"Gates"
|
|
547
|
+
],
|
|
523
548
|
"parameters": [
|
|
524
549
|
{
|
|
525
550
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -575,7 +600,9 @@
|
|
|
575
600
|
"operationId": "listExperiments",
|
|
576
601
|
"summary": "List experiments",
|
|
577
602
|
"description": "Returns a single page of non-archived experiments ordered by `updated_at desc, id desc`. Use the `cursor` query parameter to paginate.\n\n**Use case:** Snapshot every active experiment in the project — e.g. render an overview dashboard or drive a CI check that no experiment has been running past its `min_runtime_days`.",
|
|
578
|
-
"tags": [
|
|
603
|
+
"tags": [
|
|
604
|
+
"Experiments"
|
|
605
|
+
],
|
|
579
606
|
"parameters": [
|
|
580
607
|
{
|
|
581
608
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -664,7 +691,9 @@
|
|
|
664
691
|
"operationId": "createExperiment",
|
|
665
692
|
"summary": "Create an experiment",
|
|
666
693
|
"description": "Creates a new experiment in `draft` status. `name`, `universe`, and `groups` are required; everything else has sensible defaults.\n\nReturns `409` if `name` already exists, `422` if the named universe doesn't exist, `403` if a plan-gated option is set (`sequential_testing`, custom `significance_threshold`) on a plan that doesn't include it.\n\n**Use cases**\n\n- **Minimal 50/50** — `name` + `universe` + two equal-weight groups.\n- **Targeted rollout** — supply `targeting_gate` to restrict the eligible audience and `allocation_pct` to enrol a slice of it.\n- **Multivariant** — three or more groups with weights summing to 10000.\n- **Sequential testing** — `sequential_testing: true` for Premium plans.",
|
|
667
|
-
"tags": [
|
|
694
|
+
"tags": [
|
|
695
|
+
"Experiments"
|
|
696
|
+
],
|
|
668
697
|
"parameters": [
|
|
669
698
|
{
|
|
670
699
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -813,7 +842,9 @@
|
|
|
813
842
|
"operationId": "getExperiment",
|
|
814
843
|
"summary": "Get one experiment",
|
|
815
844
|
"description": "Returns the full experiment row including groups, params, allocation, and lifecycle timestamps.\n\n**Use case:** Fetch one experiment to render the detail page or to inspect its current allocation and group weights.",
|
|
816
|
-
"tags": [
|
|
845
|
+
"tags": [
|
|
846
|
+
"Experiments"
|
|
847
|
+
],
|
|
817
848
|
"parameters": [
|
|
818
849
|
{
|
|
819
850
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -900,7 +931,9 @@
|
|
|
900
931
|
"operationId": "updateExperiment",
|
|
901
932
|
"summary": "Update an experiment",
|
|
902
933
|
"description": "Partial update. `allocation_pct`, `groups`, `salt`, `universe`, `params` are **immutable while running** — returns `409` if you try. Stop the experiment first.\n\nEditing `groups` while in `draft` is fine; weights must still sum to 10000.\n\n**Use cases**\n\n- **Update metadata** — `description`, `tag`, `targeting_gate` editable any time.\n- **Ramp before launch** — set `allocation_pct` while still in `draft`.\n- **Tighten significance** — `significance_threshold` (Pro+).\n- **Rewire groups** — replace `groups` wholesale while in `draft`; immutable once running.",
|
|
903
|
-
"tags": [
|
|
934
|
+
"tags": [
|
|
935
|
+
"Experiments"
|
|
936
|
+
],
|
|
904
937
|
"parameters": [
|
|
905
938
|
{
|
|
906
939
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -1003,7 +1036,9 @@
|
|
|
1003
1036
|
"operationId": "deleteExperiment",
|
|
1004
1037
|
"summary": "Delete an experiment",
|
|
1005
1038
|
"description": "Archives the experiment (soft-delete via status transition). Returns `409` if the experiment is still `running` — stop it first.\n\n**Use case:** Tear down an experiment after the analysis is signed off.",
|
|
1006
|
-
"tags": [
|
|
1039
|
+
"tags": [
|
|
1040
|
+
"Experiments"
|
|
1041
|
+
],
|
|
1007
1042
|
"parameters": [
|
|
1008
1043
|
{
|
|
1009
1044
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -1057,8 +1092,10 @@
|
|
|
1057
1092
|
"post": {
|
|
1058
1093
|
"operationId": "setExperimentStatus",
|
|
1059
1094
|
"summary": "Transition experiment status",
|
|
1060
|
-
"description": "Drives the experiment lifecycle. Allowed transitions:\n\n- `draft → running` — starts allocation. Bumps the `startedAt` timestamp.\n- `running → stopped` — halts allocation. Existing exposures stay in the dataset.\n- `stopped → archived` — soft-delete.\n- `draft → archived` — discard an unstarted experiment.\n\nRestarting an `archived` experiment is not allowed
|
|
1061
|
-
"tags": [
|
|
1095
|
+
"description": "Drives the experiment lifecycle. Allowed transitions:\n\n- `draft → running` — starts allocation. Bumps the `startedAt` timestamp.\n- `running → stopped` — halts allocation. Existing exposures stay in the dataset.\n- `stopped → archived` — soft-delete.\n- `draft → archived` — discard an unstarted experiment.\n- `archived → draft` — restore a soft-deleted experiment so it can be re-completed and started. Allowed only if it never started; one that already ran must be cloned instead.\n\nRestarting an `archived` experiment directly is not allowed — restore it to `draft` first. Returns `409` on illegal transitions and `429` if the plan's `experiments_running` limit is exceeded on `→ running`.\n\n**Use cases**\n\n- **Start** — `{ \"status\": \"running\" }` after wiring up the SDK and verifying targeting on staging.\n- **Stop** — `{ \"status\": \"stopped\" }` once the experiment hits its `min_runtime_days` and conclusive results land.\n- **Archive** — `{ \"status\": \"archived\" }` to soft-delete after sign-off.",
|
|
1096
|
+
"tags": [
|
|
1097
|
+
"Experiments"
|
|
1098
|
+
],
|
|
1062
1099
|
"parameters": [
|
|
1063
1100
|
{
|
|
1064
1101
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -1101,6 +1138,13 @@
|
|
|
1101
1138
|
"value": {
|
|
1102
1139
|
"status": "archived"
|
|
1103
1140
|
}
|
|
1141
|
+
},
|
|
1142
|
+
"restore": {
|
|
1143
|
+
"summary": "Restore — archived → draft",
|
|
1144
|
+
"description": "Un-deletes a soft-deleted experiment so it can be re-completed and started. Allowed only if it never ran.",
|
|
1145
|
+
"value": {
|
|
1146
|
+
"status": "draft"
|
|
1147
|
+
}
|
|
1104
1148
|
}
|
|
1105
1149
|
}
|
|
1106
1150
|
}
|
|
@@ -1147,7 +1191,9 @@
|
|
|
1147
1191
|
"operationId": "setExperimentMetrics",
|
|
1148
1192
|
"summary": "Attach metrics",
|
|
1149
1193
|
"description": "Replaces the experiment's metric attachments wholesale. Each entry pairs an existing `metric_id` with a `role` (`goal` / `guardrail` / `secondary`).\n\nReturns `422` if any `metric_id` doesn't exist in the project. Pass `{ metrics: [] }` to detach everything.\n\n**Use cases**\n\n- **Standard setup** — one `goal`, one or two `guardrail`, optional `secondary` metrics for diagnostics.\n- **Detach all** — send `{ \"metrics\": [] }` before archiving.",
|
|
1150
|
-
"tags": [
|
|
1194
|
+
"tags": [
|
|
1195
|
+
"Experiments"
|
|
1196
|
+
],
|
|
1151
1197
|
"parameters": [
|
|
1152
1198
|
{
|
|
1153
1199
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -1247,7 +1293,9 @@
|
|
|
1247
1293
|
"operationId": "getExperimentResults",
|
|
1248
1294
|
"summary": "Get analysis results",
|
|
1249
1295
|
"description": "Returns the latest analysis output for the experiment — one row per metric/group/day, including sample size, mean, % delta vs. control, p-value, and a sample-ratio mismatch flag.\n\n**Use case:** Render the results table on the experiment detail page or drive an automated decision once a `goal` metric reaches significance.",
|
|
1250
|
-
"tags": [
|
|
1296
|
+
"tags": [
|
|
1297
|
+
"Experiments"
|
|
1298
|
+
],
|
|
1251
1299
|
"parameters": [
|
|
1252
1300
|
{
|
|
1253
1301
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -1328,7 +1376,9 @@
|
|
|
1328
1376
|
"operationId": "getExperimentTimeseries",
|
|
1329
1377
|
"summary": "Get analysis timeseries",
|
|
1330
1378
|
"description": "Same row shape as `/results`, but returns every daily slice rather than the latest. Filter to a single metric with the `metric` query parameter.\n\n**Use case:** Drive a chart of metric movement over the experiment runtime, or sanity-check the lift is monotonic before deciding.",
|
|
1331
|
-
"tags": [
|
|
1379
|
+
"tags": [
|
|
1380
|
+
"Experiments"
|
|
1381
|
+
],
|
|
1332
1382
|
"parameters": [
|
|
1333
1383
|
{
|
|
1334
1384
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -1418,7 +1468,9 @@
|
|
|
1418
1468
|
"operationId": "reanalyzeExperiment",
|
|
1419
1469
|
"summary": "Re-queue analysis",
|
|
1420
1470
|
"description": "Requeues the daily analysis pass for this experiment outside the normal cron cadence. Useful after attaching a new metric or correcting an event taxonomy. The job runs asynchronously.\n\n**Use case:** Force-refresh results after wiring up a new metric without waiting for the next nightly cron tick.",
|
|
1421
|
-
"tags": [
|
|
1471
|
+
"tags": [
|
|
1472
|
+
"Experiments"
|
|
1473
|
+
],
|
|
1422
1474
|
"parameters": [
|
|
1423
1475
|
{
|
|
1424
1476
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -1474,7 +1526,9 @@
|
|
|
1474
1526
|
"operationId": "listConfigs",
|
|
1475
1527
|
"summary": "List dynamic configs",
|
|
1476
1528
|
"description": "Returns a single page of configs ordered by `updated_at desc, id desc`. Each row includes the latest published `version` per env and any active drafts.\n\n**Use case:** Snapshot every config in the project — e.g. CI check that asserts no env is stuck on a stale default or that every config has a published value on prod.",
|
|
1477
|
-
"tags": [
|
|
1529
|
+
"tags": [
|
|
1530
|
+
"Configs"
|
|
1531
|
+
],
|
|
1478
1532
|
"parameters": [
|
|
1479
1533
|
{
|
|
1480
1534
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -1510,7 +1564,9 @@
|
|
|
1510
1564
|
}
|
|
1511
1565
|
}
|
|
1512
1566
|
},
|
|
1513
|
-
"required": [
|
|
1567
|
+
"required": [
|
|
1568
|
+
"tiers"
|
|
1569
|
+
]
|
|
1514
1570
|
},
|
|
1515
1571
|
"updatedAt": "2026-05-09T18:22:11.000Z",
|
|
1516
1572
|
"envs": {
|
|
@@ -1568,7 +1624,9 @@
|
|
|
1568
1624
|
"operationId": "createConfig",
|
|
1569
1625
|
"summary": "Create a dynamic config",
|
|
1570
1626
|
"description": "Creates a new config with the given `schema`. The initial `value` (or an empty object) is published as version 1 on **every** env.\n\nReturns `409` if `name` already exists in the project, `400` if `value` doesn't validate against `schema`.\n\n**Use cases**\n\n- **Minimal create** — `name` + `schema`. Initial value defaults to `{}`.\n- **Seeded create** — supply a flat `value` to publish the same object on every env.\n- **Per-env seed** — supply a `{ env: value }` map for different per-env starting values.",
|
|
1571
|
-
"tags": [
|
|
1627
|
+
"tags": [
|
|
1628
|
+
"Configs"
|
|
1629
|
+
],
|
|
1572
1630
|
"parameters": [
|
|
1573
1631
|
{
|
|
1574
1632
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -1594,7 +1652,9 @@
|
|
|
1594
1652
|
"type": "array"
|
|
1595
1653
|
}
|
|
1596
1654
|
},
|
|
1597
|
-
"required": [
|
|
1655
|
+
"required": [
|
|
1656
|
+
"tiers"
|
|
1657
|
+
]
|
|
1598
1658
|
}
|
|
1599
1659
|
}
|
|
1600
1660
|
},
|
|
@@ -1611,7 +1671,9 @@
|
|
|
1611
1671
|
"type": "array"
|
|
1612
1672
|
}
|
|
1613
1673
|
},
|
|
1614
|
-
"required": [
|
|
1674
|
+
"required": [
|
|
1675
|
+
"tiers"
|
|
1676
|
+
]
|
|
1615
1677
|
},
|
|
1616
1678
|
"value": {
|
|
1617
1679
|
"tiers": [
|
|
@@ -1637,7 +1699,9 @@
|
|
|
1637
1699
|
"type": "array"
|
|
1638
1700
|
}
|
|
1639
1701
|
},
|
|
1640
|
-
"required": [
|
|
1702
|
+
"required": [
|
|
1703
|
+
"tiers"
|
|
1704
|
+
]
|
|
1641
1705
|
},
|
|
1642
1706
|
"value": {
|
|
1643
1707
|
"dev": {
|
|
@@ -1721,7 +1785,9 @@
|
|
|
1721
1785
|
"operationId": "getConfig",
|
|
1722
1786
|
"summary": "Get one config",
|
|
1723
1787
|
"description": "Returns config metadata plus the latest published values per env and any active draft values. Use this to fetch the JSON the editor renders.\n\n**Use case:** Fetch one config's current published values and any in-flight drafts.",
|
|
1724
|
-
"tags": [
|
|
1788
|
+
"tags": [
|
|
1789
|
+
"Configs"
|
|
1790
|
+
],
|
|
1725
1791
|
"parameters": [
|
|
1726
1792
|
{
|
|
1727
1793
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -1758,7 +1824,9 @@
|
|
|
1758
1824
|
}
|
|
1759
1825
|
}
|
|
1760
1826
|
},
|
|
1761
|
-
"required": [
|
|
1827
|
+
"required": [
|
|
1828
|
+
"tiers"
|
|
1829
|
+
]
|
|
1762
1830
|
},
|
|
1763
1831
|
"updatedAt": "2026-05-09T18:22:11.000Z",
|
|
1764
1832
|
"envs": {
|
|
@@ -1860,7 +1928,9 @@
|
|
|
1860
1928
|
"operationId": "updateConfig",
|
|
1861
1929
|
"summary": "Update a dynamic config",
|
|
1862
1930
|
"description": "Partial update. When `value` is supplied it is **republished on every env** (new version per env). When `schema` is supplied it replaces the current schema; every existing value is re-validated.\n\nFor env-scoped edits, use the draft/publish flow (`PUT /{id}/drafts` then `POST /{id}/publish`) instead.\n\n**Use cases**\n\n- **Republish flat value** — `{ \"value\": {…} }` sets the same value on every env.\n- **Schema migration** — `{ \"schema\": {…} }` replaces the schema; existing values are re-validated.\n- **Env-scoped edits** — use `PUT /{id}/drafts` + `POST /{id}/publish` instead of PATCH.",
|
|
1863
|
-
"tags": [
|
|
1931
|
+
"tags": [
|
|
1932
|
+
"Configs"
|
|
1933
|
+
],
|
|
1864
1934
|
"parameters": [
|
|
1865
1935
|
{
|
|
1866
1936
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -1913,7 +1983,9 @@
|
|
|
1913
1983
|
"type": "integer"
|
|
1914
1984
|
}
|
|
1915
1985
|
},
|
|
1916
|
-
"required": [
|
|
1986
|
+
"required": [
|
|
1987
|
+
"tiers"
|
|
1988
|
+
]
|
|
1917
1989
|
}
|
|
1918
1990
|
}
|
|
1919
1991
|
}
|
|
@@ -1959,7 +2031,9 @@
|
|
|
1959
2031
|
"operationId": "deleteConfig",
|
|
1960
2032
|
"summary": "Delete a dynamic config",
|
|
1961
2033
|
"description": "Soft-deletes the config and rebuilds the project's flags KV blob.\n\n**Use case:** Tear down a config after its consumers have stopped reading it.",
|
|
1962
|
-
"tags": [
|
|
2034
|
+
"tags": [
|
|
2035
|
+
"Configs"
|
|
2036
|
+
],
|
|
1963
2037
|
"parameters": [
|
|
1964
2038
|
{
|
|
1965
2039
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -2014,7 +2088,9 @@
|
|
|
2014
2088
|
"operationId": "saveConfigDraft",
|
|
2015
2089
|
"summary": "Save a draft value",
|
|
2016
2090
|
"description": "Stages a value for one env without publishing. The draft is validated against the config's current schema and stored alongside the `baseVersion` it was forked from.\n\nSaving over an existing draft overwrites it. Use `POST /{id}/publish` to promote it to a new published version.\n\n**Use case:** Iterate on a config value on dev without affecting prod — preview in staging, then publish.",
|
|
2017
|
-
"tags": [
|
|
2091
|
+
"tags": [
|
|
2092
|
+
"Configs"
|
|
2093
|
+
],
|
|
2018
2094
|
"parameters": [
|
|
2019
2095
|
{
|
|
2020
2096
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -2102,7 +2178,9 @@
|
|
|
2102
2178
|
"operationId": "discardConfigDraft",
|
|
2103
2179
|
"summary": "Discard a draft",
|
|
2104
2180
|
"description": "Drops the in-flight draft on one env. Published values are unaffected.\n\n**Use case:** Abandon an in-progress draft after deciding not to ship it.",
|
|
2105
|
-
"tags": [
|
|
2181
|
+
"tags": [
|
|
2182
|
+
"Configs"
|
|
2183
|
+
],
|
|
2106
2184
|
"parameters": [
|
|
2107
2185
|
{
|
|
2108
2186
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -2176,7 +2254,9 @@
|
|
|
2176
2254
|
"operationId": "publishConfigDraft",
|
|
2177
2255
|
"summary": "Publish a draft",
|
|
2178
2256
|
"description": "Promotes the staged draft on one env to a new published version. The draft must still validate against the current schema.\n\nReturns `404` if there is no draft for the given env.\n\n**Use case:** Ship a staged change once you've validated it on a lower env.",
|
|
2179
|
-
"tags": [
|
|
2257
|
+
"tags": [
|
|
2258
|
+
"Configs"
|
|
2259
|
+
],
|
|
2180
2260
|
"parameters": [
|
|
2181
2261
|
{
|
|
2182
2262
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -2259,7 +2339,9 @@
|
|
|
2259
2339
|
"operationId": "listConfigActivity",
|
|
2260
2340
|
"summary": "List config activity",
|
|
2261
2341
|
"description": "Returns recent audit rows for one config (create, update, draft.save, publish, delete) ordered newest first. Use the `limit` query parameter to cap the result (1–100, default 20).\n\n**Use case:** Render the activity panel in the config editor or drive a slack notification on publish events.",
|
|
2262
|
-
"tags": [
|
|
2342
|
+
"tags": [
|
|
2343
|
+
"Configs"
|
|
2344
|
+
],
|
|
2263
2345
|
"parameters": [
|
|
2264
2346
|
{
|
|
2265
2347
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -2336,7 +2418,9 @@
|
|
|
2336
2418
|
"operationId": "listKillswitches",
|
|
2337
2419
|
"summary": "List killswitches",
|
|
2338
2420
|
"description": "Returns a single page of killswitches ordered by `updated_at desc, id desc`. Each row includes the latest published `value`/`switches`/`version` per env.\n\n**Use case:** Snapshot every killswitch in the project — e.g. to render an incident-response runbook listing every kill and its current trip state.",
|
|
2339
|
-
"tags": [
|
|
2421
|
+
"tags": [
|
|
2422
|
+
"Killswitches"
|
|
2423
|
+
],
|
|
2340
2424
|
"parameters": [
|
|
2341
2425
|
{
|
|
2342
2426
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -2414,7 +2498,9 @@
|
|
|
2414
2498
|
"operationId": "createKillswitch",
|
|
2415
2499
|
"summary": "Create a killswitch",
|
|
2416
2500
|
"description": "Creates a new killswitch with `value` (default `false`) applied to **every** env at version 1.\n\nReturns `409` if `name` already exists in the project.\n\n**Use cases**\n\n- **Untripped create** — `{ \"name\": \"payments.checkout\" }`. Provision the kill ahead of an incident.\n- **Pre-tripped** — `{ \"value\": true }` to ship the killswitch already engaged.\n- **With switches** — seed `switches` to carve out per-region/per-tenant kills from day one.",
|
|
2417
|
-
"tags": [
|
|
2501
|
+
"tags": [
|
|
2502
|
+
"Killswitches"
|
|
2503
|
+
],
|
|
2418
2504
|
"parameters": [
|
|
2419
2505
|
{
|
|
2420
2506
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -2501,7 +2587,9 @@
|
|
|
2501
2587
|
"operationId": "getKillswitch",
|
|
2502
2588
|
"summary": "Get one killswitch",
|
|
2503
2589
|
"description": "Returns the killswitch metadata plus the latest published `value`/`switches`/`version` per env.\n\n**Use case:** Fetch the current state of one killswitch — e.g. to verify a trip propagated before declaring an incident mitigated.",
|
|
2504
|
-
"tags": [
|
|
2590
|
+
"tags": [
|
|
2591
|
+
"Killswitches"
|
|
2592
|
+
],
|
|
2505
2593
|
"parameters": [
|
|
2506
2594
|
{
|
|
2507
2595
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -2577,7 +2665,9 @@
|
|
|
2577
2665
|
"operationId": "updateKillswitch",
|
|
2578
2666
|
"summary": "Update a killswitch",
|
|
2579
2667
|
"description": "Partial update applied to **every** env. Setting `value`/`switches` publishes a new version per env. Description-only patches don't bump versions.\n\nTo change a single switch on a single env, use `PUT /{id}/switch` instead.\n\n**Use cases**\n\n- **Trip everywhere** — `{ \"value\": true }`. Kills the feature across dev/stage/prod in one call.\n- **Untrip everywhere** — `{ \"value\": false }`.\n- **Replace switches** — send the full new map; per-key edits use `PUT /{id}/switch`.\n- **Update description** — metadata-only patches don't bump versions.",
|
|
2580
|
-
"tags": [
|
|
2668
|
+
"tags": [
|
|
2669
|
+
"Killswitches"
|
|
2670
|
+
],
|
|
2581
2671
|
"parameters": [
|
|
2582
2672
|
{
|
|
2583
2673
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -2673,7 +2763,9 @@
|
|
|
2673
2763
|
"operationId": "deleteKillswitch",
|
|
2674
2764
|
"summary": "Delete a killswitch",
|
|
2675
2765
|
"description": "Soft-deletes the killswitch and rebuilds the project's flags KV blob so SDKs stop seeing it.\n\n**Use case:** Tear down a killswitch after the feature it protected has been removed.",
|
|
2676
|
-
"tags": [
|
|
2766
|
+
"tags": [
|
|
2767
|
+
"Killswitches"
|
|
2768
|
+
],
|
|
2677
2769
|
"parameters": [
|
|
2678
2770
|
{
|
|
2679
2771
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -2728,7 +2820,9 @@
|
|
|
2728
2820
|
"operationId": "setKillswitchSwitch",
|
|
2729
2821
|
"summary": "Set one switch entry",
|
|
2730
2822
|
"description": "Sets or updates a single `switchKey` on a single `env`. Publishes one new version on that env only — other envs untouched.\n\nUse this for surgical per-env, per-key flips during incident response (e.g. trip `eu_region` on prod without touching the flat `value` or other envs).\n\n**Use cases**\n\n- **Trip a region** — `{ \"env\": \"prod\", \"switchKey\": \"eu_region\", \"value\": true }`.\n- **Untrip without removing** — same payload with `value: false`. To remove the entry entirely use `DELETE /{id}/switch`.",
|
|
2731
|
-
"tags": [
|
|
2823
|
+
"tags": [
|
|
2824
|
+
"Killswitches"
|
|
2825
|
+
],
|
|
2732
2826
|
"parameters": [
|
|
2733
2827
|
{
|
|
2734
2828
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -2814,7 +2908,9 @@
|
|
|
2814
2908
|
"operationId": "unsetKillswitchSwitch",
|
|
2815
2909
|
"summary": "Remove one switch entry",
|
|
2816
2910
|
"description": "Removes a single `switchKey` from the `switches` map on a single `env`. Publishes a new version on that env.\n\nReturns `{ removed: false }` if the entry didn't exist (idempotent no-op).\n\n**Use case:** Clean up a per-region override after the incident is resolved so the flat `value` governs again.",
|
|
2817
|
-
"tags": [
|
|
2911
|
+
"tags": [
|
|
2912
|
+
"Killswitches"
|
|
2913
|
+
],
|
|
2818
2914
|
"parameters": [
|
|
2819
2915
|
{
|
|
2820
2916
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -2892,7 +2988,9 @@
|
|
|
2892
2988
|
"operationId": "listUniverses",
|
|
2893
2989
|
"summary": "List universes",
|
|
2894
2990
|
"description": "Returns a single page of universes ordered by `created_at desc, id desc`. The universes table has no `updated_at`, so this list is keyed on creation time.\n\n**Use case:** Snapshot every universe in the project — for example to audit which `unit_type` and `holdout_range` are in use before launching a new experiment.",
|
|
2895
|
-
"tags": [
|
|
2991
|
+
"tags": [
|
|
2992
|
+
"Universes"
|
|
2993
|
+
],
|
|
2896
2994
|
"parameters": [
|
|
2897
2995
|
{
|
|
2898
2996
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -2918,7 +3016,10 @@
|
|
|
2918
3016
|
"id": "uni_01j7w8a1b2c3d4e5f6g7h8i9j0",
|
|
2919
3017
|
"name": "primary_users",
|
|
2920
3018
|
"unitType": "user_id",
|
|
2921
|
-
"holdoutRange": [
|
|
3019
|
+
"holdoutRange": [
|
|
3020
|
+
9500,
|
|
3021
|
+
9999
|
|
3022
|
+
],
|
|
2922
3023
|
"createdAt": "2026-04-12T10:14:08.000Z"
|
|
2923
3024
|
}
|
|
2924
3025
|
],
|
|
@@ -2951,7 +3052,9 @@
|
|
|
2951
3052
|
"operationId": "createUniverse",
|
|
2952
3053
|
"summary": "Create a universe",
|
|
2953
3054
|
"description": "Creates a new universe. Only `name` is required — `unit_type` defaults to `user_id` and `holdout_range` defaults to `null` (no holdout).\n\nReturns `409` if `name` already exists in the project. Returns `403` if you supply `holdout_range` on a plan below Pro.\n\n**Use cases**\n\n- **Default universe** — `{ \"name\": \"primary_users\" }`. Per-user randomisation, no holdout.\n- **Reserved holdout** — supply `holdout_range` to carve out a measurement slice excluded from all experiments.\n- **Account-level** — `unit_type: 'account_id'` so multi-seat accounts see one consistent variant.",
|
|
2954
|
-
"tags": [
|
|
3055
|
+
"tags": [
|
|
3056
|
+
"Universes"
|
|
3057
|
+
],
|
|
2955
3058
|
"parameters": [
|
|
2956
3059
|
{
|
|
2957
3060
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -2977,7 +3080,10 @@
|
|
|
2977
3080
|
"description": "Reserves buckets 9500–9999 (5% of callers) as the holdout. Pro plan or higher.",
|
|
2978
3081
|
"value": {
|
|
2979
3082
|
"name": "primary_users",
|
|
2980
|
-
"holdout_range": [
|
|
3083
|
+
"holdout_range": [
|
|
3084
|
+
9500,
|
|
3085
|
+
9999
|
|
3086
|
+
]
|
|
2981
3087
|
}
|
|
2982
3088
|
},
|
|
2983
3089
|
"accountLevel": {
|
|
@@ -3033,7 +3139,9 @@
|
|
|
3033
3139
|
"operationId": "updateUniverse",
|
|
3034
3140
|
"summary": "Update a universe",
|
|
3035
3141
|
"description": "Partial update. Only `holdout_range` is mutable — `name` and `unit_type` are immutable after create.\n\nPass `\"holdout_range\": null` to remove an existing holdout.\n\n**Use cases**\n\n- **Adjust holdout** — change the reserved measurement slice without recreating experiments.\n- **Remove holdout** — `{ \"holdout_range\": null }`.",
|
|
3036
|
-
"tags": [
|
|
3142
|
+
"tags": [
|
|
3143
|
+
"Universes"
|
|
3144
|
+
],
|
|
3037
3145
|
"parameters": [
|
|
3038
3146
|
{
|
|
3039
3147
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -3060,7 +3168,10 @@
|
|
|
3060
3168
|
"summary": "Set holdout — reserve 5%",
|
|
3061
3169
|
"description": "Reserve buckets 9500–9999 as the holdout. Pro plan or higher.",
|
|
3062
3170
|
"value": {
|
|
3063
|
-
"holdout_range": [
|
|
3171
|
+
"holdout_range": [
|
|
3172
|
+
9500,
|
|
3173
|
+
9999
|
|
3174
|
+
]
|
|
3064
3175
|
}
|
|
3065
3176
|
},
|
|
3066
3177
|
"removeHoldout": {
|
|
@@ -3112,7 +3223,9 @@
|
|
|
3112
3223
|
"operationId": "deleteUniverse",
|
|
3113
3224
|
"summary": "Delete a universe",
|
|
3114
3225
|
"description": "Soft-deletes the universe. Returns `409` if any non-archived experiment still references it — archive those experiments first.\n\n**Use case:** Tear down a universe after every experiment that used it has been archived.",
|
|
3115
|
-
"tags": [
|
|
3226
|
+
"tags": [
|
|
3227
|
+
"Universes"
|
|
3228
|
+
],
|
|
3116
3229
|
"parameters": [
|
|
3117
3230
|
{
|
|
3118
3231
|
"$ref": "#/components/parameters/ProjectId"
|
|
@@ -3167,7 +3280,9 @@
|
|
|
3167
3280
|
"schemas": {
|
|
3168
3281
|
"ErrorResponse": {
|
|
3169
3282
|
"type": "object",
|
|
3170
|
-
"required": [
|
|
3283
|
+
"required": [
|
|
3284
|
+
"error"
|
|
3285
|
+
],
|
|
3171
3286
|
"properties": {
|
|
3172
3287
|
"error": {
|
|
3173
3288
|
"type": "string",
|
|
@@ -3198,8 +3313,9 @@
|
|
|
3198
3313
|
},
|
|
3199
3314
|
"name": {
|
|
3200
3315
|
"type": "string",
|
|
3201
|
-
"
|
|
3202
|
-
"
|
|
3316
|
+
"maxLength": 128,
|
|
3317
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$",
|
|
3318
|
+
"description": "Stable gate key used by SDKs (`Shipeasy.checkGate(user, '<name>')`). Single segment or `folder.name`. Lowercase letters, digits, `_` or `-`; max 128 chars. Immutable after create — rename = delete + recreate."
|
|
3203
3319
|
},
|
|
3204
3320
|
"enabled": {
|
|
3205
3321
|
"anyOf": [
|
|
@@ -3242,15 +3358,23 @@
|
|
|
3242
3358
|
"lt",
|
|
3243
3359
|
"lte",
|
|
3244
3360
|
"contains",
|
|
3245
|
-
"regex"
|
|
3361
|
+
"regex",
|
|
3362
|
+
"semver_gt",
|
|
3363
|
+
"semver_gte",
|
|
3364
|
+
"semver_lt",
|
|
3365
|
+
"semver_lte"
|
|
3246
3366
|
],
|
|
3247
|
-
"description": "Comparison operator. Equality: `eq`/`neq`. Set membership: `in`/`not_in` (value is an array). Numeric order: `gt`/`gte`/`lt`/`lte`. String: `contains` (substring), `regex` (JS-flavour pattern, value is the pattern string)."
|
|
3367
|
+
"description": "Comparison operator. Equality: `eq`/`neq`. Set membership: `in`/`not_in` (value is an array). Numeric order: `gt`/`gte`/`lt`/`lte`. Semver order: `semver_gt`/`semver_gte`/`semver_lt`/`semver_lte` (value is a dotted version like `4.2.0`). String: `contains` (substring), `regex` (JS-flavour pattern, value is the pattern string)."
|
|
3248
3368
|
},
|
|
3249
3369
|
"value": {
|
|
3250
|
-
"description": "Operand. Shape depends on `op`: scalar for `eq/neq/gt/gte/lt/lte/contains
|
|
3370
|
+
"description": "Operand. Shape depends on `op`: scalar for `eq/neq/gt/gte/lt/lte/contains/semver_*`; array of scalars for `in/not_in`; string pattern for `regex`."
|
|
3251
3371
|
}
|
|
3252
3372
|
},
|
|
3253
|
-
"required": [
|
|
3373
|
+
"required": [
|
|
3374
|
+
"attr",
|
|
3375
|
+
"op",
|
|
3376
|
+
"value"
|
|
3377
|
+
],
|
|
3254
3378
|
"additionalProperties": false,
|
|
3255
3379
|
"description": "Single targeting predicate. A gate's `rules` array is evaluated with AND semantics; use the gatekeeper `stack` for OR / fall-through logic."
|
|
3256
3380
|
}
|
|
@@ -3348,7 +3472,10 @@
|
|
|
3348
3472
|
"pass": {
|
|
3349
3473
|
"description": "Combinator across `rules`. `all` = AND (default), `any` = OR.",
|
|
3350
3474
|
"type": "string",
|
|
3351
|
-
"enum": [
|
|
3475
|
+
"enum": [
|
|
3476
|
+
"all",
|
|
3477
|
+
"any"
|
|
3478
|
+
]
|
|
3352
3479
|
},
|
|
3353
3480
|
"rules": {
|
|
3354
3481
|
"default": [],
|
|
@@ -3374,15 +3501,23 @@
|
|
|
3374
3501
|
"lt",
|
|
3375
3502
|
"lte",
|
|
3376
3503
|
"contains",
|
|
3377
|
-
"regex"
|
|
3504
|
+
"regex",
|
|
3505
|
+
"semver_gt",
|
|
3506
|
+
"semver_gte",
|
|
3507
|
+
"semver_lt",
|
|
3508
|
+
"semver_lte"
|
|
3378
3509
|
],
|
|
3379
|
-
"description": "Comparison operator. Equality: `eq`/`neq`. Set membership: `in`/`not_in` (value is an array). Numeric order: `gt`/`gte`/`lt`/`lte`. String: `contains` (substring), `regex` (JS-flavour pattern, value is the pattern string)."
|
|
3510
|
+
"description": "Comparison operator. Equality: `eq`/`neq`. Set membership: `in`/`not_in` (value is an array). Numeric order: `gt`/`gte`/`lt`/`lte`. Semver order: `semver_gt`/`semver_gte`/`semver_lt`/`semver_lte` (value is a dotted version like `4.2.0`). String: `contains` (substring), `regex` (JS-flavour pattern, value is the pattern string)."
|
|
3380
3511
|
},
|
|
3381
3512
|
"value": {
|
|
3382
|
-
"description": "Operand. Shape depends on `op`: scalar for `eq/neq/gt/gte/lt/lte/contains
|
|
3513
|
+
"description": "Operand. Shape depends on `op`: scalar for `eq/neq/gt/gte/lt/lte/contains/semver_*`; array of scalars for `in/not_in`; string pattern for `regex`."
|
|
3383
3514
|
}
|
|
3384
3515
|
},
|
|
3385
|
-
"required": [
|
|
3516
|
+
"required": [
|
|
3517
|
+
"attr",
|
|
3518
|
+
"op",
|
|
3519
|
+
"value"
|
|
3520
|
+
],
|
|
3386
3521
|
"additionalProperties": false,
|
|
3387
3522
|
"description": "Single targeting predicate. A gate's `rules` array is evaluated with AND semantics; use the gatekeeper `stack` for OR / fall-through logic."
|
|
3388
3523
|
}
|
|
@@ -3392,7 +3527,11 @@
|
|
|
3392
3527
|
"type": "boolean"
|
|
3393
3528
|
}
|
|
3394
3529
|
},
|
|
3395
|
-
"required": [
|
|
3530
|
+
"required": [
|
|
3531
|
+
"id",
|
|
3532
|
+
"type",
|
|
3533
|
+
"rules"
|
|
3534
|
+
],
|
|
3396
3535
|
"additionalProperties": false,
|
|
3397
3536
|
"description": "Rule-based sub-gate. When matched, evaluation short-circuits and the gate returns `true` for the current caller."
|
|
3398
3537
|
},
|
|
@@ -3443,7 +3582,11 @@
|
|
|
3443
3582
|
"type": "boolean"
|
|
3444
3583
|
}
|
|
3445
3584
|
},
|
|
3446
|
-
"required": [
|
|
3585
|
+
"required": [
|
|
3586
|
+
"id",
|
|
3587
|
+
"type",
|
|
3588
|
+
"rolloutPct"
|
|
3589
|
+
],
|
|
3447
3590
|
"additionalProperties": false,
|
|
3448
3591
|
"description": "Percentage-rollout sub-gate. Hashes `bucketBy` (default `userID`) with `salt` and returns `true` for `rolloutPct/10000` fraction of callers."
|
|
3449
3592
|
}
|
|
@@ -3461,7 +3604,13 @@
|
|
|
3461
3604
|
"description": "ISO-8601 timestamp of last mutation."
|
|
3462
3605
|
}
|
|
3463
3606
|
},
|
|
3464
|
-
"required": [
|
|
3607
|
+
"required": [
|
|
3608
|
+
"id",
|
|
3609
|
+
"name",
|
|
3610
|
+
"enabled",
|
|
3611
|
+
"rolloutPct",
|
|
3612
|
+
"updatedAt"
|
|
3613
|
+
],
|
|
3465
3614
|
"additionalProperties": false
|
|
3466
3615
|
}
|
|
3467
3616
|
},
|
|
@@ -3476,7 +3625,10 @@
|
|
|
3476
3625
|
]
|
|
3477
3626
|
}
|
|
3478
3627
|
},
|
|
3479
|
-
"required": [
|
|
3628
|
+
"required": [
|
|
3629
|
+
"data",
|
|
3630
|
+
"next_cursor"
|
|
3631
|
+
],
|
|
3480
3632
|
"additionalProperties": false
|
|
3481
3633
|
},
|
|
3482
3634
|
"CreateGateRequest": {
|
|
@@ -3484,8 +3636,9 @@
|
|
|
3484
3636
|
"properties": {
|
|
3485
3637
|
"name": {
|
|
3486
3638
|
"type": "string",
|
|
3487
|
-
"
|
|
3488
|
-
"
|
|
3639
|
+
"maxLength": 128,
|
|
3640
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$",
|
|
3641
|
+
"description": "Stable gate key used by SDKs (`Shipeasy.checkGate(user, '<name>')`). Single segment or `folder.name`. Lowercase letters, digits, `_` or `-`; max 128 chars. Immutable after create — rename = delete + recreate."
|
|
3489
3642
|
},
|
|
3490
3643
|
"enabled": {
|
|
3491
3644
|
"default": true,
|
|
@@ -3494,11 +3647,17 @@
|
|
|
3494
3647
|
},
|
|
3495
3648
|
"rollout_pct": {
|
|
3496
3649
|
"default": 0,
|
|
3497
|
-
"description": "Initial rollout in basis points (0–10000 = 0%–100%). Use `0` to create the gate dark and ramp via PATCH after deploy validation.",
|
|
3650
|
+
"description": "Initial rollout in **basis points** (0–10000 = 0%–100%) — `100` here means **1%**, not 100%. Use `rollout_percent` (0–100) below if you'd rather think in percent. Use `0` to create the gate dark and ramp via PATCH after deploy validation.",
|
|
3498
3651
|
"type": "integer",
|
|
3499
3652
|
"minimum": 0,
|
|
3500
3653
|
"maximum": 10000
|
|
3501
3654
|
},
|
|
3655
|
+
"rollout_percent": {
|
|
3656
|
+
"description": "Initial rollout as a **percentage** (0–100, fractional ok). Friendlier alias for `rollout_pct`; converted internally to basis points (e.g. `100` here = 10000 bp = 100%). If both `rollout_pct` and `rollout_percent` are set, `rollout_percent` wins.",
|
|
3657
|
+
"type": "number",
|
|
3658
|
+
"minimum": 0,
|
|
3659
|
+
"maximum": 100
|
|
3660
|
+
},
|
|
3502
3661
|
"rules": {
|
|
3503
3662
|
"default": [],
|
|
3504
3663
|
"description": "Targeting predicates. AND-combined. If non-empty, the gate returns `true` only for callers that satisfy every rule **and** fall under `rollout_pct`.",
|
|
@@ -3523,15 +3682,23 @@
|
|
|
3523
3682
|
"lt",
|
|
3524
3683
|
"lte",
|
|
3525
3684
|
"contains",
|
|
3526
|
-
"regex"
|
|
3685
|
+
"regex",
|
|
3686
|
+
"semver_gt",
|
|
3687
|
+
"semver_gte",
|
|
3688
|
+
"semver_lt",
|
|
3689
|
+
"semver_lte"
|
|
3527
3690
|
],
|
|
3528
|
-
"description": "Comparison operator. Equality: `eq`/`neq`. Set membership: `in`/`not_in` (value is an array). Numeric order: `gt`/`gte`/`lt`/`lte`. String: `contains` (substring), `regex` (JS-flavour pattern, value is the pattern string)."
|
|
3691
|
+
"description": "Comparison operator. Equality: `eq`/`neq`. Set membership: `in`/`not_in` (value is an array). Numeric order: `gt`/`gte`/`lt`/`lte`. Semver order: `semver_gt`/`semver_gte`/`semver_lt`/`semver_lte` (value is a dotted version like `4.2.0`). String: `contains` (substring), `regex` (JS-flavour pattern, value is the pattern string)."
|
|
3529
3692
|
},
|
|
3530
3693
|
"value": {
|
|
3531
|
-
"description": "Operand. Shape depends on `op`: scalar for `eq/neq/gt/gte/lt/lte/contains
|
|
3694
|
+
"description": "Operand. Shape depends on `op`: scalar for `eq/neq/gt/gte/lt/lte/contains/semver_*`; array of scalars for `in/not_in`; string pattern for `regex`."
|
|
3532
3695
|
}
|
|
3533
3696
|
},
|
|
3534
|
-
"required": [
|
|
3697
|
+
"required": [
|
|
3698
|
+
"attr",
|
|
3699
|
+
"op",
|
|
3700
|
+
"value"
|
|
3701
|
+
],
|
|
3535
3702
|
"additionalProperties": false,
|
|
3536
3703
|
"description": "Single targeting predicate. A gate's `rules` array is evaluated with AND semantics; use the gatekeeper `stack` for OR / fall-through logic."
|
|
3537
3704
|
}
|
|
@@ -3580,7 +3747,10 @@
|
|
|
3580
3747
|
"pass": {
|
|
3581
3748
|
"description": "Combinator across `rules`. `all` = AND (default), `any` = OR.",
|
|
3582
3749
|
"type": "string",
|
|
3583
|
-
"enum": [
|
|
3750
|
+
"enum": [
|
|
3751
|
+
"all",
|
|
3752
|
+
"any"
|
|
3753
|
+
]
|
|
3584
3754
|
},
|
|
3585
3755
|
"rules": {
|
|
3586
3756
|
"default": [],
|
|
@@ -3606,15 +3776,23 @@
|
|
|
3606
3776
|
"lt",
|
|
3607
3777
|
"lte",
|
|
3608
3778
|
"contains",
|
|
3609
|
-
"regex"
|
|
3779
|
+
"regex",
|
|
3780
|
+
"semver_gt",
|
|
3781
|
+
"semver_gte",
|
|
3782
|
+
"semver_lt",
|
|
3783
|
+
"semver_lte"
|
|
3610
3784
|
],
|
|
3611
|
-
"description": "Comparison operator. Equality: `eq`/`neq`. Set membership: `in`/`not_in` (value is an array). Numeric order: `gt`/`gte`/`lt`/`lte`. String: `contains` (substring), `regex` (JS-flavour pattern, value is the pattern string)."
|
|
3785
|
+
"description": "Comparison operator. Equality: `eq`/`neq`. Set membership: `in`/`not_in` (value is an array). Numeric order: `gt`/`gte`/`lt`/`lte`. Semver order: `semver_gt`/`semver_gte`/`semver_lt`/`semver_lte` (value is a dotted version like `4.2.0`). String: `contains` (substring), `regex` (JS-flavour pattern, value is the pattern string)."
|
|
3612
3786
|
},
|
|
3613
3787
|
"value": {
|
|
3614
|
-
"description": "Operand. Shape depends on `op`: scalar for `eq/neq/gt/gte/lt/lte/contains
|
|
3788
|
+
"description": "Operand. Shape depends on `op`: scalar for `eq/neq/gt/gte/lt/lte/contains/semver_*`; array of scalars for `in/not_in`; string pattern for `regex`."
|
|
3615
3789
|
}
|
|
3616
3790
|
},
|
|
3617
|
-
"required": [
|
|
3791
|
+
"required": [
|
|
3792
|
+
"attr",
|
|
3793
|
+
"op",
|
|
3794
|
+
"value"
|
|
3795
|
+
],
|
|
3618
3796
|
"additionalProperties": false,
|
|
3619
3797
|
"description": "Single targeting predicate. A gate's `rules` array is evaluated with AND semantics; use the gatekeeper `stack` for OR / fall-through logic."
|
|
3620
3798
|
}
|
|
@@ -3624,7 +3802,11 @@
|
|
|
3624
3802
|
"type": "boolean"
|
|
3625
3803
|
}
|
|
3626
3804
|
},
|
|
3627
|
-
"required": [
|
|
3805
|
+
"required": [
|
|
3806
|
+
"id",
|
|
3807
|
+
"type",
|
|
3808
|
+
"rules"
|
|
3809
|
+
],
|
|
3628
3810
|
"additionalProperties": false,
|
|
3629
3811
|
"description": "Rule-based sub-gate. When matched, evaluation short-circuits and the gate returns `true` for the current caller."
|
|
3630
3812
|
},
|
|
@@ -3675,7 +3857,11 @@
|
|
|
3675
3857
|
"type": "boolean"
|
|
3676
3858
|
}
|
|
3677
3859
|
},
|
|
3678
|
-
"required": [
|
|
3860
|
+
"required": [
|
|
3861
|
+
"id",
|
|
3862
|
+
"type",
|
|
3863
|
+
"rolloutPct"
|
|
3864
|
+
],
|
|
3679
3865
|
"additionalProperties": false,
|
|
3680
3866
|
"description": "Percentage-rollout sub-gate. Hashes `bucketBy` (default `userID`) with `salt` and returns `true` for `rolloutPct/10000` fraction of callers."
|
|
3681
3867
|
}
|
|
@@ -3699,9 +3885,17 @@
|
|
|
3699
3885
|
"maxLength": 2000
|
|
3700
3886
|
},
|
|
3701
3887
|
"folder": {
|
|
3702
|
-
"description": "
|
|
3703
|
-
"
|
|
3704
|
-
|
|
3888
|
+
"description": "Optional folder name used to group items in the dashboard. Part of the SDK lookup key: an item in folder `checkout` named `new-cart` is referenced as `checkout/new-cart` from the SDK.",
|
|
3889
|
+
"anyOf": [
|
|
3890
|
+
{
|
|
3891
|
+
"type": "string",
|
|
3892
|
+
"maxLength": 256,
|
|
3893
|
+
"pattern": "^[a-zA-Z0-9_-]+$"
|
|
3894
|
+
},
|
|
3895
|
+
{
|
|
3896
|
+
"type": "null"
|
|
3897
|
+
}
|
|
3898
|
+
]
|
|
3705
3899
|
},
|
|
3706
3900
|
"group": {
|
|
3707
3901
|
"description": "Group label for dashboard organisation (e.g. team or product area).",
|
|
@@ -3714,7 +3908,12 @@
|
|
|
3714
3908
|
"maxLength": 190
|
|
3715
3909
|
}
|
|
3716
3910
|
},
|
|
3717
|
-
"required": [
|
|
3911
|
+
"required": [
|
|
3912
|
+
"name",
|
|
3913
|
+
"enabled",
|
|
3914
|
+
"rollout_pct",
|
|
3915
|
+
"rules"
|
|
3916
|
+
],
|
|
3718
3917
|
"additionalProperties": false,
|
|
3719
3918
|
"description": "Body for `POST /api/admin/gates`. At minimum supply `name`; everything else has sensible defaults."
|
|
3720
3919
|
},
|
|
@@ -3727,22 +3926,32 @@
|
|
|
3727
3926
|
},
|
|
3728
3927
|
"name": {
|
|
3729
3928
|
"type": "string",
|
|
3730
|
-
"
|
|
3731
|
-
"
|
|
3929
|
+
"maxLength": 128,
|
|
3930
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$",
|
|
3931
|
+
"description": "Stable gate key used by SDKs (`Shipeasy.checkGate(user, '<name>')`). Single segment or `folder.name`. Lowercase letters, digits, `_` or `-`; max 128 chars. Immutable after create — rename = delete + recreate."
|
|
3732
3932
|
}
|
|
3733
3933
|
},
|
|
3734
|
-
"required": [
|
|
3934
|
+
"required": [
|
|
3935
|
+
"id",
|
|
3936
|
+
"name"
|
|
3937
|
+
],
|
|
3735
3938
|
"additionalProperties": false
|
|
3736
3939
|
},
|
|
3737
3940
|
"UpdateGateRequest": {
|
|
3738
3941
|
"type": "object",
|
|
3739
3942
|
"properties": {
|
|
3740
3943
|
"rollout_pct": {
|
|
3741
|
-
"description": "New rollout in basis points (0–10000 = 0%–100%). Omit to leave unchanged.",
|
|
3944
|
+
"description": "New rollout in **basis points** (0–10000 = 0%–100%) — `100` here means **1%**. Use `rollout_percent` (0–100) below for percent. Omit both to leave unchanged.",
|
|
3742
3945
|
"type": "integer",
|
|
3743
3946
|
"minimum": 0,
|
|
3744
3947
|
"maximum": 10000
|
|
3745
3948
|
},
|
|
3949
|
+
"rollout_percent": {
|
|
3950
|
+
"description": "New rollout as a **percentage** (0–100). Friendlier alias for `rollout_pct`; converted internally. Wins over `rollout_pct` if both are supplied. Omit both to leave unchanged.",
|
|
3951
|
+
"type": "number",
|
|
3952
|
+
"minimum": 0,
|
|
3953
|
+
"maximum": 100
|
|
3954
|
+
},
|
|
3746
3955
|
"rules": {
|
|
3747
3956
|
"description": "Replaces the rule list wholesale. To add a value to an `in` rule, send the full new `rules` array with the augmented `value` (e.g. previous `['US','CA']` → `['US','CA','GB']`).",
|
|
3748
3957
|
"type": "array",
|
|
@@ -3766,15 +3975,23 @@
|
|
|
3766
3975
|
"lt",
|
|
3767
3976
|
"lte",
|
|
3768
3977
|
"contains",
|
|
3769
|
-
"regex"
|
|
3978
|
+
"regex",
|
|
3979
|
+
"semver_gt",
|
|
3980
|
+
"semver_gte",
|
|
3981
|
+
"semver_lt",
|
|
3982
|
+
"semver_lte"
|
|
3770
3983
|
],
|
|
3771
|
-
"description": "Comparison operator. Equality: `eq`/`neq`. Set membership: `in`/`not_in` (value is an array). Numeric order: `gt`/`gte`/`lt`/`lte`. String: `contains` (substring), `regex` (JS-flavour pattern, value is the pattern string)."
|
|
3984
|
+
"description": "Comparison operator. Equality: `eq`/`neq`. Set membership: `in`/`not_in` (value is an array). Numeric order: `gt`/`gte`/`lt`/`lte`. Semver order: `semver_gt`/`semver_gte`/`semver_lt`/`semver_lte` (value is a dotted version like `4.2.0`). String: `contains` (substring), `regex` (JS-flavour pattern, value is the pattern string)."
|
|
3772
3985
|
},
|
|
3773
3986
|
"value": {
|
|
3774
|
-
"description": "Operand. Shape depends on `op`: scalar for `eq/neq/gt/gte/lt/lte/contains
|
|
3987
|
+
"description": "Operand. Shape depends on `op`: scalar for `eq/neq/gt/gte/lt/lte/contains/semver_*`; array of scalars for `in/not_in`; string pattern for `regex`."
|
|
3775
3988
|
}
|
|
3776
3989
|
},
|
|
3777
|
-
"required": [
|
|
3990
|
+
"required": [
|
|
3991
|
+
"attr",
|
|
3992
|
+
"op",
|
|
3993
|
+
"value"
|
|
3994
|
+
],
|
|
3778
3995
|
"additionalProperties": false,
|
|
3779
3996
|
"description": "Single targeting predicate. A gate's `rules` array is evaluated with AND semantics; use the gatekeeper `stack` for OR / fall-through logic."
|
|
3780
3997
|
}
|
|
@@ -3821,7 +4038,10 @@
|
|
|
3821
4038
|
"pass": {
|
|
3822
4039
|
"description": "Combinator across `rules`. `all` = AND (default), `any` = OR.",
|
|
3823
4040
|
"type": "string",
|
|
3824
|
-
"enum": [
|
|
4041
|
+
"enum": [
|
|
4042
|
+
"all",
|
|
4043
|
+
"any"
|
|
4044
|
+
]
|
|
3825
4045
|
},
|
|
3826
4046
|
"rules": {
|
|
3827
4047
|
"default": [],
|
|
@@ -3847,15 +4067,23 @@
|
|
|
3847
4067
|
"lt",
|
|
3848
4068
|
"lte",
|
|
3849
4069
|
"contains",
|
|
3850
|
-
"regex"
|
|
4070
|
+
"regex",
|
|
4071
|
+
"semver_gt",
|
|
4072
|
+
"semver_gte",
|
|
4073
|
+
"semver_lt",
|
|
4074
|
+
"semver_lte"
|
|
3851
4075
|
],
|
|
3852
|
-
"description": "Comparison operator. Equality: `eq`/`neq`. Set membership: `in`/`not_in` (value is an array). Numeric order: `gt`/`gte`/`lt`/`lte`. String: `contains` (substring), `regex` (JS-flavour pattern, value is the pattern string)."
|
|
4076
|
+
"description": "Comparison operator. Equality: `eq`/`neq`. Set membership: `in`/`not_in` (value is an array). Numeric order: `gt`/`gte`/`lt`/`lte`. Semver order: `semver_gt`/`semver_gte`/`semver_lt`/`semver_lte` (value is a dotted version like `4.2.0`). String: `contains` (substring), `regex` (JS-flavour pattern, value is the pattern string)."
|
|
3853
4077
|
},
|
|
3854
4078
|
"value": {
|
|
3855
|
-
"description": "Operand. Shape depends on `op`: scalar for `eq/neq/gt/gte/lt/lte/contains
|
|
4079
|
+
"description": "Operand. Shape depends on `op`: scalar for `eq/neq/gt/gte/lt/lte/contains/semver_*`; array of scalars for `in/not_in`; string pattern for `regex`."
|
|
3856
4080
|
}
|
|
3857
4081
|
},
|
|
3858
|
-
"required": [
|
|
4082
|
+
"required": [
|
|
4083
|
+
"attr",
|
|
4084
|
+
"op",
|
|
4085
|
+
"value"
|
|
4086
|
+
],
|
|
3859
4087
|
"additionalProperties": false,
|
|
3860
4088
|
"description": "Single targeting predicate. A gate's `rules` array is evaluated with AND semantics; use the gatekeeper `stack` for OR / fall-through logic."
|
|
3861
4089
|
}
|
|
@@ -3865,7 +4093,11 @@
|
|
|
3865
4093
|
"type": "boolean"
|
|
3866
4094
|
}
|
|
3867
4095
|
},
|
|
3868
|
-
"required": [
|
|
4096
|
+
"required": [
|
|
4097
|
+
"id",
|
|
4098
|
+
"type",
|
|
4099
|
+
"rules"
|
|
4100
|
+
],
|
|
3869
4101
|
"additionalProperties": false,
|
|
3870
4102
|
"description": "Rule-based sub-gate. When matched, evaluation short-circuits and the gate returns `true` for the current caller."
|
|
3871
4103
|
},
|
|
@@ -3916,7 +4148,11 @@
|
|
|
3916
4148
|
"type": "boolean"
|
|
3917
4149
|
}
|
|
3918
4150
|
},
|
|
3919
|
-
"required": [
|
|
4151
|
+
"required": [
|
|
4152
|
+
"id",
|
|
4153
|
+
"type",
|
|
4154
|
+
"rolloutPct"
|
|
4155
|
+
],
|
|
3920
4156
|
"additionalProperties": false,
|
|
3921
4157
|
"description": "Percentage-rollout sub-gate. Hashes `bucketBy` (default `userID`) with `salt` and returns `true` for `rolloutPct/10000` fraction of callers."
|
|
3922
4158
|
}
|
|
@@ -3940,9 +4176,17 @@
|
|
|
3940
4176
|
"maxLength": 2000
|
|
3941
4177
|
},
|
|
3942
4178
|
"folder": {
|
|
3943
|
-
"description": "
|
|
3944
|
-
"
|
|
3945
|
-
|
|
4179
|
+
"description": "Optional folder name used to group items in the dashboard. Part of the SDK lookup key: an item in folder `checkout` named `new-cart` is referenced as `checkout/new-cart` from the SDK.",
|
|
4180
|
+
"anyOf": [
|
|
4181
|
+
{
|
|
4182
|
+
"type": "string",
|
|
4183
|
+
"maxLength": 256,
|
|
4184
|
+
"pattern": "^[a-zA-Z0-9_-]+$"
|
|
4185
|
+
},
|
|
4186
|
+
{
|
|
4187
|
+
"type": "null"
|
|
4188
|
+
}
|
|
4189
|
+
]
|
|
3946
4190
|
},
|
|
3947
4191
|
"group": {
|
|
3948
4192
|
"description": "Group label for dashboard organisation (e.g. team or product area).",
|
|
@@ -3966,7 +4210,9 @@
|
|
|
3966
4210
|
"description": "Gate id that was updated."
|
|
3967
4211
|
}
|
|
3968
4212
|
},
|
|
3969
|
-
"required": [
|
|
4213
|
+
"required": [
|
|
4214
|
+
"id"
|
|
4215
|
+
],
|
|
3970
4216
|
"additionalProperties": false,
|
|
3971
4217
|
"description": "Update returns only the id — re-fetch via `GET /api/admin/gates` for the full row."
|
|
3972
4218
|
},
|
|
@@ -3978,7 +4224,9 @@
|
|
|
3978
4224
|
"const": true
|
|
3979
4225
|
}
|
|
3980
4226
|
},
|
|
3981
|
-
"required": [
|
|
4227
|
+
"required": [
|
|
4228
|
+
"ok"
|
|
4229
|
+
],
|
|
3982
4230
|
"additionalProperties": false
|
|
3983
4231
|
},
|
|
3984
4232
|
"EnableGateResponse": {
|
|
@@ -3991,7 +4239,10 @@
|
|
|
3991
4239
|
"type": "boolean"
|
|
3992
4240
|
}
|
|
3993
4241
|
},
|
|
3994
|
-
"required": [
|
|
4242
|
+
"required": [
|
|
4243
|
+
"id",
|
|
4244
|
+
"enabled"
|
|
4245
|
+
],
|
|
3995
4246
|
"additionalProperties": false
|
|
3996
4247
|
},
|
|
3997
4248
|
"DisableGateResponse": {
|
|
@@ -4004,7 +4255,10 @@
|
|
|
4004
4255
|
"type": "boolean"
|
|
4005
4256
|
}
|
|
4006
4257
|
},
|
|
4007
|
-
"required": [
|
|
4258
|
+
"required": [
|
|
4259
|
+
"id",
|
|
4260
|
+
"enabled"
|
|
4261
|
+
],
|
|
4008
4262
|
"additionalProperties": false
|
|
4009
4263
|
},
|
|
4010
4264
|
"ListExperimentsResponse": {
|
|
@@ -4021,8 +4275,9 @@
|
|
|
4021
4275
|
},
|
|
4022
4276
|
"name": {
|
|
4023
4277
|
"type": "string",
|
|
4024
|
-
"
|
|
4025
|
-
"
|
|
4278
|
+
"maxLength": 128,
|
|
4279
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$",
|
|
4280
|
+
"description": "Stable experiment key. Single segment or `folder.name` (a-z, 0-9, `_`/`-`; max 128 chars). Used by SDKs as `Shipeasy.getExperiment(user, '<name>')`. Immutable after create."
|
|
4026
4281
|
},
|
|
4027
4282
|
"description": {
|
|
4028
4283
|
"anyOf": [
|
|
@@ -4034,6 +4289,16 @@
|
|
|
4034
4289
|
}
|
|
4035
4290
|
]
|
|
4036
4291
|
},
|
|
4292
|
+
"hypothesis": {
|
|
4293
|
+
"anyOf": [
|
|
4294
|
+
{
|
|
4295
|
+
"type": "string"
|
|
4296
|
+
},
|
|
4297
|
+
{
|
|
4298
|
+
"type": "null"
|
|
4299
|
+
}
|
|
4300
|
+
]
|
|
4301
|
+
},
|
|
4037
4302
|
"tag": {
|
|
4038
4303
|
"anyOf": [
|
|
4039
4304
|
{
|
|
@@ -4044,9 +4309,60 @@
|
|
|
4044
4309
|
}
|
|
4045
4310
|
]
|
|
4046
4311
|
},
|
|
4312
|
+
"ownerEmail": {
|
|
4313
|
+
"anyOf": [
|
|
4314
|
+
{
|
|
4315
|
+
"type": "string"
|
|
4316
|
+
},
|
|
4317
|
+
{
|
|
4318
|
+
"type": "null"
|
|
4319
|
+
}
|
|
4320
|
+
]
|
|
4321
|
+
},
|
|
4322
|
+
"audience": {
|
|
4323
|
+
"anyOf": [
|
|
4324
|
+
{
|
|
4325
|
+
"type": "string"
|
|
4326
|
+
},
|
|
4327
|
+
{
|
|
4328
|
+
"type": "null"
|
|
4329
|
+
}
|
|
4330
|
+
]
|
|
4331
|
+
},
|
|
4332
|
+
"bucketBy": {
|
|
4333
|
+
"anyOf": [
|
|
4334
|
+
{
|
|
4335
|
+
"type": "string",
|
|
4336
|
+
"enum": [
|
|
4337
|
+
"user_id",
|
|
4338
|
+
"session_id",
|
|
4339
|
+
"device_id"
|
|
4340
|
+
],
|
|
4341
|
+
"description": "Identifier used as the bucketing key. `user_id` is sticky across sessions."
|
|
4342
|
+
},
|
|
4343
|
+
{
|
|
4344
|
+
"type": "null"
|
|
4345
|
+
}
|
|
4346
|
+
]
|
|
4347
|
+
},
|
|
4348
|
+
"folder": {
|
|
4349
|
+
"anyOf": [
|
|
4350
|
+
{
|
|
4351
|
+
"type": "string"
|
|
4352
|
+
},
|
|
4353
|
+
{
|
|
4354
|
+
"type": "null"
|
|
4355
|
+
}
|
|
4356
|
+
]
|
|
4357
|
+
},
|
|
4047
4358
|
"status": {
|
|
4048
4359
|
"type": "string",
|
|
4049
|
-
"enum": [
|
|
4360
|
+
"enum": [
|
|
4361
|
+
"draft",
|
|
4362
|
+
"running",
|
|
4363
|
+
"stopped",
|
|
4364
|
+
"archived"
|
|
4365
|
+
]
|
|
4050
4366
|
},
|
|
4051
4367
|
"universe": {
|
|
4052
4368
|
"type": "string",
|
|
@@ -4075,7 +4391,11 @@
|
|
|
4075
4391
|
"type": "object",
|
|
4076
4392
|
"additionalProperties": {
|
|
4077
4393
|
"type": "string",
|
|
4078
|
-
"enum": [
|
|
4394
|
+
"enum": [
|
|
4395
|
+
"string",
|
|
4396
|
+
"bool",
|
|
4397
|
+
"number"
|
|
4398
|
+
]
|
|
4079
4399
|
}
|
|
4080
4400
|
},
|
|
4081
4401
|
"groups": {
|
|
@@ -4102,7 +4422,11 @@
|
|
|
4102
4422
|
"additionalProperties": {}
|
|
4103
4423
|
}
|
|
4104
4424
|
},
|
|
4105
|
-
"required": [
|
|
4425
|
+
"required": [
|
|
4426
|
+
"name",
|
|
4427
|
+
"weight",
|
|
4428
|
+
"params"
|
|
4429
|
+
],
|
|
4106
4430
|
"additionalProperties": false,
|
|
4107
4431
|
"description": "One variant in the experiment. Weights across all groups must sum to 10000."
|
|
4108
4432
|
}
|
|
@@ -4152,7 +4476,12 @@
|
|
|
4152
4476
|
"id",
|
|
4153
4477
|
"name",
|
|
4154
4478
|
"description",
|
|
4479
|
+
"hypothesis",
|
|
4155
4480
|
"tag",
|
|
4481
|
+
"ownerEmail",
|
|
4482
|
+
"audience",
|
|
4483
|
+
"bucketBy",
|
|
4484
|
+
"folder",
|
|
4156
4485
|
"status",
|
|
4157
4486
|
"universe",
|
|
4158
4487
|
"targetingGate",
|
|
@@ -4181,7 +4510,10 @@
|
|
|
4181
4510
|
]
|
|
4182
4511
|
}
|
|
4183
4512
|
},
|
|
4184
|
-
"required": [
|
|
4513
|
+
"required": [
|
|
4514
|
+
"data",
|
|
4515
|
+
"next_cursor"
|
|
4516
|
+
],
|
|
4185
4517
|
"additionalProperties": false
|
|
4186
4518
|
},
|
|
4187
4519
|
"GetExperimentResponse": {
|
|
@@ -4193,8 +4525,9 @@
|
|
|
4193
4525
|
},
|
|
4194
4526
|
"name": {
|
|
4195
4527
|
"type": "string",
|
|
4196
|
-
"
|
|
4197
|
-
"
|
|
4528
|
+
"maxLength": 128,
|
|
4529
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$",
|
|
4530
|
+
"description": "Stable experiment key. Single segment or `folder.name` (a-z, 0-9, `_`/`-`; max 128 chars). Used by SDKs as `Shipeasy.getExperiment(user, '<name>')`. Immutable after create."
|
|
4198
4531
|
},
|
|
4199
4532
|
"description": {
|
|
4200
4533
|
"anyOf": [
|
|
@@ -4206,6 +4539,16 @@
|
|
|
4206
4539
|
}
|
|
4207
4540
|
]
|
|
4208
4541
|
},
|
|
4542
|
+
"hypothesis": {
|
|
4543
|
+
"anyOf": [
|
|
4544
|
+
{
|
|
4545
|
+
"type": "string"
|
|
4546
|
+
},
|
|
4547
|
+
{
|
|
4548
|
+
"type": "null"
|
|
4549
|
+
}
|
|
4550
|
+
]
|
|
4551
|
+
},
|
|
4209
4552
|
"tag": {
|
|
4210
4553
|
"anyOf": [
|
|
4211
4554
|
{
|
|
@@ -4216,9 +4559,60 @@
|
|
|
4216
4559
|
}
|
|
4217
4560
|
]
|
|
4218
4561
|
},
|
|
4562
|
+
"ownerEmail": {
|
|
4563
|
+
"anyOf": [
|
|
4564
|
+
{
|
|
4565
|
+
"type": "string"
|
|
4566
|
+
},
|
|
4567
|
+
{
|
|
4568
|
+
"type": "null"
|
|
4569
|
+
}
|
|
4570
|
+
]
|
|
4571
|
+
},
|
|
4572
|
+
"audience": {
|
|
4573
|
+
"anyOf": [
|
|
4574
|
+
{
|
|
4575
|
+
"type": "string"
|
|
4576
|
+
},
|
|
4577
|
+
{
|
|
4578
|
+
"type": "null"
|
|
4579
|
+
}
|
|
4580
|
+
]
|
|
4581
|
+
},
|
|
4582
|
+
"bucketBy": {
|
|
4583
|
+
"anyOf": [
|
|
4584
|
+
{
|
|
4585
|
+
"type": "string",
|
|
4586
|
+
"enum": [
|
|
4587
|
+
"user_id",
|
|
4588
|
+
"session_id",
|
|
4589
|
+
"device_id"
|
|
4590
|
+
],
|
|
4591
|
+
"description": "Identifier used as the bucketing key. `user_id` is sticky across sessions."
|
|
4592
|
+
},
|
|
4593
|
+
{
|
|
4594
|
+
"type": "null"
|
|
4595
|
+
}
|
|
4596
|
+
]
|
|
4597
|
+
},
|
|
4598
|
+
"folder": {
|
|
4599
|
+
"anyOf": [
|
|
4600
|
+
{
|
|
4601
|
+
"type": "string"
|
|
4602
|
+
},
|
|
4603
|
+
{
|
|
4604
|
+
"type": "null"
|
|
4605
|
+
}
|
|
4606
|
+
]
|
|
4607
|
+
},
|
|
4219
4608
|
"status": {
|
|
4220
4609
|
"type": "string",
|
|
4221
|
-
"enum": [
|
|
4610
|
+
"enum": [
|
|
4611
|
+
"draft",
|
|
4612
|
+
"running",
|
|
4613
|
+
"stopped",
|
|
4614
|
+
"archived"
|
|
4615
|
+
]
|
|
4222
4616
|
},
|
|
4223
4617
|
"universe": {
|
|
4224
4618
|
"type": "string",
|
|
@@ -4247,7 +4641,11 @@
|
|
|
4247
4641
|
"type": "object",
|
|
4248
4642
|
"additionalProperties": {
|
|
4249
4643
|
"type": "string",
|
|
4250
|
-
"enum": [
|
|
4644
|
+
"enum": [
|
|
4645
|
+
"string",
|
|
4646
|
+
"bool",
|
|
4647
|
+
"number"
|
|
4648
|
+
]
|
|
4251
4649
|
}
|
|
4252
4650
|
},
|
|
4253
4651
|
"groups": {
|
|
@@ -4274,7 +4672,11 @@
|
|
|
4274
4672
|
"additionalProperties": {}
|
|
4275
4673
|
}
|
|
4276
4674
|
},
|
|
4277
|
-
"required": [
|
|
4675
|
+
"required": [
|
|
4676
|
+
"name",
|
|
4677
|
+
"weight",
|
|
4678
|
+
"params"
|
|
4679
|
+
],
|
|
4278
4680
|
"additionalProperties": false,
|
|
4279
4681
|
"description": "One variant in the experiment. Weights across all groups must sum to 10000."
|
|
4280
4682
|
}
|
|
@@ -4324,7 +4726,12 @@
|
|
|
4324
4726
|
"id",
|
|
4325
4727
|
"name",
|
|
4326
4728
|
"description",
|
|
4729
|
+
"hypothesis",
|
|
4327
4730
|
"tag",
|
|
4731
|
+
"ownerEmail",
|
|
4732
|
+
"audience",
|
|
4733
|
+
"bucketBy",
|
|
4734
|
+
"folder",
|
|
4328
4735
|
"status",
|
|
4329
4736
|
"universe",
|
|
4330
4737
|
"targetingGate",
|
|
@@ -4346,8 +4753,9 @@
|
|
|
4346
4753
|
"properties": {
|
|
4347
4754
|
"name": {
|
|
4348
4755
|
"type": "string",
|
|
4349
|
-
"
|
|
4350
|
-
"
|
|
4756
|
+
"maxLength": 128,
|
|
4757
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$",
|
|
4758
|
+
"description": "Stable experiment key. Single segment or `folder.name` (a-z, 0-9, `_`/`-`; max 128 chars). Used by SDKs as `Shipeasy.getExperiment(user, '<name>')`. Immutable after create."
|
|
4351
4759
|
},
|
|
4352
4760
|
"description": {
|
|
4353
4761
|
"default": null,
|
|
@@ -4362,9 +4770,22 @@
|
|
|
4362
4770
|
}
|
|
4363
4771
|
]
|
|
4364
4772
|
},
|
|
4773
|
+
"hypothesis": {
|
|
4774
|
+
"default": null,
|
|
4775
|
+
"description": "Hypothesis statement shown in the editor. Display-only.",
|
|
4776
|
+
"anyOf": [
|
|
4777
|
+
{
|
|
4778
|
+
"type": "string",
|
|
4779
|
+
"maxLength": 4000
|
|
4780
|
+
},
|
|
4781
|
+
{
|
|
4782
|
+
"type": "null"
|
|
4783
|
+
}
|
|
4784
|
+
]
|
|
4785
|
+
},
|
|
4365
4786
|
"tag": {
|
|
4366
4787
|
"default": null,
|
|
4367
|
-
"description": "
|
|
4788
|
+
"description": "Short tag chip rendered next to the name. Display-only.",
|
|
4368
4789
|
"anyOf": [
|
|
4369
4790
|
{
|
|
4370
4791
|
"type": "string",
|
|
@@ -4375,26 +4796,82 @@
|
|
|
4375
4796
|
}
|
|
4376
4797
|
]
|
|
4377
4798
|
},
|
|
4378
|
-
"
|
|
4379
|
-
"
|
|
4380
|
-
"
|
|
4381
|
-
"
|
|
4799
|
+
"owner_email": {
|
|
4800
|
+
"default": null,
|
|
4801
|
+
"description": "Owner email. Display-only.",
|
|
4802
|
+
"anyOf": [
|
|
4803
|
+
{
|
|
4804
|
+
"type": "string",
|
|
4805
|
+
"maxLength": 254
|
|
4806
|
+
},
|
|
4807
|
+
{
|
|
4808
|
+
"type": "null"
|
|
4809
|
+
}
|
|
4810
|
+
]
|
|
4382
4811
|
},
|
|
4383
|
-
"
|
|
4812
|
+
"audience": {
|
|
4384
4813
|
"default": null,
|
|
4385
|
-
"description": "
|
|
4814
|
+
"description": "Audience label shown in the editor. Display-only.",
|
|
4386
4815
|
"anyOf": [
|
|
4387
4816
|
{
|
|
4388
|
-
"type": "string"
|
|
4817
|
+
"type": "string",
|
|
4818
|
+
"maxLength": 256
|
|
4389
4819
|
},
|
|
4390
4820
|
{
|
|
4391
4821
|
"type": "null"
|
|
4392
4822
|
}
|
|
4393
4823
|
]
|
|
4394
4824
|
},
|
|
4395
|
-
"
|
|
4396
|
-
"default":
|
|
4397
|
-
"
|
|
4825
|
+
"bucket_by": {
|
|
4826
|
+
"default": null,
|
|
4827
|
+
"anyOf": [
|
|
4828
|
+
{
|
|
4829
|
+
"type": "string",
|
|
4830
|
+
"enum": [
|
|
4831
|
+
"user_id",
|
|
4832
|
+
"session_id",
|
|
4833
|
+
"device_id"
|
|
4834
|
+
],
|
|
4835
|
+
"description": "Identifier used as the bucketing key. `user_id` is sticky across sessions."
|
|
4836
|
+
},
|
|
4837
|
+
{
|
|
4838
|
+
"type": "null"
|
|
4839
|
+
}
|
|
4840
|
+
]
|
|
4841
|
+
},
|
|
4842
|
+
"folder": {
|
|
4843
|
+
"description": "Optional folder name used to group items in the dashboard. Part of the SDK lookup key: an item in folder `checkout` named `new-cart` is referenced as `checkout/new-cart` from the SDK.",
|
|
4844
|
+
"anyOf": [
|
|
4845
|
+
{
|
|
4846
|
+
"type": "string",
|
|
4847
|
+
"maxLength": 256,
|
|
4848
|
+
"pattern": "^[a-zA-Z0-9_-]+$"
|
|
4849
|
+
},
|
|
4850
|
+
{
|
|
4851
|
+
"type": "null"
|
|
4852
|
+
}
|
|
4853
|
+
]
|
|
4854
|
+
},
|
|
4855
|
+
"universe": {
|
|
4856
|
+
"type": "string",
|
|
4857
|
+
"minLength": 1,
|
|
4858
|
+
"description": "Name of an existing universe in the project. Returns `422` if the universe doesn't exist."
|
|
4859
|
+
},
|
|
4860
|
+
"targeting_gate": {
|
|
4861
|
+
"default": null,
|
|
4862
|
+
"description": "Optional gate name. Only callers that pass the gate are enrolled in the experiment.",
|
|
4863
|
+
"anyOf": [
|
|
4864
|
+
{
|
|
4865
|
+
"type": "string"
|
|
4866
|
+
},
|
|
4867
|
+
{
|
|
4868
|
+
"type": "null"
|
|
4869
|
+
}
|
|
4870
|
+
]
|
|
4871
|
+
},
|
|
4872
|
+
"allocation_pct": {
|
|
4873
|
+
"default": 0,
|
|
4874
|
+
"description": "Share of the (gated) audience allocated to the experiment, in basis points (0–10000 = 0%–100%). `0` = unallocated. Immutable while the experiment is running.",
|
|
4398
4875
|
"type": "integer",
|
|
4399
4876
|
"minimum": 0,
|
|
4400
4877
|
"maximum": 10000
|
|
@@ -4410,7 +4887,11 @@
|
|
|
4410
4887
|
"type": "object",
|
|
4411
4888
|
"additionalProperties": {
|
|
4412
4889
|
"type": "string",
|
|
4413
|
-
"enum": [
|
|
4890
|
+
"enum": [
|
|
4891
|
+
"string",
|
|
4892
|
+
"bool",
|
|
4893
|
+
"number"
|
|
4894
|
+
]
|
|
4414
4895
|
},
|
|
4415
4896
|
"description": "Map of param-name → scalar type. Defines the shape of `groups[].params`. Example: `{ headline: 'string', show_cta: 'bool' }`."
|
|
4416
4897
|
},
|
|
@@ -4439,7 +4920,11 @@
|
|
|
4439
4920
|
"additionalProperties": {}
|
|
4440
4921
|
}
|
|
4441
4922
|
},
|
|
4442
|
-
"required": [
|
|
4923
|
+
"required": [
|
|
4924
|
+
"name",
|
|
4925
|
+
"weight",
|
|
4926
|
+
"params"
|
|
4927
|
+
],
|
|
4443
4928
|
"additionalProperties": false,
|
|
4444
4929
|
"description": "One variant in the experiment. Weights across all groups must sum to 10000."
|
|
4445
4930
|
},
|
|
@@ -4470,12 +4955,63 @@
|
|
|
4470
4955
|
"default": false,
|
|
4471
4956
|
"description": "Enable sequential testing (always-valid p-values). Requires Premium plan or higher.",
|
|
4472
4957
|
"type": "boolean"
|
|
4958
|
+
},
|
|
4959
|
+
"goal_metric": {
|
|
4960
|
+
"description": "Single goal metric defined inline as a DSL query. The underlying event is auto-created if missing.",
|
|
4961
|
+
"type": "object",
|
|
4962
|
+
"properties": {
|
|
4963
|
+
"name": {
|
|
4964
|
+
"type": "string",
|
|
4965
|
+
"maxLength": 128,
|
|
4966
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$"
|
|
4967
|
+
},
|
|
4968
|
+
"query": {
|
|
4969
|
+
"type": "string",
|
|
4970
|
+
"minLength": 1,
|
|
4971
|
+
"maxLength": 4096,
|
|
4972
|
+
"description": "Metric DSL string, e.g. `count_users(checkout_completed)`."
|
|
4973
|
+
}
|
|
4974
|
+
},
|
|
4975
|
+
"required": [
|
|
4976
|
+
"query"
|
|
4977
|
+
],
|
|
4978
|
+
"additionalProperties": false
|
|
4979
|
+
},
|
|
4980
|
+
"guardrail_metrics": {
|
|
4981
|
+
"default": [],
|
|
4982
|
+
"description": "Up to 10 guardrail metrics defined inline. Each is upserted (event + metric) and attached with role=guardrail.",
|
|
4983
|
+
"maxItems": 10,
|
|
4984
|
+
"type": "array",
|
|
4985
|
+
"items": {
|
|
4986
|
+
"type": "object",
|
|
4987
|
+
"properties": {
|
|
4988
|
+
"name": {
|
|
4989
|
+
"type": "string",
|
|
4990
|
+
"maxLength": 128,
|
|
4991
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$"
|
|
4992
|
+
},
|
|
4993
|
+
"query": {
|
|
4994
|
+
"type": "string",
|
|
4995
|
+
"minLength": 1,
|
|
4996
|
+
"maxLength": 4096,
|
|
4997
|
+
"description": "Metric DSL string, e.g. `count_users(checkout_completed)`."
|
|
4998
|
+
}
|
|
4999
|
+
},
|
|
5000
|
+
"required": [
|
|
5001
|
+
"query"
|
|
5002
|
+
],
|
|
5003
|
+
"additionalProperties": false
|
|
5004
|
+
}
|
|
4473
5005
|
}
|
|
4474
5006
|
},
|
|
4475
5007
|
"required": [
|
|
4476
5008
|
"name",
|
|
4477
5009
|
"description",
|
|
5010
|
+
"hypothesis",
|
|
4478
5011
|
"tag",
|
|
5012
|
+
"owner_email",
|
|
5013
|
+
"audience",
|
|
5014
|
+
"bucket_by",
|
|
4479
5015
|
"universe",
|
|
4480
5016
|
"targeting_gate",
|
|
4481
5017
|
"allocation_pct",
|
|
@@ -4484,7 +5020,8 @@
|
|
|
4484
5020
|
"significance_threshold",
|
|
4485
5021
|
"min_runtime_days",
|
|
4486
5022
|
"min_sample_size",
|
|
4487
|
-
"sequential_testing"
|
|
5023
|
+
"sequential_testing",
|
|
5024
|
+
"guardrail_metrics"
|
|
4488
5025
|
],
|
|
4489
5026
|
"additionalProperties": false,
|
|
4490
5027
|
"description": "Body for `POST /api/admin/experiments`. `name`, `universe`, and `groups` (≥2, weights sum to 10000) required."
|
|
@@ -4498,11 +5035,15 @@
|
|
|
4498
5035
|
},
|
|
4499
5036
|
"name": {
|
|
4500
5037
|
"type": "string",
|
|
4501
|
-
"
|
|
4502
|
-
"
|
|
5038
|
+
"maxLength": 128,
|
|
5039
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$",
|
|
5040
|
+
"description": "Stable experiment key. Single segment or `folder.name` (a-z, 0-9, `_`/`-`; max 128 chars). Used by SDKs as `Shipeasy.getExperiment(user, '<name>')`. Immutable after create."
|
|
4503
5041
|
}
|
|
4504
5042
|
},
|
|
4505
|
-
"required": [
|
|
5043
|
+
"required": [
|
|
5044
|
+
"id",
|
|
5045
|
+
"name"
|
|
5046
|
+
],
|
|
4506
5047
|
"additionalProperties": false
|
|
4507
5048
|
},
|
|
4508
5049
|
"UpdateExperimentRequest": {
|
|
@@ -4510,8 +5051,9 @@
|
|
|
4510
5051
|
"properties": {
|
|
4511
5052
|
"name": {
|
|
4512
5053
|
"type": "string",
|
|
4513
|
-
"
|
|
4514
|
-
"
|
|
5054
|
+
"maxLength": 128,
|
|
5055
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$",
|
|
5056
|
+
"description": "Stable experiment key. Single segment or `folder.name` (a-z, 0-9, `_`/`-`; max 128 chars). Used by SDKs as `Shipeasy.getExperiment(user, '<name>')`. Immutable after create."
|
|
4515
5057
|
},
|
|
4516
5058
|
"description": {
|
|
4517
5059
|
"anyOf": [
|
|
@@ -4524,6 +5066,17 @@
|
|
|
4524
5066
|
}
|
|
4525
5067
|
]
|
|
4526
5068
|
},
|
|
5069
|
+
"hypothesis": {
|
|
5070
|
+
"anyOf": [
|
|
5071
|
+
{
|
|
5072
|
+
"type": "string",
|
|
5073
|
+
"maxLength": 4000
|
|
5074
|
+
},
|
|
5075
|
+
{
|
|
5076
|
+
"type": "null"
|
|
5077
|
+
}
|
|
5078
|
+
]
|
|
5079
|
+
},
|
|
4527
5080
|
"tag": {
|
|
4528
5081
|
"anyOf": [
|
|
4529
5082
|
{
|
|
@@ -4535,6 +5088,57 @@
|
|
|
4535
5088
|
}
|
|
4536
5089
|
]
|
|
4537
5090
|
},
|
|
5091
|
+
"owner_email": {
|
|
5092
|
+
"anyOf": [
|
|
5093
|
+
{
|
|
5094
|
+
"type": "string",
|
|
5095
|
+
"maxLength": 254
|
|
5096
|
+
},
|
|
5097
|
+
{
|
|
5098
|
+
"type": "null"
|
|
5099
|
+
}
|
|
5100
|
+
]
|
|
5101
|
+
},
|
|
5102
|
+
"audience": {
|
|
5103
|
+
"anyOf": [
|
|
5104
|
+
{
|
|
5105
|
+
"type": "string",
|
|
5106
|
+
"maxLength": 256
|
|
5107
|
+
},
|
|
5108
|
+
{
|
|
5109
|
+
"type": "null"
|
|
5110
|
+
}
|
|
5111
|
+
]
|
|
5112
|
+
},
|
|
5113
|
+
"bucket_by": {
|
|
5114
|
+
"anyOf": [
|
|
5115
|
+
{
|
|
5116
|
+
"type": "string",
|
|
5117
|
+
"enum": [
|
|
5118
|
+
"user_id",
|
|
5119
|
+
"session_id",
|
|
5120
|
+
"device_id"
|
|
5121
|
+
],
|
|
5122
|
+
"description": "Identifier used as the bucketing key. `user_id` is sticky across sessions."
|
|
5123
|
+
},
|
|
5124
|
+
{
|
|
5125
|
+
"type": "null"
|
|
5126
|
+
}
|
|
5127
|
+
]
|
|
5128
|
+
},
|
|
5129
|
+
"folder": {
|
|
5130
|
+
"description": "Optional folder name used to group items in the dashboard. Part of the SDK lookup key: an item in folder `checkout` named `new-cart` is referenced as `checkout/new-cart` from the SDK.",
|
|
5131
|
+
"anyOf": [
|
|
5132
|
+
{
|
|
5133
|
+
"type": "string",
|
|
5134
|
+
"maxLength": 256,
|
|
5135
|
+
"pattern": "^[a-zA-Z0-9_-]+$"
|
|
5136
|
+
},
|
|
5137
|
+
{
|
|
5138
|
+
"type": "null"
|
|
5139
|
+
}
|
|
5140
|
+
]
|
|
5141
|
+
},
|
|
4538
5142
|
"targeting_gate": {
|
|
4539
5143
|
"anyOf": [
|
|
4540
5144
|
{
|
|
@@ -4565,7 +5169,11 @@
|
|
|
4565
5169
|
"type": "object",
|
|
4566
5170
|
"additionalProperties": {
|
|
4567
5171
|
"type": "string",
|
|
4568
|
-
"enum": [
|
|
5172
|
+
"enum": [
|
|
5173
|
+
"string",
|
|
5174
|
+
"bool",
|
|
5175
|
+
"number"
|
|
5176
|
+
]
|
|
4569
5177
|
},
|
|
4570
5178
|
"description": "Map of param-name → scalar type. Defines the shape of `groups[].params`. Example: `{ headline: 'string', show_cta: 'bool' }`."
|
|
4571
5179
|
},
|
|
@@ -4595,7 +5203,11 @@
|
|
|
4595
5203
|
"additionalProperties": {}
|
|
4596
5204
|
}
|
|
4597
5205
|
},
|
|
4598
|
-
"required": [
|
|
5206
|
+
"required": [
|
|
5207
|
+
"name",
|
|
5208
|
+
"weight",
|
|
5209
|
+
"params"
|
|
5210
|
+
],
|
|
4599
5211
|
"additionalProperties": false,
|
|
4600
5212
|
"description": "One variant in the experiment. Weights across all groups must sum to 10000."
|
|
4601
5213
|
}
|
|
@@ -4617,6 +5229,52 @@
|
|
|
4617
5229
|
},
|
|
4618
5230
|
"sequential_testing": {
|
|
4619
5231
|
"type": "boolean"
|
|
5232
|
+
},
|
|
5233
|
+
"goal_metric": {
|
|
5234
|
+
"description": "Replaces the goal metric (event auto-upserted).",
|
|
5235
|
+
"type": "object",
|
|
5236
|
+
"properties": {
|
|
5237
|
+
"name": {
|
|
5238
|
+
"type": "string",
|
|
5239
|
+
"maxLength": 128,
|
|
5240
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$"
|
|
5241
|
+
},
|
|
5242
|
+
"query": {
|
|
5243
|
+
"type": "string",
|
|
5244
|
+
"minLength": 1,
|
|
5245
|
+
"maxLength": 4096,
|
|
5246
|
+
"description": "Metric DSL string, e.g. `count_users(checkout_completed)`."
|
|
5247
|
+
}
|
|
5248
|
+
},
|
|
5249
|
+
"required": [
|
|
5250
|
+
"query"
|
|
5251
|
+
],
|
|
5252
|
+
"additionalProperties": false
|
|
5253
|
+
},
|
|
5254
|
+
"guardrail_metrics": {
|
|
5255
|
+
"description": "Replaces the guardrail set wholesale (event auto-upserted per entry).",
|
|
5256
|
+
"maxItems": 10,
|
|
5257
|
+
"type": "array",
|
|
5258
|
+
"items": {
|
|
5259
|
+
"type": "object",
|
|
5260
|
+
"properties": {
|
|
5261
|
+
"name": {
|
|
5262
|
+
"type": "string",
|
|
5263
|
+
"maxLength": 128,
|
|
5264
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$"
|
|
5265
|
+
},
|
|
5266
|
+
"query": {
|
|
5267
|
+
"type": "string",
|
|
5268
|
+
"minLength": 1,
|
|
5269
|
+
"maxLength": 4096,
|
|
5270
|
+
"description": "Metric DSL string, e.g. `count_users(checkout_completed)`."
|
|
5271
|
+
}
|
|
5272
|
+
},
|
|
5273
|
+
"required": [
|
|
5274
|
+
"query"
|
|
5275
|
+
],
|
|
5276
|
+
"additionalProperties": false
|
|
5277
|
+
}
|
|
4620
5278
|
}
|
|
4621
5279
|
},
|
|
4622
5280
|
"additionalProperties": false,
|
|
@@ -4630,7 +5288,9 @@
|
|
|
4630
5288
|
"description": "Experiment id that was updated."
|
|
4631
5289
|
}
|
|
4632
5290
|
},
|
|
4633
|
-
"required": [
|
|
5291
|
+
"required": [
|
|
5292
|
+
"id"
|
|
5293
|
+
],
|
|
4634
5294
|
"additionalProperties": false
|
|
4635
5295
|
},
|
|
4636
5296
|
"DeleteExperimentResponse": {
|
|
@@ -4641,7 +5301,9 @@
|
|
|
4641
5301
|
"const": true
|
|
4642
5302
|
}
|
|
4643
5303
|
},
|
|
4644
|
-
"required": [
|
|
5304
|
+
"required": [
|
|
5305
|
+
"ok"
|
|
5306
|
+
],
|
|
4645
5307
|
"additionalProperties": false
|
|
4646
5308
|
},
|
|
4647
5309
|
"SetExperimentStatusRequest": {
|
|
@@ -4649,11 +5311,18 @@
|
|
|
4649
5311
|
"properties": {
|
|
4650
5312
|
"status": {
|
|
4651
5313
|
"type": "string",
|
|
4652
|
-
"enum": [
|
|
4653
|
-
|
|
5314
|
+
"enum": [
|
|
5315
|
+
"draft",
|
|
5316
|
+
"running",
|
|
5317
|
+
"stopped",
|
|
5318
|
+
"archived"
|
|
5319
|
+
],
|
|
5320
|
+
"description": "Target status. Allowed transitions: `draft → running`, `running → stopped`, `stopped → archived`, `draft → archived`, and `archived → draft` (restore — only if the experiment never started). Restarting an archived experiment directly is not allowed; restore it to draft first, then start."
|
|
4654
5321
|
}
|
|
4655
5322
|
},
|
|
4656
|
-
"required": [
|
|
5323
|
+
"required": [
|
|
5324
|
+
"status"
|
|
5325
|
+
],
|
|
4657
5326
|
"additionalProperties": false,
|
|
4658
5327
|
"description": "Body for `POST /api/admin/experiments/{id}/status`."
|
|
4659
5328
|
},
|
|
@@ -4665,10 +5334,18 @@
|
|
|
4665
5334
|
},
|
|
4666
5335
|
"status": {
|
|
4667
5336
|
"type": "string",
|
|
4668
|
-
"enum": [
|
|
5337
|
+
"enum": [
|
|
5338
|
+
"draft",
|
|
5339
|
+
"running",
|
|
5340
|
+
"stopped",
|
|
5341
|
+
"archived"
|
|
5342
|
+
]
|
|
4669
5343
|
}
|
|
4670
5344
|
},
|
|
4671
|
-
"required": [
|
|
5345
|
+
"required": [
|
|
5346
|
+
"id",
|
|
5347
|
+
"status"
|
|
5348
|
+
],
|
|
4672
5349
|
"additionalProperties": false
|
|
4673
5350
|
},
|
|
4674
5351
|
"SetExperimentMetricsRequest": {
|
|
@@ -4685,17 +5362,26 @@
|
|
|
4685
5362
|
},
|
|
4686
5363
|
"role": {
|
|
4687
5364
|
"type": "string",
|
|
4688
|
-
"enum": [
|
|
5365
|
+
"enum": [
|
|
5366
|
+
"goal",
|
|
5367
|
+
"guardrail",
|
|
5368
|
+
"secondary"
|
|
5369
|
+
],
|
|
4689
5370
|
"description": "Metric role. `goal` drives the decision, `guardrail` blocks ship if degraded, `secondary` is informational."
|
|
4690
5371
|
}
|
|
4691
5372
|
},
|
|
4692
|
-
"required": [
|
|
5373
|
+
"required": [
|
|
5374
|
+
"metric_id",
|
|
5375
|
+
"role"
|
|
5376
|
+
],
|
|
4693
5377
|
"additionalProperties": false
|
|
4694
5378
|
},
|
|
4695
5379
|
"description": "Replacement metrics list — replaces the current attachments wholesale."
|
|
4696
5380
|
}
|
|
4697
5381
|
},
|
|
4698
|
-
"required": [
|
|
5382
|
+
"required": [
|
|
5383
|
+
"metrics"
|
|
5384
|
+
],
|
|
4699
5385
|
"additionalProperties": false,
|
|
4700
5386
|
"description": "Body for `POST /api/admin/experiments/{id}/metrics`. Replaces the experiment's metric attachments wholesale. Returns `422` if any `metric_id` is unknown."
|
|
4701
5387
|
},
|
|
@@ -4715,15 +5401,25 @@
|
|
|
4715
5401
|
},
|
|
4716
5402
|
"role": {
|
|
4717
5403
|
"type": "string",
|
|
4718
|
-
"enum": [
|
|
5404
|
+
"enum": [
|
|
5405
|
+
"goal",
|
|
5406
|
+
"guardrail",
|
|
5407
|
+
"secondary"
|
|
5408
|
+
]
|
|
4719
5409
|
}
|
|
4720
5410
|
},
|
|
4721
|
-
"required": [
|
|
5411
|
+
"required": [
|
|
5412
|
+
"metric_id",
|
|
5413
|
+
"role"
|
|
5414
|
+
],
|
|
4722
5415
|
"additionalProperties": false
|
|
4723
5416
|
}
|
|
4724
5417
|
}
|
|
4725
5418
|
},
|
|
4726
|
-
"required": [
|
|
5419
|
+
"required": [
|
|
5420
|
+
"id",
|
|
5421
|
+
"metrics"
|
|
5422
|
+
],
|
|
4727
5423
|
"additionalProperties": false
|
|
4728
5424
|
},
|
|
4729
5425
|
"GetExperimentResultsResponse": {
|
|
@@ -4737,15 +5433,25 @@
|
|
|
4737
5433
|
},
|
|
4738
5434
|
"name": {
|
|
4739
5435
|
"type": "string",
|
|
4740
|
-
"
|
|
4741
|
-
"
|
|
5436
|
+
"maxLength": 128,
|
|
5437
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$",
|
|
5438
|
+
"description": "Stable experiment key. Single segment or `folder.name` (a-z, 0-9, `_`/`-`; max 128 chars). Used by SDKs as `Shipeasy.getExperiment(user, '<name>')`. Immutable after create."
|
|
4742
5439
|
},
|
|
4743
5440
|
"status": {
|
|
4744
5441
|
"type": "string",
|
|
4745
|
-
"enum": [
|
|
5442
|
+
"enum": [
|
|
5443
|
+
"draft",
|
|
5444
|
+
"running",
|
|
5445
|
+
"stopped",
|
|
5446
|
+
"archived"
|
|
5447
|
+
]
|
|
4746
5448
|
}
|
|
4747
5449
|
},
|
|
4748
|
-
"required": [
|
|
5450
|
+
"required": [
|
|
5451
|
+
"id",
|
|
5452
|
+
"name",
|
|
5453
|
+
"status"
|
|
5454
|
+
],
|
|
4749
5455
|
"additionalProperties": false
|
|
4750
5456
|
},
|
|
4751
5457
|
"results": {
|
|
@@ -4829,7 +5535,10 @@
|
|
|
4829
5535
|
}
|
|
4830
5536
|
}
|
|
4831
5537
|
},
|
|
4832
|
-
"required": [
|
|
5538
|
+
"required": [
|
|
5539
|
+
"experiment",
|
|
5540
|
+
"results"
|
|
5541
|
+
],
|
|
4833
5542
|
"additionalProperties": false
|
|
4834
5543
|
},
|
|
4835
5544
|
"GetExperimentTimeseriesResponse": {
|
|
@@ -4843,15 +5552,25 @@
|
|
|
4843
5552
|
},
|
|
4844
5553
|
"name": {
|
|
4845
5554
|
"type": "string",
|
|
4846
|
-
"
|
|
4847
|
-
"
|
|
5555
|
+
"maxLength": 128,
|
|
5556
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$",
|
|
5557
|
+
"description": "Stable experiment key. Single segment or `folder.name` (a-z, 0-9, `_`/`-`; max 128 chars). Used by SDKs as `Shipeasy.getExperiment(user, '<name>')`. Immutable after create."
|
|
4848
5558
|
},
|
|
4849
5559
|
"status": {
|
|
4850
5560
|
"type": "string",
|
|
4851
|
-
"enum": [
|
|
5561
|
+
"enum": [
|
|
5562
|
+
"draft",
|
|
5563
|
+
"running",
|
|
5564
|
+
"stopped",
|
|
5565
|
+
"archived"
|
|
5566
|
+
]
|
|
4852
5567
|
}
|
|
4853
5568
|
},
|
|
4854
|
-
"required": [
|
|
5569
|
+
"required": [
|
|
5570
|
+
"id",
|
|
5571
|
+
"name",
|
|
5572
|
+
"status"
|
|
5573
|
+
],
|
|
4855
5574
|
"additionalProperties": false
|
|
4856
5575
|
},
|
|
4857
5576
|
"series": {
|
|
@@ -4935,7 +5654,10 @@
|
|
|
4935
5654
|
}
|
|
4936
5655
|
}
|
|
4937
5656
|
},
|
|
4938
|
-
"required": [
|
|
5657
|
+
"required": [
|
|
5658
|
+
"experiment",
|
|
5659
|
+
"series"
|
|
5660
|
+
],
|
|
4939
5661
|
"additionalProperties": false
|
|
4940
5662
|
},
|
|
4941
5663
|
"ReanalyzeExperimentResponse": {
|
|
@@ -4949,7 +5671,10 @@
|
|
|
4949
5671
|
"const": true
|
|
4950
5672
|
}
|
|
4951
5673
|
},
|
|
4952
|
-
"required": [
|
|
5674
|
+
"required": [
|
|
5675
|
+
"id",
|
|
5676
|
+
"queued"
|
|
5677
|
+
],
|
|
4953
5678
|
"additionalProperties": false
|
|
4954
5679
|
},
|
|
4955
5680
|
"ListConfigsResponse": {
|
|
@@ -5008,10 +5733,18 @@
|
|
|
5008
5733
|
"description": "Email/id of the actor who published this version."
|
|
5009
5734
|
}
|
|
5010
5735
|
},
|
|
5011
|
-
"required": [
|
|
5736
|
+
"required": [
|
|
5737
|
+
"version",
|
|
5738
|
+
"publishedAt",
|
|
5739
|
+
"publishedBy"
|
|
5740
|
+
],
|
|
5012
5741
|
"additionalProperties": false
|
|
5013
5742
|
},
|
|
5014
|
-
"required": [
|
|
5743
|
+
"required": [
|
|
5744
|
+
"dev",
|
|
5745
|
+
"staging",
|
|
5746
|
+
"prod"
|
|
5747
|
+
],
|
|
5015
5748
|
"description": "Per-env latest published version metadata."
|
|
5016
5749
|
},
|
|
5017
5750
|
"drafts": {
|
|
@@ -5034,26 +5767,50 @@
|
|
|
5034
5767
|
"description": "Published version the draft was forked from."
|
|
5035
5768
|
}
|
|
5036
5769
|
},
|
|
5037
|
-
"required": [
|
|
5770
|
+
"required": [
|
|
5771
|
+
"updatedAt",
|
|
5772
|
+
"authorEmail",
|
|
5773
|
+
"baseVersion"
|
|
5774
|
+
],
|
|
5038
5775
|
"additionalProperties": false
|
|
5039
5776
|
},
|
|
5040
|
-
"required": [
|
|
5777
|
+
"required": [
|
|
5778
|
+
"dev",
|
|
5779
|
+
"staging",
|
|
5780
|
+
"prod"
|
|
5781
|
+
],
|
|
5041
5782
|
"description": "Per-env active drafts (if any)."
|
|
5042
5783
|
},
|
|
5043
5784
|
"values": {
|
|
5044
5785
|
"description": "Per-env latest published values (only returned by `GET /{id}`, not list).",
|
|
5045
5786
|
"type": "object",
|
|
5046
5787
|
"additionalProperties": {},
|
|
5047
|
-
"required": [
|
|
5788
|
+
"required": [
|
|
5789
|
+
"dev",
|
|
5790
|
+
"staging",
|
|
5791
|
+
"prod"
|
|
5792
|
+
]
|
|
5048
5793
|
},
|
|
5049
5794
|
"draftValues": {
|
|
5050
5795
|
"description": "Per-env draft values (only returned by `GET /{id}`).",
|
|
5051
5796
|
"type": "object",
|
|
5052
5797
|
"additionalProperties": {},
|
|
5053
|
-
"required": [
|
|
5798
|
+
"required": [
|
|
5799
|
+
"dev",
|
|
5800
|
+
"staging",
|
|
5801
|
+
"prod"
|
|
5802
|
+
]
|
|
5054
5803
|
}
|
|
5055
5804
|
},
|
|
5056
|
-
"required": [
|
|
5805
|
+
"required": [
|
|
5806
|
+
"id",
|
|
5807
|
+
"name",
|
|
5808
|
+
"description",
|
|
5809
|
+
"schema",
|
|
5810
|
+
"updatedAt",
|
|
5811
|
+
"envs",
|
|
5812
|
+
"drafts"
|
|
5813
|
+
],
|
|
5057
5814
|
"additionalProperties": false
|
|
5058
5815
|
}
|
|
5059
5816
|
},
|
|
@@ -5068,7 +5825,10 @@
|
|
|
5068
5825
|
]
|
|
5069
5826
|
}
|
|
5070
5827
|
},
|
|
5071
|
-
"required": [
|
|
5828
|
+
"required": [
|
|
5829
|
+
"data",
|
|
5830
|
+
"next_cursor"
|
|
5831
|
+
],
|
|
5072
5832
|
"additionalProperties": false
|
|
5073
5833
|
},
|
|
5074
5834
|
"GetConfigResponse": {
|
|
@@ -5122,10 +5882,18 @@
|
|
|
5122
5882
|
"description": "Email/id of the actor who published this version."
|
|
5123
5883
|
}
|
|
5124
5884
|
},
|
|
5125
|
-
"required": [
|
|
5885
|
+
"required": [
|
|
5886
|
+
"version",
|
|
5887
|
+
"publishedAt",
|
|
5888
|
+
"publishedBy"
|
|
5889
|
+
],
|
|
5126
5890
|
"additionalProperties": false
|
|
5127
5891
|
},
|
|
5128
|
-
"required": [
|
|
5892
|
+
"required": [
|
|
5893
|
+
"dev",
|
|
5894
|
+
"staging",
|
|
5895
|
+
"prod"
|
|
5896
|
+
],
|
|
5129
5897
|
"description": "Per-env latest published version metadata."
|
|
5130
5898
|
},
|
|
5131
5899
|
"drafts": {
|
|
@@ -5148,26 +5916,50 @@
|
|
|
5148
5916
|
"description": "Published version the draft was forked from."
|
|
5149
5917
|
}
|
|
5150
5918
|
},
|
|
5151
|
-
"required": [
|
|
5919
|
+
"required": [
|
|
5920
|
+
"updatedAt",
|
|
5921
|
+
"authorEmail",
|
|
5922
|
+
"baseVersion"
|
|
5923
|
+
],
|
|
5152
5924
|
"additionalProperties": false
|
|
5153
5925
|
},
|
|
5154
|
-
"required": [
|
|
5926
|
+
"required": [
|
|
5927
|
+
"dev",
|
|
5928
|
+
"staging",
|
|
5929
|
+
"prod"
|
|
5930
|
+
],
|
|
5155
5931
|
"description": "Per-env active drafts (if any)."
|
|
5156
5932
|
},
|
|
5157
5933
|
"values": {
|
|
5158
5934
|
"description": "Per-env latest published values (only returned by `GET /{id}`, not list).",
|
|
5159
5935
|
"type": "object",
|
|
5160
5936
|
"additionalProperties": {},
|
|
5161
|
-
"required": [
|
|
5937
|
+
"required": [
|
|
5938
|
+
"dev",
|
|
5939
|
+
"staging",
|
|
5940
|
+
"prod"
|
|
5941
|
+
]
|
|
5162
5942
|
},
|
|
5163
5943
|
"draftValues": {
|
|
5164
5944
|
"description": "Per-env draft values (only returned by `GET /{id}`).",
|
|
5165
5945
|
"type": "object",
|
|
5166
5946
|
"additionalProperties": {},
|
|
5167
|
-
"required": [
|
|
5947
|
+
"required": [
|
|
5948
|
+
"dev",
|
|
5949
|
+
"staging",
|
|
5950
|
+
"prod"
|
|
5951
|
+
]
|
|
5168
5952
|
}
|
|
5169
5953
|
},
|
|
5170
|
-
"required": [
|
|
5954
|
+
"required": [
|
|
5955
|
+
"id",
|
|
5956
|
+
"name",
|
|
5957
|
+
"description",
|
|
5958
|
+
"schema",
|
|
5959
|
+
"updatedAt",
|
|
5960
|
+
"envs",
|
|
5961
|
+
"drafts"
|
|
5962
|
+
],
|
|
5171
5963
|
"additionalProperties": false
|
|
5172
5964
|
},
|
|
5173
5965
|
"CreateConfigRequest": {
|
|
@@ -5183,6 +5975,19 @@
|
|
|
5183
5975
|
"type": "string",
|
|
5184
5976
|
"maxLength": 512
|
|
5185
5977
|
},
|
|
5978
|
+
"folder": {
|
|
5979
|
+
"description": "Optional folder name used to group items in the dashboard. Part of the SDK lookup key: an item in folder `checkout` named `new-cart` is referenced as `checkout/new-cart` from the SDK.",
|
|
5980
|
+
"anyOf": [
|
|
5981
|
+
{
|
|
5982
|
+
"type": "string",
|
|
5983
|
+
"maxLength": 256,
|
|
5984
|
+
"pattern": "^[a-zA-Z0-9_-]+$"
|
|
5985
|
+
},
|
|
5986
|
+
{
|
|
5987
|
+
"type": "null"
|
|
5988
|
+
}
|
|
5989
|
+
]
|
|
5990
|
+
},
|
|
5186
5991
|
"schema": {
|
|
5187
5992
|
"type": "object",
|
|
5188
5993
|
"additionalProperties": {},
|
|
@@ -5194,13 +5999,20 @@
|
|
|
5194
5999
|
{
|
|
5195
6000
|
"type": "object",
|
|
5196
6001
|
"additionalProperties": {},
|
|
5197
|
-
"required": [
|
|
6002
|
+
"required": [
|
|
6003
|
+
"dev",
|
|
6004
|
+
"staging",
|
|
6005
|
+
"prod"
|
|
6006
|
+
]
|
|
5198
6007
|
}
|
|
5199
6008
|
],
|
|
5200
6009
|
"description": "Initial config value. Either a single JSON object applied to every env, or a `{ env: value }` map seeding per-env values. Must match `schema`. Defaults to `{}` on every env when omitted."
|
|
5201
6010
|
}
|
|
5202
6011
|
},
|
|
5203
|
-
"required": [
|
|
6012
|
+
"required": [
|
|
6013
|
+
"name",
|
|
6014
|
+
"schema"
|
|
6015
|
+
],
|
|
5204
6016
|
"additionalProperties": false,
|
|
5205
6017
|
"description": "Body for `POST /api/admin/configs`. `name` + `schema` required."
|
|
5206
6018
|
},
|
|
@@ -5217,7 +6029,10 @@
|
|
|
5217
6029
|
"description": "Stable config key in `folder.name` form (two lowercase segments separated by a dot, e.g. `pricing.tiers`). Used by SDKs as `Shipeasy.getConfig('<name>')`. Immutable after create."
|
|
5218
6030
|
}
|
|
5219
6031
|
},
|
|
5220
|
-
"required": [
|
|
6032
|
+
"required": [
|
|
6033
|
+
"id",
|
|
6034
|
+
"name"
|
|
6035
|
+
],
|
|
5221
6036
|
"additionalProperties": false
|
|
5222
6037
|
},
|
|
5223
6038
|
"UpdateConfigRequest": {
|
|
@@ -5230,6 +6045,19 @@
|
|
|
5230
6045
|
},
|
|
5231
6046
|
"value": {
|
|
5232
6047
|
"description": "Flat value applied to **every** env. Publishes a new version per env. To target one env, use `PUT /{id}/drafts` then `POST /{id}/publish`."
|
|
6048
|
+
},
|
|
6049
|
+
"folder": {
|
|
6050
|
+
"description": "Optional folder name used to group items in the dashboard. Part of the SDK lookup key: an item in folder `checkout` named `new-cart` is referenced as `checkout/new-cart` from the SDK.",
|
|
6051
|
+
"anyOf": [
|
|
6052
|
+
{
|
|
6053
|
+
"type": "string",
|
|
6054
|
+
"maxLength": 256,
|
|
6055
|
+
"pattern": "^[a-zA-Z0-9_-]+$"
|
|
6056
|
+
},
|
|
6057
|
+
{
|
|
6058
|
+
"type": "null"
|
|
6059
|
+
}
|
|
6060
|
+
]
|
|
5233
6061
|
}
|
|
5234
6062
|
},
|
|
5235
6063
|
"additionalProperties": false,
|
|
@@ -5243,7 +6071,9 @@
|
|
|
5243
6071
|
"description": "Config id that was updated."
|
|
5244
6072
|
}
|
|
5245
6073
|
},
|
|
5246
|
-
"required": [
|
|
6074
|
+
"required": [
|
|
6075
|
+
"id"
|
|
6076
|
+
],
|
|
5247
6077
|
"additionalProperties": false
|
|
5248
6078
|
},
|
|
5249
6079
|
"DeleteConfigResponse": {
|
|
@@ -5254,7 +6084,9 @@
|
|
|
5254
6084
|
"const": true
|
|
5255
6085
|
}
|
|
5256
6086
|
},
|
|
5257
|
-
"required": [
|
|
6087
|
+
"required": [
|
|
6088
|
+
"ok"
|
|
6089
|
+
],
|
|
5258
6090
|
"additionalProperties": false
|
|
5259
6091
|
},
|
|
5260
6092
|
"SaveConfigDraftRequest": {
|
|
@@ -5262,14 +6094,21 @@
|
|
|
5262
6094
|
"properties": {
|
|
5263
6095
|
"env": {
|
|
5264
6096
|
"type": "string",
|
|
5265
|
-
"enum": [
|
|
6097
|
+
"enum": [
|
|
6098
|
+
"dev",
|
|
6099
|
+
"staging",
|
|
6100
|
+
"prod"
|
|
6101
|
+
],
|
|
5266
6102
|
"description": "Target environment. One of the project's configured envs (`dev`, `stage`, `prod`)."
|
|
5267
6103
|
},
|
|
5268
6104
|
"value": {
|
|
5269
6105
|
"description": "Draft value to stage on `env`. Validated against the config's current schema."
|
|
5270
6106
|
}
|
|
5271
6107
|
},
|
|
5272
|
-
"required": [
|
|
6108
|
+
"required": [
|
|
6109
|
+
"env",
|
|
6110
|
+
"value"
|
|
6111
|
+
],
|
|
5273
6112
|
"additionalProperties": false,
|
|
5274
6113
|
"description": "Body for `PUT /api/admin/configs/{id}/drafts`. Stages a value for a single env without publishing."
|
|
5275
6114
|
},
|
|
@@ -5281,7 +6120,11 @@
|
|
|
5281
6120
|
},
|
|
5282
6121
|
"env": {
|
|
5283
6122
|
"type": "string",
|
|
5284
|
-
"enum": [
|
|
6123
|
+
"enum": [
|
|
6124
|
+
"dev",
|
|
6125
|
+
"staging",
|
|
6126
|
+
"prod"
|
|
6127
|
+
],
|
|
5285
6128
|
"description": "Target environment. One of the project's configured envs (`dev`, `stage`, `prod`)."
|
|
5286
6129
|
},
|
|
5287
6130
|
"baseVersion": {
|
|
@@ -5294,7 +6137,12 @@
|
|
|
5294
6137
|
"type": "string"
|
|
5295
6138
|
}
|
|
5296
6139
|
},
|
|
5297
|
-
"required": [
|
|
6140
|
+
"required": [
|
|
6141
|
+
"id",
|
|
6142
|
+
"env",
|
|
6143
|
+
"baseVersion",
|
|
6144
|
+
"updatedAt"
|
|
6145
|
+
],
|
|
5298
6146
|
"additionalProperties": false
|
|
5299
6147
|
},
|
|
5300
6148
|
"DiscardConfigDraftRequest": {
|
|
@@ -5302,11 +6150,17 @@
|
|
|
5302
6150
|
"properties": {
|
|
5303
6151
|
"env": {
|
|
5304
6152
|
"type": "string",
|
|
5305
|
-
"enum": [
|
|
6153
|
+
"enum": [
|
|
6154
|
+
"dev",
|
|
6155
|
+
"staging",
|
|
6156
|
+
"prod"
|
|
6157
|
+
],
|
|
5306
6158
|
"description": "Target environment. One of the project's configured envs (`dev`, `stage`, `prod`)."
|
|
5307
6159
|
}
|
|
5308
6160
|
},
|
|
5309
|
-
"required": [
|
|
6161
|
+
"required": [
|
|
6162
|
+
"env"
|
|
6163
|
+
],
|
|
5310
6164
|
"additionalProperties": false,
|
|
5311
6165
|
"description": "Body for `POST /api/admin/configs/{id}/publish` and `DELETE /api/admin/configs/{id}/drafts`. Names the target env."
|
|
5312
6166
|
},
|
|
@@ -5318,7 +6172,9 @@
|
|
|
5318
6172
|
"const": true
|
|
5319
6173
|
}
|
|
5320
6174
|
},
|
|
5321
|
-
"required": [
|
|
6175
|
+
"required": [
|
|
6176
|
+
"ok"
|
|
6177
|
+
],
|
|
5322
6178
|
"additionalProperties": false
|
|
5323
6179
|
},
|
|
5324
6180
|
"PublishConfigDraftRequest": {
|
|
@@ -5326,11 +6182,17 @@
|
|
|
5326
6182
|
"properties": {
|
|
5327
6183
|
"env": {
|
|
5328
6184
|
"type": "string",
|
|
5329
|
-
"enum": [
|
|
6185
|
+
"enum": [
|
|
6186
|
+
"dev",
|
|
6187
|
+
"staging",
|
|
6188
|
+
"prod"
|
|
6189
|
+
],
|
|
5330
6190
|
"description": "Target environment. One of the project's configured envs (`dev`, `stage`, `prod`)."
|
|
5331
6191
|
}
|
|
5332
6192
|
},
|
|
5333
|
-
"required": [
|
|
6193
|
+
"required": [
|
|
6194
|
+
"env"
|
|
6195
|
+
],
|
|
5334
6196
|
"additionalProperties": false,
|
|
5335
6197
|
"description": "Body for `POST /api/admin/configs/{id}/publish` and `DELETE /api/admin/configs/{id}/drafts`. Names the target env."
|
|
5336
6198
|
},
|
|
@@ -5342,7 +6204,11 @@
|
|
|
5342
6204
|
},
|
|
5343
6205
|
"env": {
|
|
5344
6206
|
"type": "string",
|
|
5345
|
-
"enum": [
|
|
6207
|
+
"enum": [
|
|
6208
|
+
"dev",
|
|
6209
|
+
"staging",
|
|
6210
|
+
"prod"
|
|
6211
|
+
],
|
|
5346
6212
|
"description": "Target environment. One of the project's configured envs (`dev`, `stage`, `prod`)."
|
|
5347
6213
|
},
|
|
5348
6214
|
"version": {
|
|
@@ -5352,7 +6218,11 @@
|
|
|
5352
6218
|
"description": "Newly published version on `env`."
|
|
5353
6219
|
}
|
|
5354
6220
|
},
|
|
5355
|
-
"required": [
|
|
6221
|
+
"required": [
|
|
6222
|
+
"id",
|
|
6223
|
+
"env",
|
|
6224
|
+
"version"
|
|
6225
|
+
],
|
|
5356
6226
|
"additionalProperties": false
|
|
5357
6227
|
},
|
|
5358
6228
|
"ListConfigActivityResponse": {
|
|
@@ -5372,7 +6242,11 @@
|
|
|
5372
6242
|
},
|
|
5373
6243
|
"actorType": {
|
|
5374
6244
|
"type": "string",
|
|
5375
|
-
"enum": [
|
|
6245
|
+
"enum": [
|
|
6246
|
+
"user",
|
|
6247
|
+
"cli",
|
|
6248
|
+
"system"
|
|
6249
|
+
]
|
|
5376
6250
|
},
|
|
5377
6251
|
"payload": {
|
|
5378
6252
|
"anyOf": [
|
|
@@ -5387,7 +6261,14 @@
|
|
|
5387
6261
|
"description": "ISO-8601 timestamp."
|
|
5388
6262
|
}
|
|
5389
6263
|
},
|
|
5390
|
-
"required": [
|
|
6264
|
+
"required": [
|
|
6265
|
+
"id",
|
|
6266
|
+
"action",
|
|
6267
|
+
"actorEmail",
|
|
6268
|
+
"actorType",
|
|
6269
|
+
"payload",
|
|
6270
|
+
"createdAt"
|
|
6271
|
+
],
|
|
5391
6272
|
"additionalProperties": false
|
|
5392
6273
|
},
|
|
5393
6274
|
"description": "Recent audit rows for one config, newest first."
|
|
@@ -5450,14 +6331,28 @@
|
|
|
5450
6331
|
"description": "ISO-8601 publish timestamp for this version."
|
|
5451
6332
|
}
|
|
5452
6333
|
},
|
|
5453
|
-
"required": [
|
|
6334
|
+
"required": [
|
|
6335
|
+
"value",
|
|
6336
|
+
"version",
|
|
6337
|
+
"publishedAt"
|
|
6338
|
+
],
|
|
5454
6339
|
"additionalProperties": false
|
|
5455
6340
|
},
|
|
5456
|
-
"required": [
|
|
6341
|
+
"required": [
|
|
6342
|
+
"dev",
|
|
6343
|
+
"staging",
|
|
6344
|
+
"prod"
|
|
6345
|
+
],
|
|
5457
6346
|
"description": "Per-env latest value, switches, version, and publish timestamp."
|
|
5458
6347
|
}
|
|
5459
6348
|
},
|
|
5460
|
-
"required": [
|
|
6349
|
+
"required": [
|
|
6350
|
+
"id",
|
|
6351
|
+
"name",
|
|
6352
|
+
"description",
|
|
6353
|
+
"updatedAt",
|
|
6354
|
+
"envs"
|
|
6355
|
+
],
|
|
5461
6356
|
"additionalProperties": false
|
|
5462
6357
|
}
|
|
5463
6358
|
},
|
|
@@ -5472,7 +6367,10 @@
|
|
|
5472
6367
|
]
|
|
5473
6368
|
}
|
|
5474
6369
|
},
|
|
5475
|
-
"required": [
|
|
6370
|
+
"required": [
|
|
6371
|
+
"data",
|
|
6372
|
+
"next_cursor"
|
|
6373
|
+
],
|
|
5476
6374
|
"additionalProperties": false
|
|
5477
6375
|
},
|
|
5478
6376
|
"GetKillswitchResponse": {
|
|
@@ -5528,14 +6426,28 @@
|
|
|
5528
6426
|
"description": "ISO-8601 publish timestamp for this version."
|
|
5529
6427
|
}
|
|
5530
6428
|
},
|
|
5531
|
-
"required": [
|
|
6429
|
+
"required": [
|
|
6430
|
+
"value",
|
|
6431
|
+
"version",
|
|
6432
|
+
"publishedAt"
|
|
6433
|
+
],
|
|
5532
6434
|
"additionalProperties": false
|
|
5533
6435
|
},
|
|
5534
|
-
"required": [
|
|
6436
|
+
"required": [
|
|
6437
|
+
"dev",
|
|
6438
|
+
"staging",
|
|
6439
|
+
"prod"
|
|
6440
|
+
],
|
|
5535
6441
|
"description": "Per-env latest value, switches, version, and publish timestamp."
|
|
5536
6442
|
}
|
|
5537
6443
|
},
|
|
5538
|
-
"required": [
|
|
6444
|
+
"required": [
|
|
6445
|
+
"id",
|
|
6446
|
+
"name",
|
|
6447
|
+
"description",
|
|
6448
|
+
"updatedAt",
|
|
6449
|
+
"envs"
|
|
6450
|
+
],
|
|
5539
6451
|
"additionalProperties": false
|
|
5540
6452
|
},
|
|
5541
6453
|
"CreateKillswitchRequest": {
|
|
@@ -5551,6 +6463,19 @@
|
|
|
5551
6463
|
"type": "string",
|
|
5552
6464
|
"maxLength": 512
|
|
5553
6465
|
},
|
|
6466
|
+
"folder": {
|
|
6467
|
+
"description": "Optional folder name used to group items in the dashboard. Part of the SDK lookup key: an item in folder `checkout` named `new-cart` is referenced as `checkout/new-cart` from the SDK.",
|
|
6468
|
+
"anyOf": [
|
|
6469
|
+
{
|
|
6470
|
+
"type": "string",
|
|
6471
|
+
"maxLength": 256,
|
|
6472
|
+
"pattern": "^[a-zA-Z0-9_-]+$"
|
|
6473
|
+
},
|
|
6474
|
+
{
|
|
6475
|
+
"type": "null"
|
|
6476
|
+
}
|
|
6477
|
+
]
|
|
6478
|
+
},
|
|
5554
6479
|
"value": {
|
|
5555
6480
|
"description": "Default value applied to every env at creation. Defaults to `false`. Use `true` to ship the killswitch pre-tripped.",
|
|
5556
6481
|
"type": "boolean"
|
|
@@ -5563,7 +6488,9 @@
|
|
|
5563
6488
|
}
|
|
5564
6489
|
}
|
|
5565
6490
|
},
|
|
5566
|
-
"required": [
|
|
6491
|
+
"required": [
|
|
6492
|
+
"name"
|
|
6493
|
+
],
|
|
5567
6494
|
"additionalProperties": false,
|
|
5568
6495
|
"description": "Body for `POST /api/admin/killswitches`. Only `name` is required."
|
|
5569
6496
|
},
|
|
@@ -5580,7 +6507,10 @@
|
|
|
5580
6507
|
"description": "Stable config key in `folder.name` form (two lowercase segments separated by a dot, e.g. `pricing.tiers`). Used by SDKs as `Shipeasy.getConfig('<name>')`. Immutable after create."
|
|
5581
6508
|
}
|
|
5582
6509
|
},
|
|
5583
|
-
"required": [
|
|
6510
|
+
"required": [
|
|
6511
|
+
"id",
|
|
6512
|
+
"name"
|
|
6513
|
+
],
|
|
5584
6514
|
"additionalProperties": false
|
|
5585
6515
|
},
|
|
5586
6516
|
"UpdateKillswitchRequest": {
|
|
@@ -5598,6 +6528,19 @@
|
|
|
5598
6528
|
}
|
|
5599
6529
|
]
|
|
5600
6530
|
},
|
|
6531
|
+
"folder": {
|
|
6532
|
+
"description": "Optional folder name used to group items in the dashboard. Part of the SDK lookup key: an item in folder `checkout` named `new-cart` is referenced as `checkout/new-cart` from the SDK.",
|
|
6533
|
+
"anyOf": [
|
|
6534
|
+
{
|
|
6535
|
+
"type": "string",
|
|
6536
|
+
"maxLength": 256,
|
|
6537
|
+
"pattern": "^[a-zA-Z0-9_-]+$"
|
|
6538
|
+
},
|
|
6539
|
+
{
|
|
6540
|
+
"type": "null"
|
|
6541
|
+
}
|
|
6542
|
+
]
|
|
6543
|
+
},
|
|
5601
6544
|
"value": {
|
|
5602
6545
|
"description": "Flat value applied to every env. Publishes a new version per env when set. Omit to leave values unchanged.",
|
|
5603
6546
|
"type": "boolean"
|
|
@@ -5621,7 +6564,9 @@
|
|
|
5621
6564
|
"description": "Killswitch id that was updated."
|
|
5622
6565
|
}
|
|
5623
6566
|
},
|
|
5624
|
-
"required": [
|
|
6567
|
+
"required": [
|
|
6568
|
+
"id"
|
|
6569
|
+
],
|
|
5625
6570
|
"additionalProperties": false
|
|
5626
6571
|
},
|
|
5627
6572
|
"DeleteKillswitchResponse": {
|
|
@@ -5632,7 +6577,9 @@
|
|
|
5632
6577
|
"const": true
|
|
5633
6578
|
}
|
|
5634
6579
|
},
|
|
5635
|
-
"required": [
|
|
6580
|
+
"required": [
|
|
6581
|
+
"ok"
|
|
6582
|
+
],
|
|
5636
6583
|
"additionalProperties": false
|
|
5637
6584
|
},
|
|
5638
6585
|
"SetKillswitchSwitchRequest": {
|
|
@@ -5640,7 +6587,11 @@
|
|
|
5640
6587
|
"properties": {
|
|
5641
6588
|
"env": {
|
|
5642
6589
|
"type": "string",
|
|
5643
|
-
"enum": [
|
|
6590
|
+
"enum": [
|
|
6591
|
+
"dev",
|
|
6592
|
+
"staging",
|
|
6593
|
+
"prod"
|
|
6594
|
+
],
|
|
5644
6595
|
"description": "Target environment (`dev`/`stage`/`prod`)."
|
|
5645
6596
|
},
|
|
5646
6597
|
"switchKey": {
|
|
@@ -5654,7 +6605,11 @@
|
|
|
5654
6605
|
"description": "New boolean value for this `switchKey` on this `env`."
|
|
5655
6606
|
}
|
|
5656
6607
|
},
|
|
5657
|
-
"required": [
|
|
6608
|
+
"required": [
|
|
6609
|
+
"env",
|
|
6610
|
+
"switchKey",
|
|
6611
|
+
"value"
|
|
6612
|
+
],
|
|
5658
6613
|
"additionalProperties": false,
|
|
5659
6614
|
"description": "Body for `PUT /api/admin/killswitches/{id}/switch`. Sets or updates one switch entry on one env."
|
|
5660
6615
|
},
|
|
@@ -5666,7 +6621,11 @@
|
|
|
5666
6621
|
},
|
|
5667
6622
|
"env": {
|
|
5668
6623
|
"type": "string",
|
|
5669
|
-
"enum": [
|
|
6624
|
+
"enum": [
|
|
6625
|
+
"dev",
|
|
6626
|
+
"staging",
|
|
6627
|
+
"prod"
|
|
6628
|
+
],
|
|
5670
6629
|
"description": "Target environment. One of the project's configured envs (`dev`, `stage`, `prod`)."
|
|
5671
6630
|
},
|
|
5672
6631
|
"switchKey": {
|
|
@@ -5679,7 +6638,12 @@
|
|
|
5679
6638
|
"type": "boolean"
|
|
5680
6639
|
}
|
|
5681
6640
|
},
|
|
5682
|
-
"required": [
|
|
6641
|
+
"required": [
|
|
6642
|
+
"id",
|
|
6643
|
+
"env",
|
|
6644
|
+
"switchKey",
|
|
6645
|
+
"value"
|
|
6646
|
+
],
|
|
5683
6647
|
"additionalProperties": false
|
|
5684
6648
|
},
|
|
5685
6649
|
"UnsetKillswitchSwitchRequest": {
|
|
@@ -5687,7 +6651,11 @@
|
|
|
5687
6651
|
"properties": {
|
|
5688
6652
|
"env": {
|
|
5689
6653
|
"type": "string",
|
|
5690
|
-
"enum": [
|
|
6654
|
+
"enum": [
|
|
6655
|
+
"dev",
|
|
6656
|
+
"staging",
|
|
6657
|
+
"prod"
|
|
6658
|
+
],
|
|
5691
6659
|
"description": "Target environment."
|
|
5692
6660
|
},
|
|
5693
6661
|
"switchKey": {
|
|
@@ -5697,7 +6665,10 @@
|
|
|
5697
6665
|
"description": "Switch key to remove."
|
|
5698
6666
|
}
|
|
5699
6667
|
},
|
|
5700
|
-
"required": [
|
|
6668
|
+
"required": [
|
|
6669
|
+
"env",
|
|
6670
|
+
"switchKey"
|
|
6671
|
+
],
|
|
5701
6672
|
"additionalProperties": false,
|
|
5702
6673
|
"description": "Body for `DELETE /api/admin/killswitches/{id}/switch`. Removes one switch entry from one env."
|
|
5703
6674
|
},
|
|
@@ -5709,7 +6680,11 @@
|
|
|
5709
6680
|
},
|
|
5710
6681
|
"env": {
|
|
5711
6682
|
"type": "string",
|
|
5712
|
-
"enum": [
|
|
6683
|
+
"enum": [
|
|
6684
|
+
"dev",
|
|
6685
|
+
"staging",
|
|
6686
|
+
"prod"
|
|
6687
|
+
],
|
|
5713
6688
|
"description": "Target environment. One of the project's configured envs (`dev`, `stage`, `prod`)."
|
|
5714
6689
|
},
|
|
5715
6690
|
"switchKey": {
|
|
@@ -5723,7 +6698,12 @@
|
|
|
5723
6698
|
"description": "`true` if the entry existed and was removed, `false` if no-op."
|
|
5724
6699
|
}
|
|
5725
6700
|
},
|
|
5726
|
-
"required": [
|
|
6701
|
+
"required": [
|
|
6702
|
+
"id",
|
|
6703
|
+
"env",
|
|
6704
|
+
"switchKey",
|
|
6705
|
+
"removed"
|
|
6706
|
+
],
|
|
5727
6707
|
"additionalProperties": false
|
|
5728
6708
|
},
|
|
5729
6709
|
"ListUniversesResponse": {
|
|
@@ -5740,8 +6720,9 @@
|
|
|
5740
6720
|
},
|
|
5741
6721
|
"name": {
|
|
5742
6722
|
"type": "string",
|
|
5743
|
-
"
|
|
5744
|
-
"
|
|
6723
|
+
"maxLength": 128,
|
|
6724
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$",
|
|
6725
|
+
"description": "Stable universe key. Single segment or `folder.name`. Lowercase letters, digits, `_` or `-`; max 128 chars. Immutable after create."
|
|
5745
6726
|
},
|
|
5746
6727
|
"unitType": {
|
|
5747
6728
|
"type": "string",
|
|
@@ -5771,7 +6752,13 @@
|
|
|
5771
6752
|
"description": "ISO-8601 timestamp of creation."
|
|
5772
6753
|
}
|
|
5773
6754
|
},
|
|
5774
|
-
"required": [
|
|
6755
|
+
"required": [
|
|
6756
|
+
"id",
|
|
6757
|
+
"name",
|
|
6758
|
+
"unitType",
|
|
6759
|
+
"holdoutRange",
|
|
6760
|
+
"createdAt"
|
|
6761
|
+
],
|
|
5775
6762
|
"additionalProperties": false
|
|
5776
6763
|
}
|
|
5777
6764
|
},
|
|
@@ -5786,7 +6773,10 @@
|
|
|
5786
6773
|
]
|
|
5787
6774
|
}
|
|
5788
6775
|
},
|
|
5789
|
-
"required": [
|
|
6776
|
+
"required": [
|
|
6777
|
+
"data",
|
|
6778
|
+
"next_cursor"
|
|
6779
|
+
],
|
|
5790
6780
|
"additionalProperties": false
|
|
5791
6781
|
},
|
|
5792
6782
|
"CreateUniverseRequest": {
|
|
@@ -5794,8 +6784,22 @@
|
|
|
5794
6784
|
"properties": {
|
|
5795
6785
|
"name": {
|
|
5796
6786
|
"type": "string",
|
|
5797
|
-
"
|
|
5798
|
-
"
|
|
6787
|
+
"maxLength": 128,
|
|
6788
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$",
|
|
6789
|
+
"description": "Stable universe key. Single segment or `folder.name`. Lowercase letters, digits, `_` or `-`; max 128 chars. Immutable after create."
|
|
6790
|
+
},
|
|
6791
|
+
"folder": {
|
|
6792
|
+
"description": "Optional folder name used to group items in the dashboard. Part of the SDK lookup key: an item in folder `checkout` named `new-cart` is referenced as `checkout/new-cart` from the SDK.",
|
|
6793
|
+
"anyOf": [
|
|
6794
|
+
{
|
|
6795
|
+
"type": "string",
|
|
6796
|
+
"maxLength": 256,
|
|
6797
|
+
"pattern": "^[a-zA-Z0-9_-]+$"
|
|
6798
|
+
},
|
|
6799
|
+
{
|
|
6800
|
+
"type": "null"
|
|
6801
|
+
}
|
|
6802
|
+
]
|
|
5799
6803
|
},
|
|
5800
6804
|
"unit_type": {
|
|
5801
6805
|
"default": "user_id",
|
|
@@ -5827,7 +6831,11 @@
|
|
|
5827
6831
|
"description": "Inclusive `[lo, hi]` bucket range (0–9999) reserved as the **holdout** — callers hashed into this slice are excluded from every experiment in the universe. `null` disables the holdout. Pro plan or higher required."
|
|
5828
6832
|
}
|
|
5829
6833
|
},
|
|
5830
|
-
"required": [
|
|
6834
|
+
"required": [
|
|
6835
|
+
"name",
|
|
6836
|
+
"unit_type",
|
|
6837
|
+
"holdout_range"
|
|
6838
|
+
],
|
|
5831
6839
|
"additionalProperties": false,
|
|
5832
6840
|
"description": "Body for `POST /api/admin/universes`. Only `name` is required."
|
|
5833
6841
|
},
|
|
@@ -5840,16 +6848,33 @@
|
|
|
5840
6848
|
},
|
|
5841
6849
|
"name": {
|
|
5842
6850
|
"type": "string",
|
|
5843
|
-
"
|
|
5844
|
-
"
|
|
6851
|
+
"maxLength": 128,
|
|
6852
|
+
"pattern": "^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?(?:\\.[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?)?$",
|
|
6853
|
+
"description": "Stable universe key. Single segment or `folder.name`. Lowercase letters, digits, `_` or `-`; max 128 chars. Immutable after create."
|
|
5845
6854
|
}
|
|
5846
6855
|
},
|
|
5847
|
-
"required": [
|
|
6856
|
+
"required": [
|
|
6857
|
+
"id",
|
|
6858
|
+
"name"
|
|
6859
|
+
],
|
|
5848
6860
|
"additionalProperties": false
|
|
5849
6861
|
},
|
|
5850
6862
|
"UpdateUniverseRequest": {
|
|
5851
6863
|
"type": "object",
|
|
5852
6864
|
"properties": {
|
|
6865
|
+
"folder": {
|
|
6866
|
+
"description": "Optional folder name used to group items in the dashboard. Part of the SDK lookup key: an item in folder `checkout` named `new-cart` is referenced as `checkout/new-cart` from the SDK.",
|
|
6867
|
+
"anyOf": [
|
|
6868
|
+
{
|
|
6869
|
+
"type": "string",
|
|
6870
|
+
"maxLength": 256,
|
|
6871
|
+
"pattern": "^[a-zA-Z0-9_-]+$"
|
|
6872
|
+
},
|
|
6873
|
+
{
|
|
6874
|
+
"type": "null"
|
|
6875
|
+
}
|
|
6876
|
+
]
|
|
6877
|
+
},
|
|
5853
6878
|
"holdout_range": {
|
|
5854
6879
|
"anyOf": [
|
|
5855
6880
|
{
|
|
@@ -5885,7 +6910,9 @@
|
|
|
5885
6910
|
"description": "Universe id that was updated."
|
|
5886
6911
|
}
|
|
5887
6912
|
},
|
|
5888
|
-
"required": [
|
|
6913
|
+
"required": [
|
|
6914
|
+
"id"
|
|
6915
|
+
],
|
|
5889
6916
|
"additionalProperties": false
|
|
5890
6917
|
},
|
|
5891
6918
|
"DeleteUniverseResponse": {
|
|
@@ -5896,7 +6923,9 @@
|
|
|
5896
6923
|
"const": true
|
|
5897
6924
|
}
|
|
5898
6925
|
},
|
|
5899
|
-
"required": [
|
|
6926
|
+
"required": [
|
|
6927
|
+
"ok"
|
|
6928
|
+
],
|
|
5900
6929
|
"additionalProperties": false
|
|
5901
6930
|
}
|
|
5902
6931
|
},
|