@shipeasy/openapi 1.6.0 → 2.1.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-EPLLHLZN.js +1616 -0
  3. package/dist/chunk-EPLLHLZN.js.map +1 -0
  4. package/dist/chunk-SPH5HWCD.js +3326 -0
  5. package/dist/chunk-SPH5HWCD.js.map +1 -0
  6. package/dist/client-pVkoo3Bf.d.ts +11186 -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 +64 -0
  11. package/dist/custom.js +292 -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 +7920 -0
  20. package/dist/schemas.js +1083 -0
  21. package/dist/schemas.js.map +1 -0
  22. package/openapi.json +15297 -3044
  23. package/openapi.yaml +13979 -0
  24. package/package.json +33 -26
  25. package/spec/components/errors.yaml +53 -0
  26. package/spec/components/parameters.yaml +24 -0
  27. package/spec/components/responses.yaml +107 -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 +87 -0
  31. package/spec/components/schemas/configs.yaml +371 -0
  32. package/spec/components/schemas/connectors.yaml +593 -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 +198 -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 +1011 -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 +348 -0
  47. package/spec/paths/alert-rules.yaml +250 -0
  48. package/spec/paths/attributes.yaml +261 -0
  49. package/spec/paths/configs.yaml +744 -0
  50. package/spec/paths/connectors.yaml +748 -0
  51. package/spec/paths/errors.yaml +382 -0
  52. package/spec/paths/events.yaml +366 -0
  53. package/spec/paths/experiments.yaml +777 -0
  54. package/spec/paths/gate-templates.yaml +263 -0
  55. package/spec/paths/gates.yaml +451 -0
  56. package/spec/paths/i18n.yaml +544 -0
  57. package/spec/paths/keys.yaml +181 -0
  58. package/spec/paths/killswitches.yaml +557 -0
  59. package/spec/paths/metrics.yaml +302 -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 +247 -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,348 @@
