@shipeasy/openapi 1.6.0 → 2.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.
Files changed (151) hide show
  1. package/README.md +37 -0
  2. package/dist/chunk-643YSMLU.js +1616 -0
  3. package/dist/chunk-643YSMLU.js.map +1 -0
  4. package/dist/chunk-MRW3DJ57.js +3385 -0
  5. package/dist/chunk-MRW3DJ57.js.map +1 -0
  6. package/dist/client-K0ShmsC7.d.ts +11284 -0
  7. package/dist/client.d.ts +1 -0
  8. package/dist/client.js +215 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/custom.d.ts +86 -0
  11. package/dist/custom.js +300 -0
  12. package/dist/custom.js.map +1 -0
  13. package/dist/index.d.ts +29 -41
  14. package/dist/index.js +258 -4375
  15. package/dist/index.js.map +1 -0
  16. package/dist/node-context.d.ts +81 -33
  17. package/dist/node-context.js +98 -44
  18. package/dist/node-context.js.map +1 -0
  19. package/dist/schemas.d.ts +7973 -0
  20. package/dist/schemas.js +1099 -0
  21. package/dist/schemas.js.map +1 -0
  22. package/openapi.json +15922 -3232
  23. package/openapi.yaml +14277 -0
  24. package/package.json +33 -26
  25. package/spec/components/errors.yaml +53 -0
  26. package/spec/components/parameters.yaml +32 -0
  27. package/spec/components/responses.yaml +122 -0
  28. package/spec/components/schemas/alert-rules.yaml +175 -0
  29. package/spec/components/schemas/attributes.yaml +157 -0
  30. package/spec/components/schemas/common.yaml +92 -0
  31. package/spec/components/schemas/configs.yaml +371 -0
  32. package/spec/components/schemas/connectors.yaml +587 -0
  33. package/spec/components/schemas/errors-api.yaml +209 -0
  34. package/spec/components/schemas/events.yaml +321 -0
  35. package/spec/components/schemas/experiments.yaml +865 -0
  36. package/spec/components/schemas/gate-templates.yaml +237 -0
  37. package/spec/components/schemas/gates.yaml +890 -0
  38. package/spec/components/schemas/i18n.yaml +478 -0
  39. package/spec/components/schemas/keys.yaml +186 -0
  40. package/spec/components/schemas/killswitches.yaml +309 -0
  41. package/spec/components/schemas/metrics.yaml +547 -0
  42. package/spec/components/schemas/ops.yaml +1013 -0
  43. package/spec/components/schemas/projects.yaml +222 -0
  44. package/spec/components/schemas/search.yaml +46 -0
  45. package/spec/components/schemas/universes.yaml +127 -0
  46. package/spec/openapi.yaml +367 -0
  47. package/spec/paths/alert-rules.yaml +258 -0
  48. package/spec/paths/attributes.yaml +272 -0
  49. package/spec/paths/configs.yaml +758 -0
  50. package/spec/paths/connectors.yaml +782 -0
  51. package/spec/paths/errors.yaml +382 -0
  52. package/spec/paths/events.yaml +380 -0
  53. package/spec/paths/experiments.yaml +803 -0
  54. package/spec/paths/gate-templates.yaml +267 -0
  55. package/spec/paths/gates.yaml +465 -0
  56. package/spec/paths/i18n.yaml +557 -0
  57. package/spec/paths/keys.yaml +182 -0
  58. package/spec/paths/killswitches.yaml +574 -0
  59. package/spec/paths/metrics.yaml +313 -0
  60. package/spec/paths/ops.yaml +446 -0
  61. package/spec/paths/projects.yaml +210 -0
  62. package/spec/paths/search.yaml +62 -0
  63. package/spec/paths/universes.yaml +255 -0
  64. package/dist/operations/attributes.d.ts +0 -33
  65. package/dist/operations/attributes.js +0 -16
  66. package/dist/operations/cli-adapter.d.ts +0 -35
  67. package/dist/operations/cli-adapter.js +0 -91
  68. package/dist/operations/coerce.d.ts +0 -32
  69. package/dist/operations/coerce.js +0 -53
  70. package/dist/operations/configs.d.ts +0 -28
  71. package/dist/operations/configs.js +0 -119
  72. package/dist/operations/docs.d.ts +0 -37
  73. package/dist/operations/docs.js +0 -39
  74. package/dist/operations/events.d.ts +0 -28
  75. package/dist/operations/events.js +0 -121
  76. package/dist/operations/experiments.d.ts +0 -28
  77. package/dist/operations/experiments.js +0 -280
  78. package/dist/operations/gates.d.ts +0 -28
  79. package/dist/operations/gates.js +0 -132
  80. package/dist/operations/i18n.d.ts +0 -28
  81. package/dist/operations/i18n.js +0 -121
  82. package/dist/operations/index.d.ts +0 -63
  83. package/dist/operations/index.js +0 -1751
  84. package/dist/operations/killswitches.d.ts +0 -28
  85. package/dist/operations/killswitches.js +0 -126
  86. package/dist/operations/mcp-adapter.d.ts +0 -35
  87. package/dist/operations/mcp-adapter.js +0 -94
  88. package/dist/operations/metrics.d.ts +0 -30
  89. package/dist/operations/metrics.js +0 -114
  90. package/dist/operations/ops.d.ts +0 -28
  91. package/dist/operations/ops.js +0 -313
  92. package/dist/operations/projects.d.ts +0 -28
  93. package/dist/operations/projects.js +0 -36
  94. package/dist/operations/sdk-docs.d.ts +0 -28
  95. package/dist/operations/sdk-docs.js +0 -160
  96. package/dist/operations/types.d.ts +0 -138
  97. package/dist/operations/types.js +0 -9
  98. package/dist/operations/universes.d.ts +0 -28
  99. package/dist/operations/universes.js +0 -93
  100. package/dist/operations/util.d.ts +0 -33
  101. package/dist/operations/util.js +0 -9
  102. package/dist/resources/alert-rules.d.ts +0 -50
  103. package/dist/resources/alert-rules.js +0 -75
  104. package/dist/resources/attributes.d.ts +0 -19
  105. package/dist/resources/attributes.js +0 -10
  106. package/dist/resources/configs.d.ts +0 -681
  107. package/dist/resources/configs.js +0 -509
  108. package/dist/resources/events.d.ts +0 -61
  109. package/dist/resources/events.js +0 -42
  110. package/dist/resources/experiments.d.ts +0 -849
  111. package/dist/resources/experiments.js +0 -707
  112. package/dist/resources/gates.d.ts +0 -808
  113. package/dist/resources/gates.js +0 -522
  114. package/dist/resources/i18n.d.ts +0 -84
  115. package/dist/resources/i18n.js +0 -60
  116. package/dist/resources/index.d.ts +0 -2767
  117. package/dist/resources/index.js +0 -2563
  118. package/dist/resources/killswitches.d.ts +0 -436
  119. package/dist/resources/killswitches.js +0 -514
  120. package/dist/resources/metrics.d.ts +0 -54
  121. package/dist/resources/metrics.js +0 -40
  122. package/dist/resources/ops.d.ts +0 -88
  123. package/dist/resources/ops.js +0 -36
  124. package/dist/resources/projects.d.ts +0 -54
  125. package/dist/resources/projects.js +0 -14
  126. package/dist/resources/universes.d.ts +0 -185
  127. package/dist/resources/universes.js +0 -234
  128. package/dist/schemas/alert-rules.d.ts +0 -65
  129. package/dist/schemas/alert-rules.js +0 -37
  130. package/dist/schemas/configs.d.ts +0 -154
  131. package/dist/schemas/configs.js +0 -134
  132. package/dist/schemas/constants.d.ts +0 -6
  133. package/dist/schemas/constants.js +0 -7
  134. package/dist/schemas/experiments.d.ts +0 -229
  135. package/dist/schemas/experiments.js +0 -221
  136. package/dist/schemas/folder.d.ts +0 -10
  137. package/dist/schemas/folder.js +0 -8
  138. package/dist/schemas/gates.d.ts +0 -386
  139. package/dist/schemas/gates.js +0 -190
  140. package/dist/schemas/index.d.ts +0 -11
  141. package/dist/schemas/index.js +0 -762
  142. package/dist/schemas/killswitches.d.ts +0 -110
  143. package/dist/schemas/killswitches.js +0 -226
  144. package/dist/schemas/metric-name.d.ts +0 -5
  145. package/dist/schemas/metric-name.js +0 -6
  146. package/dist/schemas/pagination.d.ts +0 -37
  147. package/dist/schemas/pagination.js +0 -44
  148. package/dist/schemas/universes.d.ts +0 -35
  149. package/dist/schemas/universes.js +0 -55
  150. package/dist/transport.d.ts +0 -30
  151. package/dist/transport.js +0 -44
@@ -0,0 +1,803 @@
1
+ /api/admin/experiments:
2
+ get:
3
+ operationId: listExperiments
4
+ summary: List experiments
5
+ description: |-
6
+ Returns a single page of non-archived experiments ordered by `updated_at desc, id desc`. Use the `cursor` query parameter to paginate.
7
+
8
+ **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`.
9
+ tags:
10
+ - Experiments
11
+ parameters:
12
+ - $ref: ../components/parameters.yaml#/ProjectId
13
+ - $ref: ../components/parameters.yaml#/PaginationLimit
14
+ - $ref: ../components/parameters.yaml#/PaginationCursor
15
+ - name: status
16
+ in: query
17
+ required: false
18
+ description: Filter by lifecycle status. Pass `archived` to return the archive tab; any other value (or omitting it) returns the non-archived experiments.
19
+ schema:
20
+ type: string
21
+ - $ref: ../components/parameters.yaml#/Q
22
+ responses:
23
+ "200":
24
+ description: List experiments
25
+ content:
26
+ application/json:
27
+ schema:
28
+ $ref: ../components/schemas/experiments.yaml#/ListExperimentsResponse
29
+ example:
30
+ data:
31
+ - id: exp_01j7wb12c3d4e5f6g7h8j9k0l1
32
+ name: checkout_button_color
33
+ description: Test green vs. blue CTA on the checkout page.
34
+ tag: checkout
35
+ status: running
36
+ universe: primary_users
37
+ targetingGate: null
38
+ allocationPct: 5000
39
+ salt: 8d3e9a1f6b7c4a5fa1c2b6d3e7c8e3a1
40
+ params:
41
+ cta_color: string
42
+ groups:
43
+ - name: control
44
+ weight: 5000
45
+ params:
46
+ cta_color: blue
47
+ - name: treatment
48
+ weight: 5000
49
+ params:
50
+ cta_color: green
51
+ significanceThreshold: 0.05
52
+ minRuntimeDays: 7
53
+ minSampleSize: 1000
54
+ sequentialTesting: false
55
+ startedAt: 2026-05-01T12:00:00.000Z
56
+ stoppedAt: null
57
+ updatedAt: 2026-05-09T18:22:11.000Z
58
+ next_cursor: null
59
+ "400":
60
+ $ref: ../components/responses.yaml#/BadRequest
61
+ "401":
62
+ $ref: ../components/responses.yaml#/Unauthorized
63
+ "403":
64
+ $ref: ../components/responses.yaml#/Forbidden
65
+ "404":
66
+ $ref: ../components/responses.yaml#/NotFound
67
+ "409":
68
+ $ref: ../components/responses.yaml#/Conflict
69
+ "422":
70
+ $ref: ../components/responses.yaml#/UnprocessableEntity
71
+ x-error-codes:
72
+ - BAD_REQUEST
73
+ - UNAUTHORIZED
74
+ - FORBIDDEN
75
+ x-cli:
76
+ name: list
77
+ post:
78
+ operationId: createExperiment
79
+ summary: Create an experiment
80
+ description: |-
81
+ Creates a new experiment in `draft` status. `name`, `universe`, and `groups` are required; everything else has sensible defaults.
82
+
83
+ Returns `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.
84
+
85
+ **Use cases**
86
+
87
+ - **Minimal 50/50** — `name` + `universe` + two equal-weight groups.
88
+ - **Targeted rollout** — supply `targeting_gate` to restrict the eligible audience and `allocation_pct` to enrol a slice of it.
89
+ - **Multivariant** — three or more groups with weights summing to 10000.
90
+ - **Sequential testing** — `sequential_testing: true` for Premium plans.
91
+ tags:
92
+ - Experiments
93
+ parameters:
94
+ - $ref: ../components/parameters.yaml#/ProjectId
95
+ requestBody:
96
+ required: true
97
+ content:
98
+ application/json:
99
+ schema:
100
+ $ref: ../components/schemas/experiments.yaml#/CreateExperimentRequest
101
+ examples:
102
+ minimal:
103
+ summary: Minimal — two-group 50/50
104
+ description: Smallest valid body. Two groups at 50/50, no allocation, no targeting.
105
+ value:
106
+ name: checkout_button_color
107
+ universe: primary_users
108
+ groups:
109
+ - name: control
110
+ weight: 5000
111
+ - name: treatment
112
+ weight: 5000
113
+ targeted:
114
+ summary: Targeted — gate + allocation + params
115
+ description: Gate the audience with a `targeting_gate`, allocate 50% of it, and parameterise the variants.
116
+ value:
117
+ name: checkout_button_color
118
+ description: Green CTA on checkout for Pro users.
119
+ universe: primary_users
120
+ targeting_gate: pro_plan_only
121
+ allocation_pct: 5000
122
+ params:
123
+ cta_color: string
124
+ groups:
125
+ - name: control
126
+ weight: 5000
127
+ params:
128
+ cta_color: blue
129
+ - name: treatment
130
+ weight: 5000
131
+ params:
132
+ cta_color: green
133
+ multivariant:
134
+ summary: Multivariant — three groups
135
+ description: Three variants splitting 40/30/30. Requires the sum to equal 10000.
136
+ value:
137
+ name: headline_test
138
+ universe: primary_users
139
+ groups:
140
+ - name: control
141
+ weight: 4000
142
+ - name: alt_a
143
+ weight: 3000
144
+ - name: alt_b
145
+ weight: 3000
146
+ sequential:
147
+ summary: Sequential testing — Premium plan
148
+ description: Enable always-valid sequential tests. Requires Premium plan or higher.
149
+ value:
150
+ name: checkout_button_color
151
+ universe: primary_users
152
+ groups:
153
+ - name: control
154
+ weight: 5000
155
+ - name: treatment
156
+ weight: 5000
157
+ sequential_testing: true
158
+ min_runtime_days: 14
159
+ responses:
160
+ "201":
161
+ description: Create an experiment
162
+ content:
163
+ application/json:
164
+ schema:
165
+ $ref: ../components/schemas/experiments.yaml#/CreateExperimentResponse
166
+ example:
167
+ id: exp_01j7wb12c3d4e5f6g7h8j9k0l1
168
+ name: checkout_button_color
169
+ links:
170
+ GetExperiment:
171
+ operationId: getExperiment
172
+ parameters: { id: $response.body#/id }
173
+ UpdateExperiment:
174
+ operationId: updateExperiment
175
+ parameters: { id: $response.body#/id }
176
+ SetExperimentMetrics:
177
+ operationId: setExperimentMetrics
178
+ parameters: { id: $response.body#/id }
179
+ SetExperimentStatus:
180
+ operationId: setExperimentStatus
181
+ parameters: { id: $response.body#/id }
182
+ ReanalyzeExperiment:
183
+ operationId: reanalyzeExperiment
184
+ parameters: { id: $response.body#/id }
185
+ DeleteExperiment:
186
+ operationId: deleteExperiment
187
+ parameters: { id: $response.body#/id }
188
+ "400":
189
+ $ref: ../components/responses.yaml#/BadRequest
190
+ "401":
191
+ $ref: ../components/responses.yaml#/Unauthorized
192
+ "403":
193
+ $ref: ../components/responses.yaml#/Forbidden
194
+ "404":
195
+ $ref: ../components/responses.yaml#/NotFound
196
+ "409":
197
+ $ref: ../components/responses.yaml#/Conflict
198
+ "422":
199
+ $ref: ../components/responses.yaml#/UnprocessableEntity
200
+ x-error-codes:
201
+ - BAD_REQUEST
202
+ - UNAUTHORIZED
203
+ - FORBIDDEN
204
+ - PLAN_REQUIRED
205
+ - ALREADY_EXISTS
206
+ - GROUPS_WEIGHT_SUM
207
+ - REFERENCED_NOT_FOUND
208
+ - VALIDATION
209
+ x-cli:
210
+ name: create
211
+ positional:
212
+ - name
213
+ /api/admin/experiments/{id}:
214
+ get:
215
+ operationId: getExperiment
216
+ summary: Get one experiment
217
+ description: |-
218
+ Returns the full experiment row including groups, params, allocation, and lifecycle timestamps.
219
+
220
+ **Use case:** Fetch one experiment to render the detail page or to inspect its current allocation and group weights.
221
+ tags:
222
+ - Experiments
223
+ parameters:
224
+ - $ref: ../components/parameters.yaml#/ProjectId
225
+ - name: id
226
+ in: path
227
+ required: true
228
+ description: Stable opaque experiment id (`exp_…`) or the experiment's `name`.
229
+ schema:
230
+ $ref: ../components/schemas/common.yaml#/ResourceId
231
+ responses:
232
+ "200":
233
+ description: Get one experiment
234
+ content:
235
+ application/json:
236
+ schema:
237
+ $ref: ../components/schemas/experiments.yaml#/GetExperimentResponse
238
+ example:
239
+ id: exp_01j7wb12c3d4e5f6g7h8j9k0l1
240
+ name: checkout_button_color
241
+ description: Test green vs. blue CTA on the checkout page.
242
+ tag: checkout
243
+ status: running
244
+ universe: primary_users
245
+ targetingGate: null
246
+ allocationPct: 5000
247
+ salt: 8d3e9a1f6b7c4a5fa1c2b6d3e7c8e3a1
248
+ params:
249
+ cta_color: string
250
+ groups:
251
+ - name: control
252
+ weight: 5000
253
+ params:
254
+ cta_color: blue
255
+ - name: treatment
256
+ weight: 5000
257
+ params:
258
+ cta_color: green
259
+ significanceThreshold: 0.05
260
+ minRuntimeDays: 7
261
+ minSampleSize: 1000
262
+ sequentialTesting: false
263
+ startedAt: 2026-05-01T12:00:00.000Z
264
+ stoppedAt: null
265
+ updatedAt: 2026-05-09T18:22:11.000Z
266
+ "400":
267
+ $ref: ../components/responses.yaml#/BadRequest
268
+ "401":
269
+ $ref: ../components/responses.yaml#/Unauthorized
270
+ "403":
271
+ $ref: ../components/responses.yaml#/Forbidden
272
+ "404":
273
+ $ref: ../components/responses.yaml#/NotFound
274
+ "409":
275
+ $ref: ../components/responses.yaml#/Conflict
276
+ "422":
277
+ $ref: ../components/responses.yaml#/UnprocessableEntity
278
+ x-error-codes:
279
+ - BAD_REQUEST
280
+ - UNAUTHORIZED
281
+ - FORBIDDEN
282
+ - NOT_FOUND
283
+ x-cli:
284
+ name: get
285
+ positional:
286
+ - id
287
+ patch:
288
+ operationId: updateExperiment
289
+ summary: Update an experiment
290
+ description: |-
291
+ Partial update. `allocation_pct`, `groups`, `salt`, `universe`, `params` are **immutable while running** — returns `409` if you try. Stop the experiment first.
292
+
293
+ Editing `groups` while in `draft` is fine; weights must still sum to 10000.
294
+
295
+ **Use cases**
296
+
297
+ - **Update metadata** — `description`, `tag`, `targeting_gate` editable any time.
298
+ - **Ramp before launch** — set `allocation_pct` while still in `draft`.
299
+ - **Tighten significance** — `significance_threshold` (Pro+).
300
+ - **Rewire groups** — replace `groups` wholesale while in `draft`; immutable once running.
301
+ tags:
302
+ - Experiments
303
+ parameters:
304
+ - $ref: ../components/parameters.yaml#/ProjectId
305
+ - name: id
306
+ in: path
307
+ required: true
308
+ description: Stable opaque experiment id (`exp_…`) or the experiment's `name`.
309
+ schema:
310
+ $ref: ../components/schemas/common.yaml#/ResourceId
311
+ requestBody:
312
+ required: true
313
+ content:
314
+ application/json:
315
+ schema:
316
+ $ref: ../components/schemas/experiments.yaml#/UpdateExperimentRequest
317
+ examples:
318
+ rampAllocation:
319
+ summary: Ramp allocation — 0 → 50%
320
+ description: Bumps the share of the targeted audience enrolled. Allowed only when the experiment is in `draft`.
321
+ value:
322
+ allocation_pct: 5000
323
+ changeWeights:
324
+ summary: Change group weights
325
+ description: Replace the groups array — weights must still sum to 10000.
326
+ value:
327
+ groups:
328
+ - name: control
329
+ weight: 2500
330
+ - name: treatment
331
+ weight: 7500
332
+ tighterSignificance:
333
+ summary: Tighter significance threshold
334
+ description: Drop the p-value cutoff from 0.05 → 0.01. Requires Pro plan or higher.
335
+ value:
336
+ significance_threshold: 0.01
337
+ updateMetadata:
338
+ summary: Update metadata
339
+ description: Change description/tag/targeting_gate freely on running experiments.
340
+ value:
341
+ description: Bumped to 50% after passing canary on 25%.
342
+ tag: checkout
343
+ responses:
344
+ "200":
345
+ description: Update an experiment
346
+ content:
347
+ application/json:
348
+ schema:
349
+ $ref: ../components/schemas/experiments.yaml#/UpdateExperimentResponse
350
+ example:
351
+ id: exp_01j7wb12c3d4e5f6g7h8j9k0l1
352
+ "400":
353
+ $ref: ../components/responses.yaml#/BadRequest
354
+ "401":
355
+ $ref: ../components/responses.yaml#/Unauthorized
356
+ "403":
357
+ $ref: ../components/responses.yaml#/Forbidden
358
+ "404":
359
+ $ref: ../components/responses.yaml#/NotFound
360
+ "409":
361
+ $ref: ../components/responses.yaml#/Conflict
362
+ "422":
363
+ $ref: ../components/responses.yaml#/UnprocessableEntity
364
+ x-error-codes:
365
+ - BAD_REQUEST
366
+ - UNAUTHORIZED
367
+ - FORBIDDEN
368
+ - PLAN_REQUIRED
369
+ - NOT_FOUND
370
+ - IMMUTABLE_FIELD
371
+ - INVALID_TRANSITION
372
+ - GROUPS_WEIGHT_SUM
373
+ - REFERENCED_NOT_FOUND
374
+ - VALIDATION
375
+ x-cli:
376
+ name: update
377
+ positional:
378
+ - id
379
+ delete:
380
+ operationId: deleteExperiment
381
+ summary: Delete an experiment
382
+ description: |-
383
+ Archives the experiment (soft-delete via status transition). Returns `409` if the experiment is still `running` — stop it first.
384
+
385
+ **Use case:** Tear down an experiment after the analysis is signed off.
386
+ tags:
387
+ - Experiments
388
+ parameters:
389
+ - $ref: ../components/parameters.yaml#/ProjectId
390
+ - name: id
391
+ in: path
392
+ required: true
393
+ description: Stable opaque experiment id (`exp_…`) or the experiment's `name`.
394
+ schema:
395
+ $ref: ../components/schemas/common.yaml#/ResourceId
396
+ responses:
397
+ "200":
398
+ description: Delete an experiment
399
+ content:
400
+ application/json:
401
+ schema:
402
+ $ref: ../components/schemas/experiments.yaml#/DeleteExperimentResponse
403
+ example:
404
+ ok: true
405
+ "400":
406
+ $ref: ../components/responses.yaml#/BadRequest
407
+ "401":
408
+ $ref: ../components/responses.yaml#/Unauthorized
409
+ "403":
410
+ $ref: ../components/responses.yaml#/Forbidden
411
+ "404":
412
+ $ref: ../components/responses.yaml#/NotFound
413
+ "409":
414
+ $ref: ../components/responses.yaml#/Conflict
415
+ "422":
416
+ $ref: ../components/responses.yaml#/UnprocessableEntity
417
+ x-error-codes:
418
+ - BAD_REQUEST
419
+ - UNAUTHORIZED
420
+ - FORBIDDEN
421
+ - NOT_FOUND
422
+ - INVALID_TRANSITION
423
+ x-cli:
424
+ name: archive
425
+ positional:
426
+ - id
427
+ /api/admin/experiments/{id}/status:
428
+ post:
429
+ operationId: setExperimentStatus
430
+ summary: Transition experiment status
431
+ description: |-
432
+ Drives the experiment lifecycle. Allowed transitions:
433
+
434
+ - `draft → running` — starts allocation. Bumps the `startedAt` timestamp.
435
+ - `running → stopped` — halts allocation. Existing exposures stay in the dataset.
436
+ - `stopped → archived` — soft-delete.
437
+ - `draft → archived` — discard an unstarted experiment.
438
+ - `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.
439
+
440
+ Restarting 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`.
441
+
442
+ **Use cases**
443
+
444
+ - **Start** — `{ "status": "running" }` after wiring up the SDK and verifying targeting on staging.
445
+ - **Stop** — `{ "status": "stopped" }` once the experiment hits its `min_runtime_days` and conclusive results land.
446
+ - **Archive** — `{ "status": "archived" }` to soft-delete after sign-off.
447
+ tags:
448
+ - Experiments
449
+ parameters:
450
+ - $ref: ../components/parameters.yaml#/ProjectId
451
+ - name: id
452
+ in: path
453
+ required: true
454
+ description: Stable opaque experiment id (`exp_…`) or the experiment's `name`.
455
+ schema:
456
+ $ref: ../components/schemas/common.yaml#/ResourceId
457
+ requestBody:
458
+ required: true
459
+ content:
460
+ application/json:
461
+ schema:
462
+ $ref: ../components/schemas/experiments.yaml#/SetExperimentStatusRequest
463
+ examples:
464
+ start:
465
+ summary: Start — draft → running
466
+ description: Begins allocation. The experiment counts against the plan's `experiments_running` limit.
467
+ value:
468
+ status: running
469
+ stop:
470
+ summary: Stop — running → stopped
471
+ description: Halts allocation. Existing exposures remain analysable.
472
+ value:
473
+ status: stopped
474
+ archive:
475
+ summary: Archive — stopped → archived
476
+ description: Soft-deletes the experiment. List endpoints exclude archived rows by default.
477
+ value:
478
+ status: archived
479
+ restore:
480
+ summary: Restore — archived → draft
481
+ description: Un-deletes a soft-deleted experiment so it can be re-completed and started. Allowed only if it never ran.
482
+ value:
483
+ status: draft
484
+ responses:
485
+ "200":
486
+ description: Transition experiment status
487
+ content:
488
+ application/json:
489
+ schema:
490
+ $ref: ../components/schemas/experiments.yaml#/SetExperimentStatusResponse
491
+ example:
492
+ id: exp_01j7wb12c3d4e5f6g7h8j9k0l1
493
+ status: running
494
+ "400":
495
+ $ref: ../components/responses.yaml#/BadRequest
496
+ "401":
497
+ $ref: ../components/responses.yaml#/Unauthorized
498
+ "403":
499
+ $ref: ../components/responses.yaml#/Forbidden
500
+ "404":
501
+ $ref: ../components/responses.yaml#/NotFound
502
+ "409":
503
+ $ref: ../components/responses.yaml#/Conflict
504
+ "422":
505
+ $ref: ../components/responses.yaml#/UnprocessableEntity
506
+ x-error-codes:
507
+ - BAD_REQUEST
508
+ - UNAUTHORIZED
509
+ - FORBIDDEN
510
+ - NOT_FOUND
511
+ - INVALID_TRANSITION
512
+ - VALIDATION
513
+ x-cli:
514
+ positional:
515
+ - id
516
+ commands:
517
+ - name: start
518
+ summary: Start an experiment (draft → running)
519
+ preset:
520
+ status: running
521
+ - name: stop
522
+ summary: Stop a running experiment
523
+ preset:
524
+ status: stopped
525
+ - name: restore
526
+ summary: Restore an archived experiment (→ draft)
527
+ preset:
528
+ status: draft
529
+ /api/admin/experiments/{id}/metrics:
530
+ post:
531
+ operationId: setExperimentMetrics
532
+ summary: Attach metrics
533
+ description: |-
534
+ Replaces the experiment's metric attachments wholesale. Each entry pairs an existing `metric_id` with a `role` (`goal` / `guardrail` / `secondary`).
535
+
536
+ Returns `422` if any `metric_id` doesn't exist in the project. Pass `{ metrics: [] }` to detach everything.
537
+
538
+ **Use cases**
539
+
540
+ - **Standard setup** — one `goal`, one or two `guardrail`, optional `secondary` metrics for diagnostics.
541
+ - **Detach all** — send `{ "metrics": [] }` before archiving.
542
+ tags:
543
+ - Experiments
544
+ parameters:
545
+ - $ref: ../components/parameters.yaml#/ProjectId
546
+ - name: id
547
+ in: path
548
+ required: true
549
+ description: Stable opaque experiment id (`exp_…`) or the experiment's `name`.
550
+ schema:
551
+ $ref: ../components/schemas/common.yaml#/ResourceId
552
+ requestBody:
553
+ required: true
554
+ content:
555
+ application/json:
556
+ schema:
557
+ $ref: ../components/schemas/experiments.yaml#/SetExperimentMetricsRequest
558
+ examples:
559
+ standard:
560
+ summary: Standard — one goal + one guardrail
561
+ description: Attaches one decision metric and one safety metric.
562
+ value:
563
+ metrics:
564
+ - metric_id: met_checkout_completed
565
+ role: goal
566
+ - metric_id: met_page_errors
567
+ role: guardrail
568
+ detach:
569
+ summary: Detach all
570
+ description: Send an empty array to clear every metric.
571
+ value:
572
+ metrics: []
573
+ responses:
574
+ "200":
575
+ description: Attach metrics
576
+ content:
577
+ application/json:
578
+ schema:
579
+ $ref: ../components/schemas/experiments.yaml#/SetExperimentMetricsResponse
580
+ example:
581
+ id: exp_01j7wb12c3d4e5f6g7h8j9k0l1
582
+ metrics:
583
+ - metric_id: met_checkout_completed
584
+ role: goal
585
+ - metric_id: met_page_errors
586
+ role: guardrail
587
+ "400":
588
+ $ref: ../components/responses.yaml#/BadRequest
589
+ "401":
590
+ $ref: ../components/responses.yaml#/Unauthorized
591
+ "403":
592
+ $ref: ../components/responses.yaml#/Forbidden
593
+ "404":
594
+ $ref: ../components/responses.yaml#/NotFound
595
+ "409":
596
+ $ref: ../components/responses.yaml#/Conflict
597
+ "422":
598
+ $ref: ../components/responses.yaml#/UnprocessableEntity
599
+ x-error-codes:
600
+ - BAD_REQUEST
601
+ - UNAUTHORIZED
602
+ - FORBIDDEN
603
+ - NOT_FOUND
604
+ - EVENT_PENDING
605
+ - REFERENCED_NOT_FOUND
606
+ - VALIDATION
607
+ x-cli:
608
+ name: set-metrics
609
+ positional:
610
+ - id
611
+ /api/admin/experiments/{id}/results:
612
+ get:
613
+ operationId: getExperimentResults
614
+ summary: Get analysis results
615
+ description: |-
616
+ 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.
617
+
618
+ **Use case:** Render the results table on the experiment detail page or drive an automated decision once a `goal` metric reaches significance.
619
+ tags:
620
+ - Experiments
621
+ parameters:
622
+ - $ref: ../components/parameters.yaml#/ProjectId
623
+ - name: id
624
+ in: path
625
+ required: true
626
+ description: Stable opaque experiment id (`exp_…`) or the experiment's `name`.
627
+ schema:
628
+ $ref: ../components/schemas/common.yaml#/ResourceId
629
+ responses:
630
+ "200":
631
+ description: Get analysis results
632
+ content:
633
+ application/json:
634
+ schema:
635
+ $ref: ../components/schemas/experiments.yaml#/GetExperimentResultsResponse
636
+ example:
637
+ experiment:
638
+ id: exp_01j7wb12c3d4e5f6g7h8j9k0l1
639
+ name: checkout_button_color
640
+ status: running
641
+ results:
642
+ - metric: checkout_completed
643
+ group_name: control
644
+ ds: 2026-05-09
645
+ n: 12421
646
+ mean: 0.1834
647
+ delta_pct: null
648
+ p_value: null
649
+ srm_detected: 0
650
+ - metric: checkout_completed
651
+ group_name: treatment
652
+ ds: 2026-05-09
653
+ n: 12519
654
+ mean: 0.1922
655
+ delta_pct: 4.8
656
+ p_value: 0.018
657
+ srm_detected: 0
658
+ verdict: ship
659
+ "400":
660
+ $ref: ../components/responses.yaml#/BadRequest
661
+ "401":
662
+ $ref: ../components/responses.yaml#/Unauthorized
663
+ "403":
664
+ $ref: ../components/responses.yaml#/Forbidden
665
+ "404":
666
+ $ref: ../components/responses.yaml#/NotFound
667
+ "409":
668
+ $ref: ../components/responses.yaml#/Conflict
669
+ "422":
670
+ $ref: ../components/responses.yaml#/UnprocessableEntity
671
+ x-error-codes:
672
+ - BAD_REQUEST
673
+ - UNAUTHORIZED
674
+ - FORBIDDEN
675
+ - NOT_FOUND
676
+ x-cli:
677
+ name: results
678
+ positional:
679
+ - id
680
+ /api/admin/experiments/{id}/timeseries:
681
+ get:
682
+ operationId: getExperimentTimeseries
683
+ summary: Get analysis timeseries
684
+ description: |-
685
+ Same row shape as `/results`, but returns every daily slice rather than the latest. Filter to a single metric with the `metric` query parameter.
686
+
687
+ **Use case:** Drive a chart of metric movement over the experiment runtime, or sanity-check the lift is monotonic before deciding.
688
+ tags:
689
+ - Experiments
690
+ parameters:
691
+ - $ref: ../components/parameters.yaml#/ProjectId
692
+ - name: id
693
+ in: path
694
+ required: true
695
+ description: Stable opaque experiment id (`exp_…`) or the experiment's `name`.
696
+ schema:
697
+ $ref: ../components/schemas/common.yaml#/ResourceId
698
+ - name: metric
699
+ in: query
700
+ required: false
701
+ description: Optional metric name to filter the series.
702
+ schema:
703
+ type: string
704
+ responses:
705
+ "200":
706
+ description: Get analysis timeseries
707
+ content:
708
+ application/json:
709
+ schema:
710
+ $ref: ../components/schemas/experiments.yaml#/GetExperimentTimeseriesResponse
711
+ example:
712
+ experiment:
713
+ id: exp_01j7wb12c3d4e5f6g7h8j9k0l1
714
+ name: checkout_button_color
715
+ status: running
716
+ series:
717
+ - metric: checkout_completed
718
+ group_name: treatment
719
+ ds: 2026-05-08
720
+ n: 11200
721
+ mean: 0.1903
722
+ delta_pct: 3.9
723
+ p_value: 0.034
724
+ srm_detected: 0
725
+ - metric: checkout_completed
726
+ group_name: treatment
727
+ ds: 2026-05-09
728
+ n: 12519
729
+ mean: 0.1922
730
+ delta_pct: 4.8
731
+ p_value: 0.018
732
+ srm_detected: 0
733
+ "400":
734
+ $ref: ../components/responses.yaml#/BadRequest
735
+ "401":
736
+ $ref: ../components/responses.yaml#/Unauthorized
737
+ "403":
738
+ $ref: ../components/responses.yaml#/Forbidden
739
+ "404":
740
+ $ref: ../components/responses.yaml#/NotFound
741
+ "409":
742
+ $ref: ../components/responses.yaml#/Conflict
743
+ "422":
744
+ $ref: ../components/responses.yaml#/UnprocessableEntity
745
+ x-error-codes:
746
+ - BAD_REQUEST
747
+ - UNAUTHORIZED
748
+ - FORBIDDEN
749
+ - NOT_FOUND
750
+ x-cli:
751
+ name: timeseries
752
+ positional:
753
+ - id
754
+ /api/admin/experiments/{id}/reanalyze:
755
+ post:
756
+ operationId: reanalyzeExperiment
757
+ summary: Re-queue analysis
758
+ description: |-
759
+ 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.
760
+
761
+ **Use case:** Force-refresh results after wiring up a new metric without waiting for the next nightly cron tick.
762
+ tags:
763
+ - Experiments
764
+ parameters:
765
+ - $ref: ../components/parameters.yaml#/ProjectId
766
+ - name: id
767
+ in: path
768
+ required: true
769
+ description: Stable opaque experiment id (`exp_…`) or the experiment's `name`.
770
+ schema:
771
+ $ref: ../components/schemas/common.yaml#/ResourceId
772
+ responses:
773
+ "200":
774
+ description: Re-queue analysis
775
+ content:
776
+ application/json:
777
+ schema:
778
+ $ref: ../components/schemas/experiments.yaml#/ReanalyzeExperimentResponse
779
+ example:
780
+ id: exp_01j7wb12c3d4e5f6g7h8j9k0l1
781
+ queued: true
782
+ "400":
783
+ $ref: ../components/responses.yaml#/BadRequest
784
+ "401":
785
+ $ref: ../components/responses.yaml#/Unauthorized
786
+ "403":
787
+ $ref: ../components/responses.yaml#/Forbidden
788
+ "404":
789
+ $ref: ../components/responses.yaml#/NotFound
790
+ "409":
791
+ $ref: ../components/responses.yaml#/Conflict
792
+ "422":
793
+ $ref: ../components/responses.yaml#/UnprocessableEntity
794
+ x-error-codes:
795
+ - BAD_REQUEST
796
+ - UNAUTHORIZED
797
+ - FORBIDDEN
798
+ - NOT_FOUND
799
+ - VALIDATION
800
+ x-cli:
801
+ name: reanalyze
802
+ positional:
803
+ - id