1
+ openapi: 3.2.0
2
+ info:
3
+ title: Shipeasy Admin API
4
+ version: 2.0.0
5
+ description: |-
6
+ REST API for managing feature gates, experiments, configs, universes, and killswitches in a Shipeasy project. Authenticate with an admin SDK key (`Authorization: Bearer sdk_admin_…`) and scope every request to a project via the `X-Project-Id` header.
7
+
8
+ Mint admin keys via `POST /api/admin/keys` with `type: "admin"`. Keys expire after 90 days; rotate with the `revoke` action.
9
+ contact:
10
+ name: Shipeasy
11
+ url: https://shipeasy.ai
12
+ license:
13
+ name: Proprietary
14
+ identifier: LicenseRef-Proprietary
15
+ servers:
16
+ - url: https://shipeasy.ai
17
+ description: Production
18
+ - url: http://localhost:3000
19
+ description: Local Next.js dev server
20
+ security:
21
+ - bearerSdkKey: []
22
+ tags:
23
+ - name: Release
24
+ summary: Feature delivery
25
+ kind: nav
26
+ description: Flags, kill switches, dynamic configs, experiments, and the universes they bucket in — the feature-delivery surface.
27
+ - name: Flags
28
+ parent: Release
29
+ description: |-
30
+ Feature gates: boolean flags evaluated at runtime against project rules + a percentage rollout.
31
+
32
+ **Identity.** Each gate is keyed by a stable `name` (a-z, 0-9, `_`/`-`, max 64 chars) which is what SDKs pass to `Shipeasy.checkGate(user, '<name>')`. The `name` is immutable — rename means delete + recreate.
33
+
34
+ **Evaluation model.** A gate returns `true` when (a) `enabled` is true, and (b) the caller satisfies the gate's rules. There are two evaluation shapes:
35
+ - **Flat** — `rules` (AND-combined predicates) gate the caller, then `rollout_pct` (basis points, 0–10000) hashes them into a bucket. Used for simple `is in X% rollout` gates.
36
+ - **Gatekeeper stack** — an ordered array of `condition` and `rollout` sub-gates, evaluated top-to-bottom; first match wins. Used to express `internal-only ∪ 1% beta ∪ 50% public` in one gate. When `stack` is present it takes precedence over the flat fields.
37
+
38
+ **Rules.** Each rule is `{ attr, op, value }`. Supported ops: `eq`, `neq`, `in`, `not_in`, `gt`, `gte`, `lt`, `lte`, `contains`, `regex`. Attribute names match the keys on the SDK evaluation context (e.g. `country`, `plan`, `email`).
39
+
40
+ **Rollout basis points.** `rollout_pct` is in **basis points**, not percent. `0` = 0%, `100` = 1%, `5000` = 50%, `10000` = 100%. This allows sub-1% precision (e.g. `7` = 0.07%).
41
+
42
+ **Lifecycle.** Create dark (`rollout_pct: 0`) → attach rules → ramp via PATCH → flip kill-switch via `disable`/`enable` → delete once retired. Deletion is blocked while a running experiment references the gate as a targeting gate.
43
+ - name: Killswitch
44
+ parent: Release
45
+ x-cli:
46
+ aliases:
47
+ - ks
48
+ description: |-
49
+ Killswitches: per-env boolean overrides for kill-style operational toggles. Optimised for incident response — no rules, no rollout, just a flat boolean (plus optional per-key overrides) versioned per environment.
50
+
51
+ **Identity.** Each killswitch is keyed by `name` in `folder.name` form (e.g. `payments.checkout`). Immutable after create.
52
+
53
+ **Per-env values.** Every killswitch stores one version stream per env (`dev`, `stage`, `prod`). A `PATCH` with `value`/`switches` applies to **every** env in one shot (publishes a new version per env). To touch a single env, use `PUT /{id}/switch` and friends.
54
+
55
+ **Switches map.** Optional `switches: { key: bool }` overrides the flat `value` for specific named call sites — useful for region/feature-scoped kills.
56
+
57
+ **Versioning.** Each publish (create, update, set-switch, unset-switch) bumps the per-env `version` monotonically. SDKs deliver the latest published version.
58
+ - name: Configs
59
+ parent: Release
60
+ description: |-
61
+ Dynamic configs: JSON-Schema-validated structured values delivered to SDKs and editable per environment with a draft/publish workflow.
62
+
63
+ **Identity.** Each config is keyed by `name` in `folder.name` form (e.g. `pricing.tiers`). Immutable after create.
64
+
65
+ **Schema-first.** Every config carries a JSON Schema (draft 2020-12, top-level `type: 'object'`). Every published value is validated against it.
66
+
67
+ **Drafts → publish.** Per-env edits go through `PUT /{id}/drafts` (stages a value) then `POST /{id}/publish` (promotes to a new version). The flat `PATCH /{id}` republishes on **every** env in one shot — bypassing drafts.
68
+
69
+ **Versioning.** Each publish bumps the per-env `version` monotonically. SDKs deliver the latest published version for each env.
70
+ - name: Experiments
71
+ parent: Release
72
+ description: |-
73
+ A/B/n experiments: randomised group assignment plus the analysis pipeline (t-test, sequential testing, SRM detection) on top of a universe.
74
+
75
+ **Identity.** Stable `name` (a-z, 0-9, `_`/`-`, max 64 chars). Immutable after create.
76
+
77
+ **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.
78
+
79
+ **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.
80
+
81
+ **Immutable while running.** `allocation_pct`, `groups`, `salt`, `universe`, `params` cannot be edited on a running experiment — stop it first.
82
+
83
+ **Metrics.** Attach via `POST /{id}/metrics`. Each metric has a role: `goal` drives the decision, `guardrail` blocks ship on regression, `secondary` is informational.
84
+
85
+ **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.
86
+ - name: Universes
87
+ parent: Experiments
88
+ description: |-
89
+ Universes: the shared bucketing space all experiments draw from.
90
+
91
+ **Identity.** Each universe is keyed by a stable `name` (a-z, 0-9, `_`/`-`, max 64 chars). Experiments reference it via `universe: '<name>'`. The name is immutable.
92
+
93
+ **Unit of randomisation.** `unit_type` selects the attribute hashed into a 0–9999 bucket — default `user_id` for per-user randomisation, `account_id` to keep a whole account in the same group.
94
+
95
+ **Holdout.** `holdout_range` is an inclusive `[lo, hi]` bucket range (0–9999) reserved for measurement — callers hashed into the holdout are excluded from every experiment in the universe. Pro plan or higher.
96
+
97
+ **Deletion.** Blocked while any non-archived experiment references the universe — archive those first.
98
+ - name: Templates
99
+ parent: Flags
100
+ description: |-
101
+ Targeting-rule templates: reusable `{ attr, op, value }` rule definitions
102
+ (country, email-domain, region presets, …). Read-only built-ins ship with
103
+ the platform; each project can also save its own. To target by
104
+ country/plan/region, list templates, copy the matching template's `rules`,
105
+ substitute the concrete value(s), and pass them to `release flags create`.
106
+ - name: Attributes
107
+ parent: Flags
108
+ description: |-
109
+ Targeting attributes: the auto-inferred schema of user-context keys the
110
+ platform has observed in evaluation calls. Read-only — populated by the
111
+ SDK hot path, surfaced here so you can see which keys (and value types)
112
+ are available when writing gate/experiment targeting rules.
113
+ - name: Metrics
114
+ description: |-
115
+ Metrics: the event-backed queries that drive tracking dashboards and
116
+ experiment success / guardrail measurement.
117
+
118
+ **Definition.** Each metric pins one source event (`event_name`), one
119
+ aggregation, and (for `sum`/`avg`/quantile) a numeric value label. The
120
+ query is expressed as the DSL string (`query`, e.g. `sum(purchase, amount)`)
121
+ or its typed IR (`query_ir`) — supply exactly one.
122
+
123
+ **Identity.** Keyed by a stable `name` (single segment or `folder.name`).
124
+ Resolve endpoints accept the `id` or the `name`.
125
+
126
+ **Deletion.** Archive (soft-delete). Blocked while the metric is attached
127
+ to a running experiment — stop those first.
128
+ - name: Events
129
+ parent: Metrics
130
+ description: |-
131
+ Events: the catalog of event names (and their typed properties) that metric queries reference.
132
+
133
+ **Auto-discovery.** The SDK's `/collect` ingest path records any unknown event name it receives as a `pending` row (`pending: 1`) so you can review it. Metrics defined on a pending event fail until it is approved.
134
+
135
+ **Approval.** `POST /{id}/approve` promotes a pending event to usable (`pending: 0`), optionally declaring its folder/description/properties in the same call. Registering a brand-new event via `POST` that matches a pending name approves it instead of failing with a conflict.
136
+
137
+ **Properties.** Each event can declare typed properties (`name`, `type` of `string|number|boolean`, `required`). On update/approve the `properties` array replaces the full set — there is no merge.
138
+
139
+ **Deletion.** Soft-delete (the user-facing verb is `archive`). Blocked while any metric still references the event — delete those metrics first.
140
+ - name: Ops
141
+ description: |-
142
+ Operational queue: the unified table of bug reports, feature requests, and
143
+ auto-filed error/alert tickets, all over `/api/admin/ops`. One `create`
144
+ endpoint files either user type (`type: bug | feature_request`); list, get,
145
+ update, and link-pr are unified across every type. Also exposes the
146
+ `notify` escalation bell and the read-only Slack-channels list used to
147
+ resolve alert-rule notification targets.
148
+
149
+ **Handles.** A queue item is addressed by its per-project `number` (e.g. `7`)
150
+ or its full id — the API resolves either.
151
+ - name: Alerts
152
+ parent: Ops
153
+ x-cli:
154
+ aliases:
155
+ - ar
156
+ description: |-
157
+ Alert rules: the metric-threshold definitions the analysis cron evaluates each run.
158
+
159
+ **What fires.** Each rule binds a `metricId`, a `comparator` (`gt`/`gte`/`lt`/`lte`), and a `threshold`. On every cron pass the cron aggregates the metric over the trailing `windowHours` and raises an alert at `severity` when `value comparator threshold` holds.
160
+
161
+ **Immutable metric.** The bound metric (and its aggregation) is fixed at create time — there is no update path for `metricId`. Tune `threshold`/`comparator`/`windowHours`/`severity`/`name`/`enabled` instead, or delete + recreate to repoint the rule at a different metric.
162
+
163
+ **Delivery.** `notify` optionally targets a Slack channel and/or email for this rule; `null` falls back to the project's default notification settings. Slack targets require a connected Slack connector.
164
+ - name: Projects
165
+ description: |-
166
+ Projects: the account-level container every other resource is scoped to.
167
+
168
+ **Account-level, not bound-project-level.** Both operations resolve from the caller's credential rather than the `.shipeasy`-bound project — `current` reads the project the auth header maps to, and `upsert` find-or-creates under the session's owner. Neither touches the local `.shipeasy` binding; recording the result there is a consumer side-effect layered on top.
169
+
170
+ **Idempotent upsert.** A project is keyed by `(owner_email, domain)`. Calling `upsert` again with the same domain returns the existing project with `created: false`, so it is safe to run on every install.
171
+ - name: i18n
172
+ description: |-
173
+ String Manager (i18n): the worker-safe REST surface — locale profiles, the
174
+ insert-only key push, single-key overwrite, chunk publish, and the read-only
175
+ key/draft listings.
176
+
177
+ The fs/AST parts (scan, validate, install-loader, codemod) are NOT part of
178
+ this API — they stay in the fs-having CLI/MCP.
179
+ - name: Profiles
180
+ parent: i18n
181
+ description: Locale profiles (e.g. `en:prod`) — create, list, and publish a profile's chunks to the CDN.
182
+ - name: Keys
183
+ parent: i18n
184
+ description: Translation keys — the insert-only push, single-key overwrite, and key listing.
185
+ - name: Drafts
186
+ parent: i18n
187
+ description: Machine-translation drafts awaiting review before publish.
188
+ - name: Errors
189
+ description: |-
190
+ Tracked production errors: the deduplicated, fingerprinted error stream the
191
+ SDK + framework error sinks feed. Read-only list/get plus a status update
192
+ (`open`/`resolved`/`ignored`), an auto-file-to-GitHub-issue action, and a
193
+ time-series rollup. Errors are ingestion-only — there is no create route.
194
+ - name: Trigger
195
+ parent: Ops
196
+ description: |-
197
+ Recurring coding-agent triggers: the scheduled, unattended runs that burn
198
+ down the ops queue in `--pr` mode (one PR per fixed item; nothing
199
+ auto-merges). Shipeasy can fire four providers directly — Claude routines,
200
+ Cursor cloud agents, Copilot cloud agents, and Google Jules (the Gemini
201
+ path) — registered here as trigger connectors (idempotent per provider
202
+ key). Other platforms (Codex, Windsurf, Cline, OpenClaw, OpenCode,
203
+ Continue) schedule on their own surface — typically a GitHub Actions
204
+ `schedule:` cron running the platform's headless CLI with the shared
205
+ trigger prompt.
206
+ - name: Connectors
207
+ description: |-
208
+ Outbound integrations: the per-project destinations feedback + trigger
209
+ events are dispatched to (GitHub, Google Sheets, Slack, and the
210
+ Claude/Cursor/Copilot/Jules autopilot triggers). CRUD plus a manual
211
+ `fire` (trigger-only) and a `test` payload.
212
+ - name: API Keys
213
+ description: |-
214
+ Admin + SDK key management: mint, list, and revoke the `sdk_*` keys that
215
+ authenticate every other endpoint. The plaintext key is returned exactly
216
+ once, on create. Revoke is the rotation verb.
217
+ paths:
218
+ /api/admin/gates:
219
+ $ref: ./paths/gates.yaml#/~1api~1admin~1gates
220
+ /api/admin/gates/{id}:
221
+ $ref: ./paths/gates.yaml#/~1api~1admin~1gates~1{id}
222
+ /api/admin/gates/{id}/enable:
223
+ $ref: ./paths/gates.yaml#/~1api~1admin~1gates~1{id}~1enable
224
+ /api/admin/gates/{id}/disable:
225
+ $ref: ./paths/gates.yaml#/~1api~1admin~1gates~1{id}~1disable
226
+ /api/admin/experiments:
227
+ $ref: ./paths/experiments.yaml#/~1api~1admin~1experiments
228
+ /api/admin/experiments/{id}:
229
+ $ref: ./paths/experiments.yaml#/~1api~1admin~1experiments~1{id}
230
+ /api/admin/experiments/{id}/status:
231
+ $ref: ./paths/experiments.yaml#/~1api~1admin~1experiments~1{id}~1status
232
+ /api/admin/experiments/{id}/metrics:
233
+ $ref: ./paths/experiments.yaml#/~1api~1admin~1experiments~1{id}~1metrics
234
+ /api/admin/experiments/{id}/results:
235
+ $ref: ./paths/experiments.yaml#/~1api~1admin~1experiments~1{id}~1results
236
+ /api/admin/experiments/{id}/timeseries:
237
+ $ref: ./paths/experiments.yaml#/~1api~1admin~1experiments~1{id}~1timeseries
238
+ /api/admin/experiments/{id}/reanalyze:
239
+ $ref: ./paths/experiments.yaml#/~1api~1admin~1experiments~1{id}~1reanalyze
240
+ /api/admin/configs:
241
+ $ref: ./paths/configs.yaml#/~1api~1admin~1configs
242
+ /api/admin/configs/{id}:
243
+ $ref: ./paths/configs.yaml#/~1api~1admin~1configs~1{id}
244
+ /api/admin/configs/{id}/drafts:
245
+ $ref: ./paths/configs.yaml#/~1api~1admin~1configs~1{id}~1drafts
246
+ /api/admin/configs/{id}/publish:
247
+ $ref: ./paths/configs.yaml#/~1api~1admin~1configs~1{id}~1publish
248
+ /api/admin/configs/{id}/activity:
249
+ $ref: ./paths/configs.yaml#/~1api~1admin~1configs~1{id}~1activity
250
+ /api/admin/configs/{id}/schema:
251
+ $ref: ./paths/configs.yaml#/~1api~1admin~1configs~1{id}~1schema
252
+ /api/admin/killswitches:
253
+ $ref: ./paths/killswitches.yaml#/~1api~1admin~1killswitches
254
+ /api/admin/killswitches/{id}:
255
+ $ref: ./paths/killswitches.yaml#/~1api~1admin~1killswitches~1{id}
256
+ /api/admin/killswitches/{id}/switch:
257
+ $ref: ./paths/killswitches.yaml#/~1api~1admin~1killswitches~1{id}~1switch
258
+ /api/admin/killswitches/{id}/value:
259
+ $ref: ./paths/killswitches.yaml#/~1api~1admin~1killswitches~1{id}~1value
260
+ /api/admin/universes:
261
+ $ref: ./paths/universes.yaml#/~1api~1admin~1universes
262
+ /api/admin/universes/{id}:
263
+ $ref: ./paths/universes.yaml#/~1api~1admin~1universes~1{id}
264
+ /api/admin/gates/templates:
265
+ $ref: ./paths/gate-templates.yaml#/~1api~1admin~1gates~1templates
266
+ /api/admin/gates/templates/{id}:
267
+ $ref: ./paths/gate-templates.yaml#/~1api~1admin~1gates~1templates~1{id}
268
+ /api/admin/attributes:
269
+ $ref: ./paths/attributes.yaml#/~1api~1admin~1attributes
270
+ /api/admin/attributes/{id}:
271
+ $ref: ./paths/attributes.yaml#/~1api~1admin~1attributes~1{id}
272
+ /api/admin/metrics:
273
+ $ref: ./paths/metrics.yaml#/~1api~1admin~1metrics
274
+ /api/admin/metrics/{id}:
275
+ $ref: ./paths/metrics.yaml#/~1api~1admin~1metrics~1{id}
276
+ /api/admin/events:
277
+ $ref: ./paths/events.yaml#/~1api~1admin~1events
278
+ /api/admin/events/{id}:
279
+ $ref: ./paths/events.yaml#/~1api~1admin~1events~1{id}
280
+ /api/admin/events/{id}/approve:
281
+ $ref: ./paths/events.yaml#/~1api~1admin~1events~1{id}~1approve
282
+ /api/admin/ops:
283
+ $ref: ./paths/ops.yaml#/~1api~1admin~1ops
284
+ /api/admin/ops/{handle}:
285
+ $ref: ./paths/ops.yaml#/~1api~1admin~1ops~1{handle}
286
+ /api/admin/ops/{handle}/link-pr:
287
+ $ref: ./paths/ops.yaml#/~1api~1admin~1ops~1{handle}~1link-pr
288
+ /api/admin/notifications:
289
+ $ref: ./paths/ops.yaml#/~1api~1admin~1notifications
290
+ /api/admin/slack/channels:
291
+ $ref: ./paths/ops.yaml#/~1api~1admin~1slack~1channels
292
+ /api/admin/alert-rules:
293
+ $ref: ./paths/alert-rules.yaml#/~1api~1admin~1alert-rules
294
+ /api/admin/alert-rules/{id}:
295
+ $ref: ./paths/alert-rules.yaml#/~1api~1admin~1alert-rules~1{id}
296
+ /api/admin/projects/current:
297
+ $ref: ./paths/projects.yaml#/~1api~1admin~1projects~1current
298
+ /api/admin/projects/upsert:
299
+ $ref: ./paths/projects.yaml#/~1api~1admin~1projects~1upsert
300
+ /api/admin/projects/{id}:
301
+ $ref: ./paths/projects.yaml#/~1api~1admin~1projects~1{id}
302
+ /api/admin/i18n/profiles:
303
+ $ref: ./paths/i18n.yaml#/~1api~1admin~1i18n~1profiles
304
+ /api/admin/i18n/keys:
305
+ $ref: ./paths/i18n.yaml#/~1api~1admin~1i18n~1keys
306
+ /api/admin/i18n/keys/{id}:
307
+ $ref: ./paths/i18n.yaml#/~1api~1admin~1i18n~1keys~1{id}
308
+ /api/admin/i18n/drafts:
309
+ $ref: ./paths/i18n.yaml#/~1api~1admin~1i18n~1drafts
310
+ /api/admin/i18n/drafts/{draftId}:
311
+ $ref: ./paths/i18n.yaml#/~1api~1admin~1i18n~1drafts~1{draftId}
312
+ /api/admin/i18n/profiles/{profileId}/publish:
313
+ $ref: ./paths/i18n.yaml#/~1api~1admin~1i18n~1profiles~1{profileId}~1publish
314
+ /api/admin/i18n/set:
315
+ $ref: ./paths/i18n.yaml#/~1api~1admin~1i18n~1set
316
+ /api/admin/errors:
317
+ $ref: ./paths/errors.yaml#/~1api~1admin~1errors
318
+ /api/admin/errors/{id}:
319
+ $ref: ./paths/errors.yaml#/~1api~1admin~1errors~1{id}
320
+ /api/admin/errors/{id}/file:
321
+ $ref: ./paths/errors.yaml#/~1api~1admin~1errors~1{id}~1file
322
+ /api/admin/errors/{id}/series:
323
+ $ref: ./paths/errors.yaml#/~1api~1admin~1errors~1{id}~1series
324
+ /api/admin/connectors:
325
+ $ref: ./paths/connectors.yaml#/~1api~1admin~1connectors
326
+ /api/admin/connectors/{id}:
327
+ $ref: ./paths/connectors.yaml#/~1api~1admin~1connectors~1{id}
328
+ /api/admin/connectors/{id}/fire:
329
+ $ref: ./paths/connectors.yaml#/~1api~1admin~1connectors~1{id}~1fire
330
+ /api/admin/connectors/{id}/test:
331
+ $ref: ./paths/connectors.yaml#/~1api~1admin~1connectors~1{id}~1test
332
+ /api/admin/connectors/{id}/trigger:
333
+ $ref: ./paths/connectors.yaml#/~1api~1admin~1connectors~1{id}~1trigger
334
+ /api/admin/connectors/trigger:
335
+ $ref: ./paths/connectors.yaml#/~1api~1admin~1connectors~1trigger
336
+ /api/admin/keys:
337
+ $ref: ./paths/keys.yaml#/~1api~1admin~1keys
338
+ /api/admin/keys/{id}/revoke:
339
+ $ref: ./paths/keys.yaml#/~1api~1admin~1keys~1{id}~1revoke
340
+ /api/admin/search:
341
+ $ref: ./paths/search.yaml#/~1api~1admin~1search
342
+ components:
343
+ securitySchemes:
344
+ bearerSdkKey:
345
+ type: http
346
+ scheme: bearer
347
+ bearerFormat: sdk_admin_*
348
+ description: 'Pass an admin SDK key as `Authorization: Bearer sdk_admin_…`. Mint via `POST /api/admin/keys` with `type: "admin"`.'
@@ -0,0 +1,250 @@
1
+ /api/admin/alert-rules:
2
+ get:
3
+ operationId: listAlertRules
4
+ summary: List alert rules
5
+ description: |-
6
+ Returns every alert rule in the project (not paginated). Each rule carries its bound `metricId`, the denormalised `metricName` (or `null` if the metric was removed), the comparator/threshold/window, severity, enabled flag, and delivery target.
7
+
8
+ **Use case:** Audit which metrics have alerting configured — for example to confirm an on-call threshold is set before a launch.
9
+ tags:
10
+ - Alerts
11
+ parameters:
12
+ - $ref: ../components/parameters.yaml#/ProjectId
13
+ responses:
14
+ "200":
15
+ description: List alert rules
16
+ content:
17
+ application/json:
18
+ schema:
19
+ $ref: ../components/schemas/alert-rules.yaml#/ListAlertRulesResponse
20
+ example:
21
+ - id: ar_01j7w8a1b2c3d4e5f6g7h8i9j0
22
+ name: Checkout error rate
23
+ metricId: met_01j6abc2d3e4f5g6h7i8j9k0l1
24
+ metricName: checkout_errors
25
+ comparator: gt
26
+ threshold: 50
27
+ windowHours: 24
28
+ severity: warn
29
+ enabled: true
30
+ notify: null
31
+ createdAt: 2026-04-12T10:14:08.000Z
32
+ updatedAt: 2026-04-12T10:14:08.000Z
33
+ "400":
34
+ $ref: ../components/responses.yaml#/BadRequest
35
+ "401":
36
+ $ref: ../components/responses.yaml#/Unauthorized
37
+ "403":
38
+ $ref: ../components/responses.yaml#/Forbidden
39
+ "404":
40
+ $ref: ../components/responses.yaml#/NotFound
41
+ "409":
42
+ $ref: ../components/responses.yaml#/Conflict
43
+ "422":
44
+ $ref: ../components/responses.yaml#/UnprocessableEntity
45
+ x-error-codes:
46
+ - BAD_REQUEST
47
+ - UNAUTHORIZED
48
+ - FORBIDDEN
49
+ x-cli:
50
+ name: list
51
+ post:
52
+ operationId: createAlertRule
53
+ summary: Create an alert rule
54
+ description: |-
55
+ Creates a metric-threshold alert rule. `name`, `metricId`, `comparator`, and `threshold` are required; `windowHours` defaults to `24`, `severity` to `warn`, and `enabled` to `true`.
56
+
57
+ Returns `404` if `metricId` does not resolve, and `400` for a metric with no scalar form over a window (e.g. retention metrics) — the cron can't evaluate those.
58
+
59
+ **Use cases**
60
+
61
+ - **Threshold alert** — warn when an error/latency metric crosses a value over a rolling window.
62
+ - **Routed alert** — set `notify` to page a specific Slack channel or on-call email instead of the project default.
63
+ tags:
64
+ - Alerts
65
+ parameters:
66
+ - $ref: ../components/parameters.yaml#/ProjectId
67
+ requestBody:
68
+ required: true
69
+ content:
70
+ application/json:
71
+ schema:
72
+ $ref: ../components/schemas/alert-rules.yaml#/CreateAlertRuleRequest
73
+ examples:
74
+ minimal:
75
+ summary: Minimal — alert when a metric exceeds a threshold
76
+ description: Smallest valid body. Warns when the metric exceeds 50 over the default 24h window, with no per-rule delivery target.
77
+ value:
78
+ name: Checkout error rate
79
+ metricId: met_01j6abc2d3e4f5g6h7i8j9k0l1
80
+ comparator: gt
81
+ threshold: 50
82
+ targeted:
83
+ summary: Full — custom window, severity, and Slack/email target
84
+ description: A `danger` rule over a 1h window that posts to a Slack channel and emails on-call. The Slack channel must come from a connected connector.
85
+ value:
86
+ name: Checkout error spike
87
+ metricId: met_01j6abc2d3e4f5g6h7i8j9k0l1
88
+ comparator: gt
89
+ threshold: 100
90
+ windowHours: 1
91
+ severity: danger
92
+ notify:
93
+ slackChannel:
94
+ id: C0123ABCD
95
+ name: incidents
96
+ email: oncall@acme.com
97
+ responses:
98
+ "201":
99
+ description: Create an alert rule
100
+ content:
101
+ application/json:
102
+ schema:
103
+ $ref: ../components/schemas/alert-rules.yaml#/CreateAlertRuleResponse
104
+ example:
105
+ id: ar_01j7w8a1b2c3d4e5f6g7h8i9j0
106
+ "400":
107
+ $ref: ../components/responses.yaml#/BadRequest
108
+ "401":
109
+ $ref: ../components/responses.yaml#/Unauthorized
110
+ "403":
111
+ $ref: ../components/responses.yaml#/Forbidden
112
+ "404":
113
+ $ref: ../components/responses.yaml#/NotFound
114
+ "409":
115
+ $ref: ../components/responses.yaml#/Conflict
116
+ "422":
117
+ $ref: ../components/responses.yaml#/UnprocessableEntity
118
+ x-error-codes:
119
+ - BAD_REQUEST
120
+ - UNAUTHORIZED
121
+ - FORBIDDEN
122
+ - ALREADY_EXISTS
123
+ - REFERENCED_NOT_FOUND
124
+ - VALIDATION
125
+ x-cli:
126
+ name: create
127
+ /api/admin/alert-rules/{id}:
128
+ patch:
129
+ operationId: updateAlertRule
130
+ summary: Update an alert rule
131
+ description: |-
132
+ Partial update of a rule's tunable knobs. `metricId` is immutable — the metric also pins the aggregation, so a body carrying `metricId` is rejected with `409 IMMUTABLE_FIELD`; create a new rule bound to the other metric instead (rule deletion is dashboard-only).
133
+
134
+ Pass `"notify": null` to revert the rule's delivery target back to the project default.
135
+
136
+ **Use cases**
137
+
138
+ - **Tune sensitivity** — change `threshold`/`comparator`/`windowHours` as the metric's baseline shifts.
139
+ - **Pause without losing config** — `{ "enabled": false }` instead of deleting the rule.
140
+ tags:
141
+ - Alerts
142
+ parameters:
143
+ - $ref: ../components/parameters.yaml#/ProjectId
144
+ - name: id
145
+ in: path
146
+ required: true
147
+ description: Stable opaque alert-rule id (`ar_…`) or the rule's `name`.
148
+ schema:
149
+ type: string
150
+ requestBody:
151
+ required: true
152
+ content:
153
+ application/json:
154
+ schema:
155
+ $ref: ../components/schemas/alert-rules.yaml#/UpdateAlertRuleRequest
156
+ examples:
157
+ raiseThreshold:
158
+ summary: Raise the threshold
159
+ description: Bump the alerting threshold without touching anything else.
160
+ value:
161
+ threshold: 100
162
+ disable:
163
+ summary: Disable the rule
164
+ description: Stop the cron from evaluating the rule.
165
+ value:
166
+ enabled: false
167
+ clearTarget:
168
+ summary: Revert to the project default target
169
+ description: Drop the per-rule Slack/email target and fall back to project defaults.
170
+ value:
171
+ notify: null
172
+ responses:
173
+ "200":
174
+ description: Update an alert rule
175
+ content:
176
+ application/json:
177
+ schema:
178
+ $ref: ../components/schemas/alert-rules.yaml#/UpdateAlertRuleResponse
179
+ example:
180
+ id: ar_01j7w8a1b2c3d4e5f6g7h8i9j0
181
+ "400":
182
+ $ref: ../components/responses.yaml#/BadRequest
183
+ "401":
184
+ $ref: ../components/responses.yaml#/Unauthorized
185
+ "403":
186
+ $ref: ../components/responses.yaml#/Forbidden
187
+ "404":
188
+ $ref: ../components/responses.yaml#/NotFound
189
+ "409":
190
+ $ref: ../components/responses.yaml#/Conflict
191
+ "422":
192
+ $ref: ../components/responses.yaml#/UnprocessableEntity
193
+ x-error-codes:
194
+ - BAD_REQUEST
195
+ - UNAUTHORIZED
196
+ - FORBIDDEN
197
+ - NOT_FOUND
198
+ - IMMUTABLE_FIELD
199
+ - VALIDATION
200
+ x-cli:
201
+ name: update
202
+ positional:
203
+ - id
204
+ delete:
205
+ operationId: deleteAlertRule
206
+ summary: Delete an alert rule
207
+ description: |-
208
+ Deletes the alert rule. The cron stops evaluating it immediately. Use this (then create a new rule) to repoint alerting at a different metric, since `metricId` is immutable.
209
+
210
+ **Use case:** Remove an alert rule that is no longer needed, or as the first half of repointing a rule at a different metric.
211
+ tags:
212
+ - Alerts
213
+ parameters:
214
+ - $ref: ../components/parameters.yaml#/ProjectId
215
+ - name: id
216
+ in: path
217
+ required: true
218
+ description: Stable opaque alert-rule id (`ar_…`) or the rule's `name`.
219
+ schema:
220
+ type: string
221
+ responses:
222
+ "200":
223
+ description: Delete an alert rule
224
+ content:
225
+ application/json:
226
+ schema:
227
+ $ref: ../components/schemas/alert-rules.yaml#/DeleteAlertRuleResponse
228
+ example:
229
+ ok: true
230
+ "400":
231
+ $ref: ../components/responses.yaml#/BadRequest
232
+ "401":
233
+ $ref: ../components/responses.yaml#/Unauthorized
234
+ "403":
235
+ $ref: ../components/responses.yaml#/Forbidden
236
+ "404":
237
+ $ref: ../components/responses.yaml#/NotFound
238
+ "409":
239
+ $ref: ../components/responses.yaml#/Conflict
240
+ "422":
241
+ $ref: ../components/responses.yaml#/UnprocessableEntity
242
+ x-error-codes:
243
+ - BAD_REQUEST
244
+ - UNAUTHORIZED
245
+ - FORBIDDEN
246
+ - NOT_FOUND
247
+ x-cli:
248
+ name: archive
249
+ positional:
250
+ - id