@whooshbang/contracts 1.0.0-rc.13

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 (229) hide show
  1. package/CHANGELOG.md +198 -0
  2. package/LICENSE +21 -0
  3. package/README.md +120 -0
  4. package/contract-manifest.json +390 -0
  5. package/dist/base64url.d.ts +2 -0
  6. package/dist/base64url.js +51 -0
  7. package/dist/base64url.js.map +1 -0
  8. package/dist/generated/artifact-index.d.ts +205 -0
  9. package/dist/generated/artifact-index.js +396 -0
  10. package/dist/generated/artifact-index.js.map +1 -0
  11. package/dist/generated/contract-manifest.d.ts +66 -0
  12. package/dist/generated/contract-manifest.js +6 -0
  13. package/dist/generated/contract-manifest.js.map +1 -0
  14. package/dist/generated/core-scenario.d.ts +18 -0
  15. package/dist/generated/core-scenario.js +6 -0
  16. package/dist/generated/core-scenario.js.map +1 -0
  17. package/dist/generated/fixture-index.d.ts +33 -0
  18. package/dist/generated/fixture-index.js +6 -0
  19. package/dist/generated/fixture-index.js.map +1 -0
  20. package/dist/generated/interaction-machine-scenario.d.ts +263 -0
  21. package/dist/generated/interaction-machine-scenario.js +6 -0
  22. package/dist/generated/interaction-machine-scenario.js.map +1 -0
  23. package/dist/generated/interaction-v1.d.ts +152 -0
  24. package/dist/generated/interaction-v1.js +6 -0
  25. package/dist/generated/interaction-v1.js.map +1 -0
  26. package/dist/generated/machine-v1.d.ts +169 -0
  27. package/dist/generated/machine-v1.js +6 -0
  28. package/dist/generated/machine-v1.js.map +1 -0
  29. package/dist/generated/provider-capabilities-v1.d.ts +78 -0
  30. package/dist/generated/provider-capabilities-v1.js +6 -0
  31. package/dist/generated/provider-capabilities-v1.js.map +1 -0
  32. package/dist/generated/validators-standalone.d.ts +659 -0
  33. package/dist/generated/validators-standalone.js +47800 -0
  34. package/dist/generated/validators-standalone.js.map +1 -0
  35. package/dist/generated/validators.d.ts +74 -0
  36. package/dist/generated/validators.js +493 -0
  37. package/dist/generated/validators.js.map +1 -0
  38. package/dist/generated/webhook-delivery-case-v1.d.ts +91 -0
  39. package/dist/generated/webhook-delivery-case-v1.js +6 -0
  40. package/dist/generated/webhook-delivery-case-v1.js.map +1 -0
  41. package/dist/generated/webhook-signing-vector-v1.d.ts +88 -0
  42. package/dist/generated/webhook-signing-vector-v1.js +6 -0
  43. package/dist/generated/webhook-signing-vector-v1.js.map +1 -0
  44. package/dist/generated/whooshbang-event-v1.d.ts +191 -0
  45. package/dist/generated/whooshbang-event-v1.js +6 -0
  46. package/dist/generated/whooshbang-event-v1.js.map +1 -0
  47. package/dist/generated/whooshbang-v1.d.ts +1162 -0
  48. package/dist/generated/whooshbang-v1.js +6 -0
  49. package/dist/generated/whooshbang-v1.js.map +1 -0
  50. package/dist/index.d.ts +20 -0
  51. package/dist/index.js +7 -0
  52. package/dist/index.js.map +1 -0
  53. package/dist/machine-credential.d.ts +31 -0
  54. package/dist/machine-credential.js +78 -0
  55. package/dist/machine-credential.js.map +1 -0
  56. package/dist/webhook-consumer.d.ts +50 -0
  57. package/dist/webhook-consumer.js +71 -0
  58. package/dist/webhook-consumer.js.map +1 -0
  59. package/dist/webhook-delivery.d.ts +46 -0
  60. package/dist/webhook-delivery.js +126 -0
  61. package/dist/webhook-delivery.js.map +1 -0
  62. package/dist/webhook-signature.d.ts +36 -0
  63. package/dist/webhook-signature.js +255 -0
  64. package/dist/webhook-signature.js.map +1 -0
  65. package/examples/python/verify_webhook.py +283 -0
  66. package/fixtures/.gitkeep +1 -0
  67. package/fixtures/core-v1/fixture-index.json +963 -0
  68. package/fixtures/core-v1/problems/auth-invalid.json +9 -0
  69. package/fixtures/core-v1/problems/authentication-required.json +9 -0
  70. package/fixtures/core-v1/problems/cancellation-too-late.json +9 -0
  71. package/fixtures/core-v1/problems/endpoint-rotation-conflict.json +10 -0
  72. package/fixtures/core-v1/problems/environment-mismatch.json +9 -0
  73. package/fixtures/core-v1/problems/idempotency-conflict.json +9 -0
  74. package/fixtures/core-v1/problems/idempotency-key-required.json +9 -0
  75. package/fixtures/core-v1/problems/project-slug-conflict.json +16 -0
  76. package/fixtures/core-v1/problems/provider-outcome-unknown.json +9 -0
  77. package/fixtures/core-v1/problems/provider-retryable.json +10 -0
  78. package/fixtures/core-v1/problems/provider-terminal.json +9 -0
  79. package/fixtures/core-v1/problems/rate-limited.json +10 -0
  80. package/fixtures/core-v1/problems/replay-unavailable-not-terminal.json +16 -0
  81. package/fixtures/core-v1/problems/replay-unavailable-payload.json +16 -0
  82. package/fixtures/core-v1/problems/replay-unavailable-rollout.json +16 -0
  83. package/fixtures/core-v1/problems/request-invalid.json +16 -0
  84. package/fixtures/core-v1/problems/resource-expired.json +9 -0
  85. package/fixtures/core-v1/problems/resource-not-found.json +9 -0
  86. package/fixtures/core-v1/problems/scope-forbidden.json +9 -0
  87. package/fixtures/core-v1/problems/subscriber-unbound.json +9 -0
  88. package/fixtures/core-v1/requests/create-api-credential.json +9 -0
  89. package/fixtures/core-v1/requests/create-customer-endpoint.json +5 -0
  90. package/fixtures/core-v1/requests/create-message.json +15 -0
  91. package/fixtures/core-v1/requests/create-project.json +4 -0
  92. package/fixtures/core-v1/requests/create-subscription-link.json +5 -0
  93. package/fixtures/core-v1/requests/rotate-api-credential.json +3 -0
  94. package/fixtures/core-v1/requests/rotate-customer-endpoint.json +3 -0
  95. package/fixtures/core-v1/scenarios/api-credential-invalid-indistinguishable.json +14 -0
  96. package/fixtures/core-v1/scenarios/api-credential-one-time-reveal.json +21 -0
  97. package/fixtures/core-v1/scenarios/api-credential-revocation-replay.json +17 -0
  98. package/fixtures/core-v1/scenarios/api-credential-rotation-overlap.json +18 -0
  99. package/fixtures/core-v1/scenarios/cancellation-too-late.json +15 -0
  100. package/fixtures/core-v1/scenarios/cross-account-project.json +14 -0
  101. package/fixtures/core-v1/scenarios/cross-project-resource.json +17 -0
  102. package/fixtures/core-v1/scenarios/environment-mismatch.json +17 -0
  103. package/fixtures/core-v1/scenarios/idempotency-conflict.json +35 -0
  104. package/fixtures/core-v1/scenarios/idempotency-equivalent-replay.json +27 -0
  105. package/fixtures/core-v1/scenarios/malformed-bearer.json +14 -0
  106. package/fixtures/core-v1/scenarios/metadata-overrun.json +14 -0
  107. package/fixtures/core-v1/scenarios/missing-scope.json +15 -0
  108. package/fixtures/core-v1/scenarios/project-create-equivalent-replay.json +26 -0
  109. package/fixtures/core-v1/scenarios/project-slug-conflict.json +21 -0
  110. package/fixtures/core-v1/scenarios/provider-outcome-unknown.json +15 -0
  111. package/fixtures/core-v1/scenarios/subscription-activation-replay.json +18 -0
  112. package/fixtures/core-v1/scenarios/subscription-expired-replay.json +16 -0
  113. package/fixtures/core-v1/success/account-projection.json +11 -0
  114. package/fixtures/core-v1/success/api-credential-collection.json +22 -0
  115. package/fixtures/core-v1/success/api-credential-created.json +20 -0
  116. package/fixtures/core-v1/success/api-credential-revoked.json +19 -0
  117. package/fixtures/core-v1/success/api-credential-rotated.json +41 -0
  118. package/fixtures/core-v1/success/customer-endpoint-attempts.json +15 -0
  119. package/fixtures/core-v1/success/customer-endpoint-collection.json +26 -0
  120. package/fixtures/core-v1/success/customer-endpoint-create-replayed.json +16 -0
  121. package/fixtures/core-v1/success/customer-endpoint-created.json +17 -0
  122. package/fixtures/core-v1/success/customer-endpoint-rotated.json +21 -0
  123. package/fixtures/core-v1/success/message-accepted.json +30 -0
  124. package/fixtures/core-v1/success/message-cancellation-too-late.json +27 -0
  125. package/fixtures/core-v1/success/message-cancelled.json +27 -0
  126. package/fixtures/core-v1/success/message-outcome-unknown.json +33 -0
  127. package/fixtures/core-v1/success/message-provider-accepted.json +30 -0
  128. package/fixtures/core-v1/success/project-collection.json +42 -0
  129. package/fixtures/core-v1/success/project-created.json +38 -0
  130. package/fixtures/core-v1/success/subscription-link-activated.json +22 -0
  131. package/fixtures/core-v1/success/subscription-link-cancelled.json +14 -0
  132. package/fixtures/core-v1/success/subscription-link-paused.json +22 -0
  133. package/fixtures/core-v1/success/subscription-link-pending.json +14 -0
  134. package/fixtures/core-v1/success/subscription-link-revoked.json +22 -0
  135. package/fixtures/interaction-machine-v1/capabilities/providers.json +57 -0
  136. package/fixtures/interaction-machine-v1/capabilities/telegram.json +52 -0
  137. package/fixtures/interaction-machine-v1/events/confirm-answered.json +22 -0
  138. package/fixtures/interaction-machine-v1/events/input-answered.json +22 -0
  139. package/fixtures/interaction-machine-v1/events/input-redacted.json +18 -0
  140. package/fixtures/interaction-machine-v1/events/select-answered.json +22 -0
  141. package/fixtures/interaction-machine-v1/requests/ack-processed.json +5 -0
  142. package/fixtures/interaction-machine-v1/requests/ack-quarantined.json +5 -0
  143. package/fixtures/interaction-machine-v1/requests/create-machine-client.json +6 -0
  144. package/fixtures/interaction-machine-v1/requests/create-message-confirm.json +18 -0
  145. package/fixtures/interaction-machine-v1/requests/create-message-input.json +16 -0
  146. package/fixtures/interaction-machine-v1/requests/create-message-select.json +26 -0
  147. package/fixtures/interaction-machine-v1/requests/register-machine-credential.json +4 -0
  148. package/fixtures/interaction-machine-v1/scenarios/ack-conflict.json +14 -0
  149. package/fixtures/interaction-machine-v1/scenarios/ack-cross-machine.json +15 -0
  150. package/fixtures/interaction-machine-v1/scenarios/ack-out-of-order.json +15 -0
  151. package/fixtures/interaction-machine-v1/scenarios/ack-replay.json +17 -0
  152. package/fixtures/interaction-machine-v1/scenarios/ambiguous-free-text.json +15 -0
  153. package/fixtures/interaction-machine-v1/scenarios/callback-token-opacity.json +16 -0
  154. package/fixtures/interaction-machine-v1/scenarios/credential-registration-conflict.json +16 -0
  155. package/fixtures/interaction-machine-v1/scenarios/credential-registration-replay.json +15 -0
  156. package/fixtures/interaction-machine-v1/scenarios/credential-revocation-replay.json +14 -0
  157. package/fixtures/interaction-machine-v1/scenarios/credential-rotation.json +16 -0
  158. package/fixtures/interaction-machine-v1/scenarios/first-credential-activates.json +15 -0
  159. package/fixtures/interaction-machine-v1/scenarios/interaction-duplicate.json +16 -0
  160. package/fixtures/interaction-machine-v1/scenarios/interaction-expired.json +17 -0
  161. package/fixtures/interaction-machine-v1/scenarios/interaction-mismatch.json +16 -0
  162. package/fixtures/interaction-machine-v1/scenarios/interaction-retired.json +16 -0
  163. package/fixtures/interaction-machine-v1/scenarios/interaction-stale.json +16 -0
  164. package/fixtures/interaction-machine-v1/scenarios/machine-admin-denied.json +14 -0
  165. package/fixtures/interaction-machine-v1/scenarios/machine-bound-message-create.json +22 -0
  166. package/fixtures/interaction-machine-v1/scenarios/machine-cancel-denied.json +14 -0
  167. package/fixtures/interaction-machine-v1/scenarios/machine-crash-before-ack.json +16 -0
  168. package/fixtures/interaction-machine-v1/scenarios/machine-notifier-mismatch.json +14 -0
  169. package/fixtures/interaction-machine-v1/scenarios/machine-other-message-read.json +14 -0
  170. package/fixtures/interaction-machine-v1/scenarios/machine-owned-message-read.json +22 -0
  171. package/fixtures/interaction-machine-v1/scenarios/machine-subscriber-mismatch.json +14 -0
  172. package/fixtures/interaction-machine-v1/scenarios/poll-uncommitted-cursor-rejected.json +17 -0
  173. package/fixtures/interaction-machine-v1/scenarios/project-credential-machine-endpoint-denied.json +14 -0
  174. package/fixtures/interaction-machine-v1/scenarios/quarantine-integrity-rejected.json +15 -0
  175. package/fixtures/interaction-machine-v1/scenarios/quarantine-signature-rejected.json +16 -0
  176. package/fixtures/interaction-machine-v1/scenarios/quarantine-valid.json +15 -0
  177. package/fixtures/interaction-machine-v1/scenarios/revoked-machine-credential.json +15 -0
  178. package/fixtures/interaction-machine-v1/success/ack-out-of-order.json +8 -0
  179. package/fixtures/interaction-machine-v1/success/ack-processed.json +8 -0
  180. package/fixtures/interaction-machine-v1/success/ack-quarantined.json +9 -0
  181. package/fixtures/interaction-machine-v1/success/interaction-answered-confirm.json +10 -0
  182. package/fixtures/interaction-machine-v1/success/interaction-answered-input.json +10 -0
  183. package/fixtures/interaction-machine-v1/success/interaction-answered-redacted.json +8 -0
  184. package/fixtures/interaction-machine-v1/success/interaction-answered-select.json +10 -0
  185. package/fixtures/interaction-machine-v1/success/interaction-open.json +7 -0
  186. package/fixtures/interaction-machine-v1/success/machine-client-active.json +20 -0
  187. package/fixtures/interaction-machine-v1/success/machine-client-provisioning.json +19 -0
  188. package/fixtures/interaction-machine-v1/success/machine-client-revoked.json +21 -0
  189. package/fixtures/interaction-machine-v1/success/machine-credential-active.json +13 -0
  190. package/fixtures/interaction-machine-v1/success/machine-credential-revoked.json +14 -0
  191. package/fixtures/interaction-machine-v1/success/message-interaction-open.json +33 -0
  192. package/fixtures/interaction-machine-v1/success/poll-empty.json +6 -0
  193. package/fixtures/interaction-machine-v1/success/poll-events.json +51 -0
  194. package/fixtures/interaction-machine-v1/tokens/callback-token.json +1 -0
  195. package/fixtures/whooshbang-events-v1/delivery/cases.json +418 -0
  196. package/fixtures/whooshbang-events-v1/events/agent-binding-degraded.json +17 -0
  197. package/fixtures/whooshbang-events-v1/events/interaction-expired.json +16 -0
  198. package/fixtures/whooshbang-events-v1/events/interaction-received.json +23 -0
  199. package/fixtures/whooshbang-events-v1/events/message-delivered.json +16 -0
  200. package/fixtures/whooshbang-events-v1/events/message-expired.json +15 -0
  201. package/fixtures/whooshbang-events-v1/events/message-failed.json +17 -0
  202. package/fixtures/whooshbang-events-v1/events/message-provider-accepted.json +15 -0
  203. package/fixtures/whooshbang-events-v1/events/subscription-activated.json +18 -0
  204. package/fixtures/whooshbang-events-v1/events/subscription-revoked.json +18 -0
  205. package/fixtures/whooshbang-events-v1/signing/vectors.json +852 -0
  206. package/openapi/.gitkeep +1 -0
  207. package/openapi/generated/whooshbang-v1.bundle.json +5913 -0
  208. package/openapi/whooshbang-v1.yaml +2334 -0
  209. package/package.json +63 -0
  210. package/schemas/contract-manifest.schema.json +140 -0
  211. package/schemas/core-scenario.schema.json +38 -0
  212. package/schemas/events/agent-binding-degraded-v1.schema.json +8 -0
  213. package/schemas/events/interaction-expired-v1.schema.json +8 -0
  214. package/schemas/events/interaction-received-v1.schema.json +8 -0
  215. package/schemas/events/message-delivered-v1.schema.json +8 -0
  216. package/schemas/events/message-expired-v1.schema.json +8 -0
  217. package/schemas/events/message-failed-v1.schema.json +8 -0
  218. package/schemas/events/message-provider-accepted-v1.schema.json +8 -0
  219. package/schemas/events/subscription-activated-v1.schema.json +8 -0
  220. package/schemas/events/subscription-revoked-v1.schema.json +8 -0
  221. package/schemas/events/whooshbang-event-v1.schema.json +689 -0
  222. package/schemas/fixture-index.schema.json +67 -0
  223. package/schemas/interaction-machine-scenario.schema.json +700 -0
  224. package/schemas/interaction-v1.schema.json +483 -0
  225. package/schemas/machine-v1.schema.json +430 -0
  226. package/schemas/provider-capabilities-v1.schema.json +263 -0
  227. package/schemas/webhooks/webhook-delivery-case-v1.schema.json +167 -0
  228. package/schemas/webhooks/webhook-signing-vector-v1.schema.json +197 -0
  229. package/schemas/whooshbang-v1.schema.json +2173 -0
@@ -0,0 +1,2334 @@
1
+ openapi: 3.1.1
2
+ jsonSchemaDialect: https://json-schema.org/draft/2020-12/schema
3
+ # whooshbang:public-origin production api https://api.whooshbang.com
4
+ x-contract-version: 1.0.0-rc.13
5
+ info:
6
+ title: WhooshBang API
7
+ version: 1.0.0-rc.13
8
+ description: |
9
+ The V1 contract for human account/project administration, project-scoped
10
+ subscription links, and asynchronous text messages. A Clerk session selects
11
+ one account for administration. A project credential selects one account,
12
+ project, and `test` or `live` environment for product operations; request
13
+ bodies cannot override either authenticated scope.
14
+
15
+ A person's OAuth grant selects one account and carries scopes, but no
16
+ project. It names the project and environment it acts in through the URL
17
+ path, on the environment-scoped form of each operation; the service checks
18
+ that path against the granting person's membership on every call. The flat
19
+ forms remain credential-only and are unchanged.
20
+
21
+ Resource identifiers are opaque and are not authorization. Reads outside the
22
+ credential scope return the same `404` shape as absent resources. Provider
23
+ credentials, raw Telegram identity, and protected provider responses are
24
+ never part of this API.
25
+ termsOfService: https://flowxo.com/terms
26
+ contact:
27
+ name: WhooshBang Support
28
+ url: https://flowxo.com/contact
29
+ license:
30
+ name: Proprietary
31
+ url: https://flowxo.com/terms
32
+ servers:
33
+ - url: https://api.whooshbang.com
34
+ description: Environment is selected by the bearer credential, not the URL or body.
35
+ security:
36
+ - bearerCredential: []
37
+ tags:
38
+ - name: Account
39
+ description: The current Clerk organization projected as a WhooshBang account.
40
+ - name: Projects
41
+ description: Account-scoped applications with transactionally bootstrapped test/live environments.
42
+ - name: API credentials
43
+ description: Human-administered, environment-scoped bearer credentials with one-time secret reveal.
44
+ - name: Subscription links
45
+ description: Single-use, expiring Telegram authorization links.
46
+ - name: Messages
47
+ description: Asynchronous logical messages and their highest proven outcomes.
48
+ - name: Machine clients
49
+ description: Project-administered, destination-bound local-client identities and one-way credential metadata.
50
+ - name: Machine events
51
+ description: Durable per-machine long polling and contiguous acknowledgement.
52
+ - name: Capabilities
53
+ description: Provider-neutral rendering and evidence capabilities.
54
+ - name: Customer endpoints
55
+ description: Verified signed-event destinations with one-time secret lifecycle and content-free diagnostics.
56
+ paths:
57
+ /v1/account:
58
+ get:
59
+ operationId: getAccount
60
+ summary: Read the current account projection
61
+ description: |
62
+ Returns the WhooshBang account selected by the verified Clerk
63
+ organization session and the caller's projected role. Clerk organization
64
+ and user identifiers are never public response fields.
65
+ tags:
66
+ - Account
67
+ security:
68
+ - clerkSession: []
69
+ - bearerGrant: []
70
+ x-account-membership: required
71
+ responses:
72
+ "200":
73
+ description: The current account projection.
74
+ headers:
75
+ WhooshBang-Diagnostic-Id:
76
+ $ref: "#/components/headers/DiagnosticId"
77
+ content:
78
+ application/json:
79
+ schema:
80
+ $ref: "#/components/schemas/AccountProjection"
81
+ examples:
82
+ projectedAccount:
83
+ externalValue: ../fixtures/core-v1/success/account-projection.json
84
+ "401":
85
+ $ref: "#/components/responses/Unauthorized"
86
+ "403":
87
+ $ref: "#/components/responses/Forbidden"
88
+ "429":
89
+ $ref: "#/components/responses/RateLimited"
90
+ /v1/projects:
91
+ get:
92
+ operationId: listProjects
93
+ summary: List projects in the current account
94
+ description: |
95
+ Returns only projects owned by the account selected by the verified
96
+ Clerk organization session. Every project includes its complete test/live
97
+ environment and default-notifier bootstrap.
98
+ tags:
99
+ - Projects
100
+ security:
101
+ - clerkSession: []
102
+ - bearerGrant: []
103
+ x-required-scopes:
104
+ - projects:read
105
+ x-account-membership: required
106
+ parameters:
107
+ - $ref: "#/components/parameters/ProjectAfterCursor"
108
+ - $ref: "#/components/parameters/ProjectPageLimit"
109
+ responses:
110
+ "200":
111
+ description: A stable page of projects in the current account.
112
+ headers:
113
+ WhooshBang-Diagnostic-Id:
114
+ $ref: "#/components/headers/DiagnosticId"
115
+ content:
116
+ application/json:
117
+ schema:
118
+ $ref: "#/components/schemas/ProjectCollection"
119
+ examples:
120
+ projects:
121
+ externalValue: ../fixtures/core-v1/success/project-collection.json
122
+ "400":
123
+ $ref: "#/components/responses/BadRequest"
124
+ "401":
125
+ $ref: "#/components/responses/Unauthorized"
126
+ "403":
127
+ $ref: "#/components/responses/Forbidden"
128
+ "429":
129
+ $ref: "#/components/responses/RateLimited"
130
+ post:
131
+ operationId: createProject
132
+ summary: Create a project and its default environments
133
+ description: |
134
+ Creates one project inside the authenticated account. The project, its
135
+ `test` and `live` environments, and one `Default` notifier per
136
+ environment are one atomic logical resource. Equivalent replay returns
137
+ the original `201` response without extending idempotency retention.
138
+ tags:
139
+ - Projects
140
+ security:
141
+ - clerkSession: []
142
+ - bearerGrant: []
143
+ x-required-scopes:
144
+ - projects:write
145
+ x-account-membership: required
146
+ x-idempotency:
147
+ required: true
148
+ retention_seconds: 604800
149
+ scope:
150
+ - authenticated_account
151
+ - operation_id
152
+ - key
153
+ equivalence: validated_request
154
+ replay_retention_extends: false
155
+ parameters:
156
+ - $ref: "#/components/parameters/IdempotencyKey"
157
+ requestBody:
158
+ required: true
159
+ content:
160
+ application/json:
161
+ schema:
162
+ $ref: "#/components/schemas/CreateProjectRequest"
163
+ examples:
164
+ createProject:
165
+ externalValue: ../fixtures/core-v1/requests/create-project.json
166
+ responses:
167
+ "201":
168
+ description: The complete atomic project bootstrap, or the original resource on equivalent replay.
169
+ headers:
170
+ WhooshBang-Diagnostic-Id:
171
+ $ref: "#/components/headers/DiagnosticId"
172
+ content:
173
+ application/json:
174
+ schema:
175
+ $ref: "#/components/schemas/Project"
176
+ examples:
177
+ createdProject:
178
+ externalValue: ../fixtures/core-v1/success/project-created.json
179
+ "400":
180
+ $ref: "#/components/responses/BadRequest"
181
+ "401":
182
+ $ref: "#/components/responses/Unauthorized"
183
+ "403":
184
+ $ref: "#/components/responses/Forbidden"
185
+ "409":
186
+ $ref: "#/components/responses/Conflict"
187
+ "429":
188
+ $ref: "#/components/responses/RateLimited"
189
+ /v1/projects/{project_id}:
190
+ parameters:
191
+ - $ref: "#/components/parameters/ProjectId"
192
+ get:
193
+ operationId: getProject
194
+ summary: Read one project in the current account
195
+ description: |
196
+ Returns the complete project bootstrap. An absent project and a project
197
+ outside the authenticated account use the same non-enumerating `404`.
198
+ tags:
199
+ - Projects
200
+ security:
201
+ - clerkSession: []
202
+ - bearerGrant: []
203
+ x-required-scopes:
204
+ - projects:read
205
+ x-account-membership: required
206
+ responses:
207
+ "200":
208
+ description: The current project and its two environments.
209
+ headers:
210
+ WhooshBang-Diagnostic-Id:
211
+ $ref: "#/components/headers/DiagnosticId"
212
+ content:
213
+ application/json:
214
+ schema:
215
+ $ref: "#/components/schemas/Project"
216
+ examples:
217
+ project:
218
+ externalValue: ../fixtures/core-v1/success/project-created.json
219
+ "401":
220
+ $ref: "#/components/responses/Unauthorized"
221
+ "403":
222
+ $ref: "#/components/responses/Forbidden"
223
+ "404":
224
+ $ref: "#/components/responses/NotFound"
225
+ "429":
226
+ $ref: "#/components/responses/RateLimited"
227
+ /v1/projects/{project_id}/environments/{environment_id}/credentials:
228
+ parameters:
229
+ - $ref: "#/components/parameters/ProjectId"
230
+ - $ref: "#/components/parameters/EnvironmentId"
231
+ get:
232
+ operationId: listApiCredentials
233
+ summary: List safe API credential metadata
234
+ description: |
235
+ Returns only credentials in the selected project environment owned by
236
+ the account selected by the verified Clerk organization session.
237
+ Secrets and digest material are never returned. An absent or
238
+ out-of-account project or environment uses the same non-enumerating
239
+ `404`.
240
+ tags:
241
+ - API credentials
242
+ security:
243
+ - clerkSession: []
244
+ x-account-membership: required
245
+ parameters:
246
+ - $ref: "#/components/parameters/ApiCredentialAfterCursor"
247
+ - $ref: "#/components/parameters/ApiCredentialPageLimit"
248
+ responses:
249
+ "200":
250
+ description: A stable page of safe credential metadata.
251
+ headers:
252
+ WhooshBang-Diagnostic-Id:
253
+ $ref: "#/components/headers/DiagnosticId"
254
+ content:
255
+ application/json:
256
+ schema:
257
+ $ref: "#/components/schemas/ApiCredentialCollection"
258
+ examples:
259
+ credentials:
260
+ externalValue: ../fixtures/core-v1/success/api-credential-collection.json
261
+ "400":
262
+ $ref: "#/components/responses/BadRequest"
263
+ "401":
264
+ $ref: "#/components/responses/Unauthorized"
265
+ "403":
266
+ $ref: "#/components/responses/Forbidden"
267
+ "404":
268
+ $ref: "#/components/responses/NotFound"
269
+ "429":
270
+ $ref: "#/components/responses/RateLimited"
271
+ post:
272
+ operationId: createApiCredential
273
+ summary: Create an environment-scoped API credential
274
+ description: |
275
+ Creates one credential in the selected project environment. The complete
276
+ bearer secret appears only in this creation response. It cannot be read
277
+ later and is never replayed from an idempotency cache. If a client loses
278
+ this response, it lists safe metadata and creates then revokes a
279
+ replacement.
280
+ tags:
281
+ - API credentials
282
+ security:
283
+ - clerkSession: []
284
+ x-account-membership: required
285
+ x-secret-reveal:
286
+ responses: 1
287
+ replayable: false
288
+ later_reads: metadata_only
289
+ requestBody:
290
+ required: true
291
+ content:
292
+ application/json:
293
+ schema:
294
+ $ref: "#/components/schemas/CreateApiCredentialRequest"
295
+ examples:
296
+ createCredential:
297
+ externalValue: ../fixtures/core-v1/requests/create-api-credential.json
298
+ responses:
299
+ "201":
300
+ description: Creation-only secret reveal and safe credential metadata.
301
+ headers:
302
+ WhooshBang-Diagnostic-Id:
303
+ $ref: "#/components/headers/DiagnosticId"
304
+ content:
305
+ application/json:
306
+ schema:
307
+ $ref: "#/components/schemas/ApiCredentialSecretReveal"
308
+ examples:
309
+ createdCredential:
310
+ externalValue: ../fixtures/core-v1/success/api-credential-created.json
311
+ "400":
312
+ $ref: "#/components/responses/BadRequest"
313
+ "401":
314
+ $ref: "#/components/responses/Unauthorized"
315
+ "403":
316
+ $ref: "#/components/responses/Forbidden"
317
+ "404":
318
+ $ref: "#/components/responses/NotFound"
319
+ "429":
320
+ $ref: "#/components/responses/RateLimited"
321
+ /v1/projects/{project_id}/environments/{environment_id}/credentials/{credential_id}/rotate:
322
+ parameters:
323
+ - $ref: "#/components/parameters/ProjectId"
324
+ - $ref: "#/components/parameters/EnvironmentId"
325
+ - $ref: "#/components/parameters/ApiCredentialId"
326
+ post:
327
+ operationId: rotateApiCredential
328
+ summary: Rotate an environment-scoped API credential
329
+ description: |
330
+ Creates one replacement with the same label and scopes. The complete new
331
+ bearer secret appears only in this response. The replaced credential
332
+ remains active for the explicitly declared overlap, from zero through
333
+ 86400 seconds, then becomes terminally revoked. A revoked credential
334
+ cannot be rotated. Missing and out-of-scope credentials use the same
335
+ non-enumerating `404`.
336
+ tags:
337
+ - API credentials
338
+ security:
339
+ - clerkSession: []
340
+ x-account-membership: required
341
+ x-secret-reveal:
342
+ responses: 1
343
+ replayable: false
344
+ later_reads: metadata_only
345
+ requestBody:
346
+ required: true
347
+ content:
348
+ application/json:
349
+ schema:
350
+ $ref: "#/components/schemas/RotateApiCredentialRequest"
351
+ examples:
352
+ rotateCredential:
353
+ externalValue: ../fixtures/core-v1/requests/rotate-api-credential.json
354
+ responses:
355
+ "201":
356
+ description: Creation-only replacement secret and safe metadata for both credentials.
357
+ headers:
358
+ WhooshBang-Diagnostic-Id:
359
+ $ref: "#/components/headers/DiagnosticId"
360
+ content:
361
+ application/json:
362
+ schema:
363
+ $ref: "#/components/schemas/ApiCredentialRotation"
364
+ examples:
365
+ rotatedCredential:
366
+ externalValue: ../fixtures/core-v1/success/api-credential-rotated.json
367
+ "400":
368
+ $ref: "#/components/responses/BadRequest"
369
+ "401":
370
+ $ref: "#/components/responses/Unauthorized"
371
+ "403":
372
+ $ref: "#/components/responses/Forbidden"
373
+ "404":
374
+ $ref: "#/components/responses/NotFound"
375
+ "429":
376
+ $ref: "#/components/responses/RateLimited"
377
+ /v1/projects/{project_id}/environments/{environment_id}/credentials/{credential_id}/revoke:
378
+ parameters:
379
+ - $ref: "#/components/parameters/ProjectId"
380
+ - $ref: "#/components/parameters/EnvironmentId"
381
+ - $ref: "#/components/parameters/ApiCredentialId"
382
+ post:
383
+ operationId: revokeApiCredential
384
+ summary: Revoke an environment-scoped API credential
385
+ description: |
386
+ Immediately and terminally revokes the selected credential. Repeating
387
+ the request for the same visible credential is safe and returns the
388
+ same revoked metadata without revealing secret or digest material.
389
+ Missing and out-of-scope credentials use the same non-enumerating `404`.
390
+ tags:
391
+ - API credentials
392
+ security:
393
+ - clerkSession: []
394
+ x-account-membership: required
395
+ x-repeat-semantics:
396
+ same_target: idempotent
397
+ secret_returned: false
398
+ responses:
399
+ "200":
400
+ description: Safe terminal credential metadata.
401
+ headers:
402
+ WhooshBang-Diagnostic-Id:
403
+ $ref: "#/components/headers/DiagnosticId"
404
+ content:
405
+ application/json:
406
+ schema:
407
+ $ref: "#/components/schemas/ApiCredential"
408
+ examples:
409
+ revokedCredential:
410
+ externalValue: ../fixtures/core-v1/success/api-credential-revoked.json
411
+ "401":
412
+ $ref: "#/components/responses/Unauthorized"
413
+ "403":
414
+ $ref: "#/components/responses/Forbidden"
415
+ "404":
416
+ $ref: "#/components/responses/NotFound"
417
+ "429":
418
+ $ref: "#/components/responses/RateLimited"
419
+ /v1/subscription-links:
420
+ post:
421
+ operationId: createSubscriptionLink
422
+ summary: Create a subscription link
423
+ description: |
424
+ Creates one single-use authorization link inside the authenticated
425
+ project and environment. Equivalent replay returns the original `201`
426
+ response and logical resource without extending idempotency retention.
427
+ tags:
428
+ - Subscription links
429
+ security:
430
+ - bearerCredential: []
431
+ x-required-scopes:
432
+ - subscriptions:write
433
+ x-idempotency:
434
+ required: true
435
+ retention_seconds: 604800
436
+ scope:
437
+ - authenticated_environment
438
+ - operation_id
439
+ - key
440
+ equivalence: validated_request_after_documented_defaults
441
+ replay_retention_extends: false
442
+ parameters:
443
+ - $ref: "#/components/parameters/IdempotencyKey"
444
+ requestBody:
445
+ required: true
446
+ content:
447
+ application/json:
448
+ schema:
449
+ $ref: "#/components/schemas/CreateSubscriptionLinkRequest"
450
+ examples:
451
+ defaultTelegram:
452
+ externalValue: ../fixtures/core-v1/requests/create-subscription-link.json
453
+ responses:
454
+ "201":
455
+ description: A new link, or the original link and original status on equivalent replay.
456
+ headers:
457
+ WhooshBang-Diagnostic-Id:
458
+ $ref: "#/components/headers/DiagnosticId"
459
+ content:
460
+ application/json:
461
+ schema:
462
+ $ref: "#/components/schemas/SubscriptionLink"
463
+ examples:
464
+ pending:
465
+ externalValue: ../fixtures/core-v1/success/subscription-link-pending.json
466
+ "400":
467
+ $ref: "#/components/responses/BadRequest"
468
+ "401":
469
+ $ref: "#/components/responses/Unauthorized"
470
+ "403":
471
+ $ref: "#/components/responses/Forbidden"
472
+ "409":
473
+ $ref: "#/components/responses/Conflict"
474
+ "429":
475
+ $ref: "#/components/responses/RateLimited"
476
+ /v1/subscription-links/{subscription_link_id}:
477
+ parameters:
478
+ - $ref: "#/components/parameters/SubscriptionLinkId"
479
+ get:
480
+ operationId: getSubscriptionLink
481
+ summary: Inspect a subscription link
482
+ description: |
483
+ Returns the current link state. An activated or revoked link exposes an
484
+ opaque binding summary, never a Telegram chat or user identifier.
485
+ Cross-project and cross-environment identifiers return `404`.
486
+ tags:
487
+ - Subscription links
488
+ security:
489
+ - bearerCredential: []
490
+ x-required-scopes:
491
+ - subscriptions:read
492
+ responses:
493
+ "200":
494
+ description: Current link state.
495
+ headers:
496
+ WhooshBang-Diagnostic-Id:
497
+ $ref: "#/components/headers/DiagnosticId"
498
+ content:
499
+ application/json:
500
+ schema:
501
+ $ref: "#/components/schemas/SubscriptionLink"
502
+ examples:
503
+ activated:
504
+ externalValue: ../fixtures/core-v1/success/subscription-link-activated.json
505
+ "401":
506
+ $ref: "#/components/responses/Unauthorized"
507
+ "403":
508
+ $ref: "#/components/responses/Forbidden"
509
+ "404":
510
+ $ref: "#/components/responses/NotFound"
511
+ "429":
512
+ $ref: "#/components/responses/RateLimited"
513
+ /v1/subscription-links/{subscription_link_id}/cancel:
514
+ parameters:
515
+ - $ref: "#/components/parameters/SubscriptionLinkId"
516
+ post:
517
+ operationId: cancelSubscriptionLink
518
+ summary: Cancel a pending subscription link
519
+ description: |
520
+ Cancels a pending link. Equivalent replay returns the original result.
521
+ Consumption of a cancelled or expired link never creates a binding.
522
+ tags:
523
+ - Subscription links
524
+ security:
525
+ - bearerCredential: []
526
+ x-required-scopes:
527
+ - subscriptions:write
528
+ x-idempotency:
529
+ required: true
530
+ retention_seconds: 604800
531
+ scope:
532
+ - authenticated_environment
533
+ - operation_id
534
+ - key
535
+ equivalence: validated_request_after_documented_defaults
536
+ replay_retention_extends: false
537
+ parameters:
538
+ - $ref: "#/components/parameters/IdempotencyKey"
539
+ responses:
540
+ "200":
541
+ description: Current link state and whether cancellation took effect.
542
+ headers:
543
+ WhooshBang-Diagnostic-Id:
544
+ $ref: "#/components/headers/DiagnosticId"
545
+ content:
546
+ application/json:
547
+ schema:
548
+ allOf:
549
+ - $ref: "#/components/schemas/SubscriptionLink"
550
+ - type: object
551
+ required:
552
+ - cancellation_effective
553
+ examples:
554
+ cancelled:
555
+ externalValue: ../fixtures/core-v1/success/subscription-link-cancelled.json
556
+ "400":
557
+ $ref: "#/components/responses/BadRequest"
558
+ "401":
559
+ $ref: "#/components/responses/Unauthorized"
560
+ "403":
561
+ $ref: "#/components/responses/Forbidden"
562
+ "404":
563
+ $ref: "#/components/responses/NotFound"
564
+ "409":
565
+ $ref: "#/components/responses/Conflict"
566
+ "429":
567
+ $ref: "#/components/responses/RateLimited"
568
+ /v1/messages:
569
+ post:
570
+ operationId: createMessage
571
+ summary: Create an asynchronous message
572
+ description: |
573
+ Durably accepts one logical text message for one subscriber and one
574
+ resolved channel binding. `202` proves API acceptance only; it does not
575
+ claim provider acceptance or end-device delivery.
576
+ tags:
577
+ - Messages
578
+ security:
579
+ - bearerCredential: []
580
+ - machineCredential: []
581
+ x-required-scopes:
582
+ - messages:write
583
+ x-machine-required-scopes:
584
+ - machine-messages:write
585
+ x-machine-binding-enforcement:
586
+ - authenticated_project
587
+ - authenticated_environment
588
+ - bound_notifier
589
+ - bound_subscriber
590
+ x-idempotency:
591
+ required: true
592
+ retention_seconds: 604800
593
+ scope:
594
+ - authenticated_environment
595
+ - operation_id
596
+ - key
597
+ equivalence: validated_request_after_documented_defaults
598
+ replay_retention_extends: false
599
+ parameters:
600
+ - $ref: "#/components/parameters/IdempotencyKey"
601
+ requestBody:
602
+ required: true
603
+ content:
604
+ application/json:
605
+ schema:
606
+ $ref: "#/components/schemas/CreateMessageRequest"
607
+ examples:
608
+ text:
609
+ externalValue: ../fixtures/core-v1/requests/create-message.json
610
+ confirm:
611
+ externalValue: ../fixtures/interaction-machine-v1/requests/create-message-confirm.json
612
+ select:
613
+ externalValue: ../fixtures/interaction-machine-v1/requests/create-message-select.json
614
+ input:
615
+ externalValue: ../fixtures/interaction-machine-v1/requests/create-message-input.json
616
+ responses:
617
+ "202":
618
+ description: A newly accepted message, or the original message and status on equivalent replay.
619
+ headers:
620
+ WhooshBang-Diagnostic-Id:
621
+ $ref: "#/components/headers/DiagnosticId"
622
+ content:
623
+ application/json:
624
+ schema:
625
+ $ref: "#/components/schemas/Message"
626
+ examples:
627
+ accepted:
628
+ externalValue: ../fixtures/core-v1/success/message-accepted.json
629
+ interactionOpen:
630
+ externalValue: ../fixtures/interaction-machine-v1/success/message-interaction-open.json
631
+ "400":
632
+ $ref: "#/components/responses/BadRequest"
633
+ "401":
634
+ $ref: "#/components/responses/Unauthorized"
635
+ "403":
636
+ $ref: "#/components/responses/Forbidden"
637
+ "409":
638
+ $ref: "#/components/responses/Conflict"
639
+ "422":
640
+ $ref: "#/components/responses/Unprocessable"
641
+ "429":
642
+ $ref: "#/components/responses/RateLimited"
643
+ /v1/messages/{message_id}:
644
+ parameters:
645
+ - $ref: "#/components/parameters/MessageId"
646
+ get:
647
+ operationId: getMessage
648
+ summary: Inspect a message
649
+ description: |
650
+ Returns the canonical logical state and highest proven provider state.
651
+ `outcome_unknown` is distinct from retryable and terminal failure and
652
+ never has an automatic retry scheduled.
653
+
654
+ When the message has an open interaction, the optional bounded `wait`
655
+ holds this read for its canonical terminal state. A wait timeout is a
656
+ successful current-state read, not an error. Terminal interactions and
657
+ messages without an interaction return immediately. Inspection never
658
+ acknowledges, consumes, retries, replays, or changes delivery.
659
+ parameters:
660
+ - $ref: "#/components/parameters/ResponseInspectionWait"
661
+ tags:
662
+ - Messages
663
+ security:
664
+ - bearerCredential: []
665
+ - machineCredential: []
666
+ x-required-scopes:
667
+ - messages:read
668
+ x-machine-required-scopes:
669
+ - machine-messages:read
670
+ x-machine-binding-enforcement:
671
+ - authenticated_project
672
+ - authenticated_environment
673
+ - owning_machine_client
674
+ responses:
675
+ "200":
676
+ description: Current message and safe delivery-attempt summary.
677
+ headers:
678
+ WhooshBang-Diagnostic-Id:
679
+ $ref: "#/components/headers/DiagnosticId"
680
+ content:
681
+ application/json:
682
+ schema:
683
+ $ref: "#/components/schemas/Message"
684
+ examples:
685
+ providerAccepted:
686
+ externalValue: ../fixtures/core-v1/success/message-provider-accepted.json
687
+ outcomeUnknown:
688
+ externalValue: ../fixtures/core-v1/success/message-outcome-unknown.json
689
+ interactionOpen:
690
+ externalValue: ../fixtures/interaction-machine-v1/success/message-interaction-open.json
691
+ "400":
692
+ $ref: "#/components/responses/BadRequest"
693
+ "401":
694
+ $ref: "#/components/responses/Unauthorized"
695
+ "403":
696
+ $ref: "#/components/responses/Forbidden"
697
+ "404":
698
+ $ref: "#/components/responses/NotFound"
699
+ "429":
700
+ $ref: "#/components/responses/RateLimited"
701
+ /v1/interactions/{interaction_id}:
702
+ parameters:
703
+ - $ref: "#/components/parameters/InteractionId"
704
+ get:
705
+ operationId: getInteraction
706
+ summary: Inspect an interaction response
707
+ description: |
708
+ Returns the same canonical first-terminal-writer interaction summary
709
+ used by message status, signed customer events, and machine events.
710
+ An answered interaction always retains `answered` and `answered_at`;
711
+ `answer_retained` says whether the typed answer is still present.
712
+
713
+ The optional bounded `wait` holds an open interaction read for a
714
+ terminal state. Expiry without resolution returns the current `open`
715
+ summary successfully and can be immediately re-polled. Inspection is
716
+ read-only and has no effect on any delivery or retention lifecycle.
717
+ parameters:
718
+ - $ref: "#/components/parameters/ResponseInspectionWait"
719
+ tags:
720
+ - Messages
721
+ security:
722
+ - bearerCredential: []
723
+ - machineCredential: []
724
+ x-required-scopes:
725
+ - messages:read
726
+ x-machine-required-scopes:
727
+ - machine-messages:read
728
+ x-machine-binding-enforcement:
729
+ - authenticated_project
730
+ - authenticated_environment
731
+ - owning_machine_client
732
+ responses:
733
+ "200":
734
+ description: Current canonical interaction state and retained answer.
735
+ headers:
736
+ WhooshBang-Diagnostic-Id:
737
+ $ref: "#/components/headers/DiagnosticId"
738
+ content:
739
+ application/json:
740
+ schema:
741
+ $ref: "#/components/schemas/InteractionSummary"
742
+ examples:
743
+ open:
744
+ externalValue: ../fixtures/interaction-machine-v1/success/interaction-open.json
745
+ answeredConfirm:
746
+ externalValue: ../fixtures/interaction-machine-v1/success/interaction-answered-confirm.json
747
+ answeredSelect:
748
+ externalValue: ../fixtures/interaction-machine-v1/success/interaction-answered-select.json
749
+ answeredInput:
750
+ externalValue: ../fixtures/interaction-machine-v1/success/interaction-answered-input.json
751
+ answeredRedacted:
752
+ externalValue: ../fixtures/interaction-machine-v1/success/interaction-answered-redacted.json
753
+ "400":
754
+ $ref: "#/components/responses/BadRequest"
755
+ "401":
756
+ $ref: "#/components/responses/Unauthorized"
757
+ "403":
758
+ $ref: "#/components/responses/Forbidden"
759
+ "404":
760
+ $ref: "#/components/responses/NotFound"
761
+ "429":
762
+ $ref: "#/components/responses/RateLimited"
763
+ /v1/messages/{message_id}/cancel:
764
+ parameters:
765
+ - $ref: "#/components/parameters/MessageId"
766
+ post:
767
+ operationId: cancelMessage
768
+ summary: Cancel a message before provider-call ownership
769
+ description: |
770
+ Cancellation is effective only before a worker owns the provider call.
771
+ A race at `sending`, `provider_accepted`, or `outcome_unknown` returns
772
+ the current state with `cancellation_effective: false` and never claims
773
+ provider-side deletion.
774
+ tags:
775
+ - Messages
776
+ security:
777
+ - bearerCredential: []
778
+ x-required-scopes:
779
+ - messages:write
780
+ x-idempotency:
781
+ required: true
782
+ retention_seconds: 604800
783
+ scope:
784
+ - authenticated_environment
785
+ - operation_id
786
+ - key
787
+ equivalence: validated_request_after_documented_defaults
788
+ replay_retention_extends: false
789
+ parameters:
790
+ - $ref: "#/components/parameters/IdempotencyKey"
791
+ responses:
792
+ "200":
793
+ description: Current message state and whether cancellation took effect.
794
+ headers:
795
+ WhooshBang-Diagnostic-Id:
796
+ $ref: "#/components/headers/DiagnosticId"
797
+ content:
798
+ application/json:
799
+ schema:
800
+ allOf:
801
+ - $ref: "#/components/schemas/Message"
802
+ - type: object
803
+ required:
804
+ - cancellation_effective
805
+ examples:
806
+ cancelled:
807
+ externalValue: ../fixtures/core-v1/success/message-cancelled.json
808
+ tooLate:
809
+ externalValue: ../fixtures/core-v1/success/message-cancellation-too-late.json
810
+ "400":
811
+ $ref: "#/components/responses/BadRequest"
812
+ "401":
813
+ $ref: "#/components/responses/Unauthorized"
814
+ "403":
815
+ $ref: "#/components/responses/Forbidden"
816
+ "404":
817
+ $ref: "#/components/responses/NotFound"
818
+ "409":
819
+ $ref: "#/components/responses/Conflict"
820
+ "429":
821
+ $ref: "#/components/responses/RateLimited"
822
+ /v1/machine-clients:
823
+ post:
824
+ operationId: createMachineClient
825
+ summary: Create a destination-bound machine client
826
+ description: |
827
+ Creates one machine client in the project/environment selected by the
828
+ project credential. The notifier, subscriber, and active binding become
829
+ immutable authorization bounds. The response never contains a readable
830
+ secret or digest.
831
+ tags:
832
+ - Machine clients
833
+ security:
834
+ - bearerCredential: []
835
+ x-required-scopes:
836
+ - machine-clients:write
837
+ x-idempotency:
838
+ required: true
839
+ retention_seconds: 604800
840
+ scope:
841
+ - authenticated_environment
842
+ - operation_id
843
+ - key
844
+ equivalence: validated_request_after_documented_defaults
845
+ replay_retention_extends: false
846
+ parameters:
847
+ - $ref: "#/components/parameters/IdempotencyKey"
848
+ requestBody:
849
+ required: true
850
+ content:
851
+ application/json:
852
+ schema:
853
+ $ref: "#/components/schemas/CreateMachineClientRequest"
854
+ examples:
855
+ localClient:
856
+ externalValue: ../fixtures/interaction-machine-v1/requests/create-machine-client.json
857
+ responses:
858
+ "201":
859
+ description: A new provisioning client or the original client on equivalent replay.
860
+ headers:
861
+ WhooshBang-Diagnostic-Id:
862
+ $ref: "#/components/headers/DiagnosticId"
863
+ content:
864
+ application/json:
865
+ schema:
866
+ $ref: "#/components/schemas/MachineClient"
867
+ examples:
868
+ provisioning:
869
+ externalValue: ../fixtures/interaction-machine-v1/success/machine-client-provisioning.json
870
+ "400":
871
+ $ref: "#/components/responses/BadRequest"
872
+ "401":
873
+ $ref: "#/components/responses/Unauthorized"
874
+ "403":
875
+ $ref: "#/components/responses/Forbidden"
876
+ "409":
877
+ $ref: "#/components/responses/Conflict"
878
+ "422":
879
+ $ref: "#/components/responses/Unprocessable"
880
+ "429":
881
+ $ref: "#/components/responses/RateLimited"
882
+ /v1/machine-clients/{machine_client_id}:
883
+ parameters:
884
+ - $ref: "#/components/parameters/MachineClientId"
885
+ get:
886
+ operationId: getMachineClient
887
+ summary: Inspect machine-client metadata
888
+ description: |
889
+ Returns only safe metadata inside the authenticated project/environment.
890
+ A client outside that scope is indistinguishable from an absent client.
891
+ tags:
892
+ - Machine clients
893
+ security:
894
+ - bearerCredential: []
895
+ x-required-scopes:
896
+ - machine-clients:read
897
+ responses:
898
+ "200":
899
+ description: Current machine-client metadata and fixed scope summary.
900
+ headers:
901
+ WhooshBang-Diagnostic-Id:
902
+ $ref: "#/components/headers/DiagnosticId"
903
+ content:
904
+ application/json:
905
+ schema:
906
+ $ref: "#/components/schemas/MachineClient"
907
+ examples:
908
+ active:
909
+ externalValue: ../fixtures/interaction-machine-v1/success/machine-client-active.json
910
+ "401":
911
+ $ref: "#/components/responses/Unauthorized"
912
+ "403":
913
+ $ref: "#/components/responses/Forbidden"
914
+ "404":
915
+ $ref: "#/components/responses/NotFound"
916
+ "429":
917
+ $ref: "#/components/responses/RateLimited"
918
+ /v1/machine-clients/{machine_client_id}/credentials:
919
+ parameters:
920
+ - $ref: "#/components/parameters/MachineClientId"
921
+ post:
922
+ operationId: registerMachineCredential
923
+ summary: Register a locally generated machine-credential digest
924
+ description: |
925
+ Registers only the credential ID and SHA-256 digest. The same ID and
926
+ digest returns existing safe metadata; the same ID with another digest
927
+ conflicts. The first active credential activates a provisioning client.
928
+ tags:
929
+ - Machine clients
930
+ security:
931
+ - bearerCredential: []
932
+ x-required-scopes:
933
+ - machine-clients:write
934
+ x-idempotency:
935
+ required: true
936
+ retention_seconds: 604800
937
+ scope:
938
+ - authenticated_environment
939
+ - operation_id
940
+ - key
941
+ equivalence: validated_request_after_documented_defaults
942
+ replay_retention_extends: false
943
+ parameters:
944
+ - $ref: "#/components/parameters/IdempotencyKey"
945
+ requestBody:
946
+ required: true
947
+ content:
948
+ application/json:
949
+ schema:
950
+ $ref: "#/components/schemas/RegisterMachineCredentialRequest"
951
+ examples:
952
+ digestOnly:
953
+ externalValue: ../fixtures/interaction-machine-v1/requests/register-machine-credential.json
954
+ responses:
955
+ "200":
956
+ description: Existing safe credential metadata on an equivalent registration replay; never secret or digest.
957
+ headers:
958
+ WhooshBang-Diagnostic-Id:
959
+ $ref: "#/components/headers/DiagnosticId"
960
+ content:
961
+ application/json:
962
+ schema:
963
+ $ref: "#/components/schemas/MachineCredential"
964
+ examples:
965
+ existing:
966
+ externalValue: ../fixtures/interaction-machine-v1/success/machine-credential-active.json
967
+ "201":
968
+ description: Newly registered safe credential metadata; never secret or digest.
969
+ headers:
970
+ WhooshBang-Diagnostic-Id:
971
+ $ref: "#/components/headers/DiagnosticId"
972
+ content:
973
+ application/json:
974
+ schema:
975
+ $ref: "#/components/schemas/MachineCredential"
976
+ examples:
977
+ active:
978
+ externalValue: ../fixtures/interaction-machine-v1/success/machine-credential-active.json
979
+ "400":
980
+ $ref: "#/components/responses/BadRequest"
981
+ "401":
982
+ $ref: "#/components/responses/Unauthorized"
983
+ "403":
984
+ $ref: "#/components/responses/Forbidden"
985
+ "404":
986
+ $ref: "#/components/responses/NotFound"
987
+ "409":
988
+ $ref: "#/components/responses/Conflict"
989
+ "429":
990
+ $ref: "#/components/responses/RateLimited"
991
+ /v1/machine-clients/{machine_client_id}/credentials/{credential_id}/revoke:
992
+ parameters:
993
+ - $ref: "#/components/parameters/MachineClientId"
994
+ - $ref: "#/components/parameters/MachineCredentialId"
995
+ post:
996
+ operationId: revokeMachineCredential
997
+ summary: Revoke a machine credential
998
+ description: |
999
+ Idempotently ends new authorization by this credential. Rotation
1000
+ registers and smoke-tests a replacement before this operation.
1001
+ tags:
1002
+ - Machine clients
1003
+ security:
1004
+ - bearerCredential: []
1005
+ x-required-scopes:
1006
+ - machine-clients:write
1007
+ x-idempotency:
1008
+ required: true
1009
+ retention_seconds: 604800
1010
+ scope:
1011
+ - authenticated_environment
1012
+ - operation_id
1013
+ - key
1014
+ equivalence: validated_request_after_documented_defaults
1015
+ replay_retention_extends: false
1016
+ parameters:
1017
+ - $ref: "#/components/parameters/IdempotencyKey"
1018
+ responses:
1019
+ "200":
1020
+ description: Safe revoked credential metadata.
1021
+ headers:
1022
+ WhooshBang-Diagnostic-Id:
1023
+ $ref: "#/components/headers/DiagnosticId"
1024
+ content:
1025
+ application/json:
1026
+ schema:
1027
+ $ref: "#/components/schemas/MachineCredential"
1028
+ examples:
1029
+ revoked:
1030
+ externalValue: ../fixtures/interaction-machine-v1/success/machine-credential-revoked.json
1031
+ "400":
1032
+ $ref: "#/components/responses/BadRequest"
1033
+ "401":
1034
+ $ref: "#/components/responses/Unauthorized"
1035
+ "403":
1036
+ $ref: "#/components/responses/Forbidden"
1037
+ "404":
1038
+ $ref: "#/components/responses/NotFound"
1039
+ "409":
1040
+ $ref: "#/components/responses/Conflict"
1041
+ "429":
1042
+ $ref: "#/components/responses/RateLimited"
1043
+ /v1/machine-clients/{machine_client_id}/revoke:
1044
+ parameters:
1045
+ - $ref: "#/components/parameters/MachineClientId"
1046
+ post:
1047
+ operationId: revokeMachineClient
1048
+ summary: Revoke a machine client
1049
+ description: |
1050
+ Idempotently revokes the client and all new credential authorization.
1051
+ Existing messages and immutable events are retained under contract.
1052
+ tags:
1053
+ - Machine clients
1054
+ security:
1055
+ - bearerCredential: []
1056
+ x-required-scopes:
1057
+ - machine-clients:write
1058
+ x-idempotency:
1059
+ required: true
1060
+ retention_seconds: 604800
1061
+ scope:
1062
+ - authenticated_environment
1063
+ - operation_id
1064
+ - key
1065
+ equivalence: validated_request_after_documented_defaults
1066
+ replay_retention_extends: false
1067
+ parameters:
1068
+ - $ref: "#/components/parameters/IdempotencyKey"
1069
+ responses:
1070
+ "200":
1071
+ description: Safe revoked client metadata.
1072
+ headers:
1073
+ WhooshBang-Diagnostic-Id:
1074
+ $ref: "#/components/headers/DiagnosticId"
1075
+ content:
1076
+ application/json:
1077
+ schema:
1078
+ $ref: "#/components/schemas/MachineClient"
1079
+ examples:
1080
+ revoked:
1081
+ externalValue: ../fixtures/interaction-machine-v1/success/machine-client-revoked.json
1082
+ "400":
1083
+ $ref: "#/components/responses/BadRequest"
1084
+ "401":
1085
+ $ref: "#/components/responses/Unauthorized"
1086
+ "403":
1087
+ $ref: "#/components/responses/Forbidden"
1088
+ "404":
1089
+ $ref: "#/components/responses/NotFound"
1090
+ "409":
1091
+ $ref: "#/components/responses/Conflict"
1092
+ "429":
1093
+ $ref: "#/components/responses/RateLimited"
1094
+ /v1/machine-events:
1095
+ get:
1096
+ operationId: pollMachineEvents
1097
+ summary: Long-poll the authenticated machine stream
1098
+ description: |
1099
+ Polls only the stream selected by the machine credential. `after` is
1100
+ omitted only on the first poll and otherwise must equal the exact
1101
+ atomically committed cursor returned for this stream. Any other cursor,
1102
+ including a known issued but uncommitted cursor, fails closed and never
1103
+ rewinds. Unacknowledged events may repeat with the same event ID and
1104
+ cursor.
1105
+ tags:
1106
+ - Machine events
1107
+ security:
1108
+ - machineCredential: []
1109
+ x-required-scopes:
1110
+ - machine-events:read
1111
+ x-event-retention:
1112
+ minimum_seconds_after_creation: 604800
1113
+ extends_interaction_answer_authority: false
1114
+ parameters:
1115
+ - $ref: "#/components/parameters/MachineAfterCursor"
1116
+ - $ref: "#/components/parameters/MachinePollWait"
1117
+ - $ref: "#/components/parameters/MachinePollLimit"
1118
+ responses:
1119
+ "200":
1120
+ description: Stable ordered events and the atomically committed cursor.
1121
+ headers:
1122
+ WhooshBang-Diagnostic-Id:
1123
+ $ref: "#/components/headers/DiagnosticId"
1124
+ content:
1125
+ application/json:
1126
+ schema:
1127
+ $ref: "#/components/schemas/MachineEventPollResponse"
1128
+ examples:
1129
+ events:
1130
+ externalValue: ../fixtures/interaction-machine-v1/success/poll-events.json
1131
+ empty:
1132
+ externalValue: ../fixtures/interaction-machine-v1/success/poll-empty.json
1133
+ "400":
1134
+ $ref: "#/components/responses/BadRequest"
1135
+ "401":
1136
+ $ref: "#/components/responses/Unauthorized"
1137
+ "403":
1138
+ $ref: "#/components/responses/Forbidden"
1139
+ "404":
1140
+ $ref: "#/components/responses/NotFound"
1141
+ "429":
1142
+ $ref: "#/components/responses/RateLimited"
1143
+ /v1/machine-events/{event_id}/ack:
1144
+ parameters:
1145
+ - $ref: "#/components/parameters/MachineEventId"
1146
+ post:
1147
+ operationId: ackMachineEvent
1148
+ summary: Record a per-event machine acknowledgement
1149
+ description: |
1150
+ Records processed or permitted quarantine disposition idempotently.
1151
+ The committed cursor advances only across a contiguous acknowledged
1152
+ prefix. Authentication, stream identity, signature, and schema failures
1153
+ cannot be quarantined to skip work.
1154
+ tags:
1155
+ - Machine events
1156
+ security:
1157
+ - machineCredential: []
1158
+ x-required-scopes:
1159
+ - machine-events:ack
1160
+ x-idempotency:
1161
+ required: true
1162
+ retention_seconds: 604800
1163
+ scope:
1164
+ - authenticated_environment
1165
+ - operation_id
1166
+ - key
1167
+ equivalence: validated_request_after_documented_defaults
1168
+ replay_retention_extends: false
1169
+ parameters:
1170
+ - $ref: "#/components/parameters/IdempotencyKey"
1171
+ requestBody:
1172
+ required: true
1173
+ content:
1174
+ application/json:
1175
+ schema:
1176
+ $ref: "#/components/schemas/MachineEventAckRequest"
1177
+ examples:
1178
+ processed:
1179
+ externalValue: ../fixtures/interaction-machine-v1/requests/ack-processed.json
1180
+ quarantined:
1181
+ externalValue: ../fixtures/interaction-machine-v1/requests/ack-quarantined.json
1182
+ responses:
1183
+ "200":
1184
+ description: New or existing acknowledgement and current committed position.
1185
+ headers:
1186
+ WhooshBang-Diagnostic-Id:
1187
+ $ref: "#/components/headers/DiagnosticId"
1188
+ content:
1189
+ application/json:
1190
+ schema:
1191
+ $ref: "#/components/schemas/MachineEventAckResponse"
1192
+ examples:
1193
+ processed:
1194
+ externalValue: ../fixtures/interaction-machine-v1/success/ack-processed.json
1195
+ outOfOrder:
1196
+ externalValue: ../fixtures/interaction-machine-v1/success/ack-out-of-order.json
1197
+ quarantined:
1198
+ externalValue: ../fixtures/interaction-machine-v1/success/ack-quarantined.json
1199
+ "400":
1200
+ $ref: "#/components/responses/BadRequest"
1201
+ "401":
1202
+ $ref: "#/components/responses/Unauthorized"
1203
+ "403":
1204
+ $ref: "#/components/responses/Forbidden"
1205
+ "404":
1206
+ $ref: "#/components/responses/NotFound"
1207
+ "409":
1208
+ $ref: "#/components/responses/Conflict"
1209
+ "429":
1210
+ $ref: "#/components/responses/RateLimited"
1211
+ /v1/projects/{project_id}/environments/{environment_id}/customer-endpoints:
1212
+ parameters:
1213
+ - $ref: "#/components/parameters/ProjectId"
1214
+ - $ref: "#/components/parameters/EnvironmentId"
1215
+ get:
1216
+ operationId: listCustomerEndpoints
1217
+ summary: List safe customer-endpoint health metadata
1218
+ tags:
1219
+ - Customer endpoints
1220
+ security:
1221
+ - clerkSession: []
1222
+ - bearerCredential: []
1223
+ - bearerGrant: []
1224
+ x-required-scopes:
1225
+ - messages:read
1226
+ responses:
1227
+ "200":
1228
+ description: Safe endpoint lifecycle and health metadata without URLs or protected content.
1229
+ headers:
1230
+ WhooshBang-Diagnostic-Id:
1231
+ $ref: "#/components/headers/DiagnosticId"
1232
+ content:
1233
+ application/json:
1234
+ schema:
1235
+ $ref: "#/components/schemas/CustomerEndpointCollection"
1236
+ examples:
1237
+ endpoints:
1238
+ externalValue: ../fixtures/core-v1/success/customer-endpoint-collection.json
1239
+ "401":
1240
+ $ref: "#/components/responses/Unauthorized"
1241
+ "403":
1242
+ $ref: "#/components/responses/Forbidden"
1243
+ "404":
1244
+ $ref: "#/components/responses/NotFound"
1245
+ post:
1246
+ operationId: createCustomerEndpoint
1247
+ summary: Create an inactive customer endpoint and reveal its signing secret once
1248
+ description: |
1249
+ Validates the final normalized public HTTPS destination before storing it.
1250
+ The initial response includes the new signing secret. An equivalent
1251
+ idempotent replay returns the same logical endpoint without the secret;
1252
+ different input for the same key returns `idempotency_conflict`.
1253
+ tags:
1254
+ - Customer endpoints
1255
+ security:
1256
+ - clerkSession: []
1257
+ - bearerCredential: []
1258
+ - bearerGrant: []
1259
+ x-required-scopes:
1260
+ - messages:write
1261
+ x-idempotency:
1262
+ required: true
1263
+ retention_seconds: 604800
1264
+ scope:
1265
+ - authenticated_environment
1266
+ - operation_id
1267
+ - key
1268
+ equivalence: final_normalized_url_and_validated_request
1269
+ replay_retention_extends: false
1270
+ x-secret-reveal:
1271
+ responses: 1
1272
+ replayable: false
1273
+ later_reads: metadata_only
1274
+ parameters:
1275
+ - $ref: "#/components/parameters/IdempotencyKey"
1276
+ requestBody:
1277
+ required: true
1278
+ content:
1279
+ application/json:
1280
+ schema:
1281
+ $ref: "#/components/schemas/CreateCustomerEndpointRequest"
1282
+ examples:
1283
+ createEndpoint:
1284
+ externalValue: ../fixtures/core-v1/requests/create-customer-endpoint.json
1285
+ responses:
1286
+ "201":
1287
+ description: Newly created unverified endpoint and its one-time signing secret.
1288
+ headers:
1289
+ WhooshBang-Diagnostic-Id:
1290
+ $ref: "#/components/headers/DiagnosticId"
1291
+ content:
1292
+ application/json:
1293
+ schema:
1294
+ $ref: "#/components/schemas/CustomerEndpointMutationResult"
1295
+ examples:
1296
+ created:
1297
+ externalValue: ../fixtures/core-v1/success/customer-endpoint-created.json
1298
+ "200":
1299
+ description: Equivalent replay returning safe endpoint metadata without the secret.
1300
+ content:
1301
+ application/json:
1302
+ schema:
1303
+ $ref: "#/components/schemas/CustomerEndpointMutationResult"
1304
+ examples:
1305
+ replayed:
1306
+ externalValue: ../fixtures/core-v1/success/customer-endpoint-create-replayed.json
1307
+ "400":
1308
+ $ref: "#/components/responses/BadRequest"
1309
+ "401":
1310
+ $ref: "#/components/responses/Unauthorized"
1311
+ "403":
1312
+ $ref: "#/components/responses/Forbidden"
1313
+ "404":
1314
+ $ref: "#/components/responses/NotFound"
1315
+ "409":
1316
+ $ref: "#/components/responses/Conflict"
1317
+ "503":
1318
+ $ref: "#/components/responses/ProviderRetryable"
1319
+ /v1/projects/{project_id}/environments/{environment_id}/customer-endpoints/{endpoint_id}:
1320
+ parameters:
1321
+ - $ref: "#/components/parameters/ProjectId"
1322
+ - $ref: "#/components/parameters/EnvironmentId"
1323
+ - $ref: "#/components/parameters/CustomerEndpointId"
1324
+ get:
1325
+ operationId: getCustomerEndpoint
1326
+ summary: Read safe lifecycle and health metadata for one endpoint
1327
+ tags:
1328
+ - Customer endpoints
1329
+ security:
1330
+ - clerkSession: []
1331
+ - bearerCredential: []
1332
+ - bearerGrant: []
1333
+ x-required-scopes:
1334
+ - messages:read
1335
+ responses:
1336
+ "200":
1337
+ description: Safe endpoint metadata.
1338
+ content:
1339
+ application/json:
1340
+ schema:
1341
+ $ref: "#/components/schemas/CustomerEndpoint"
1342
+ "401":
1343
+ $ref: "#/components/responses/Unauthorized"
1344
+ "403":
1345
+ $ref: "#/components/responses/Forbidden"
1346
+ "404":
1347
+ $ref: "#/components/responses/NotFound"
1348
+ /v1/projects/{project_id}/environments/{environment_id}/customer-endpoints/{endpoint_id}/verify:
1349
+ parameters:
1350
+ - $ref: "#/components/parameters/ProjectId"
1351
+ - $ref: "#/components/parameters/EnvironmentId"
1352
+ - $ref: "#/components/parameters/CustomerEndpointId"
1353
+ post:
1354
+ operationId: verifyCustomerEndpoint
1355
+ summary: Send a signed challenge and activate the endpoint only after a signed echo
1356
+ tags:
1357
+ - Customer endpoints
1358
+ security:
1359
+ - clerkSession: []
1360
+ - bearerCredential: []
1361
+ - bearerGrant: []
1362
+ x-required-scopes:
1363
+ - messages:write
1364
+ responses:
1365
+ "200":
1366
+ description: Verified active endpoint metadata.
1367
+ content:
1368
+ application/json:
1369
+ schema:
1370
+ $ref: "#/components/schemas/CustomerEndpoint"
1371
+ "401":
1372
+ $ref: "#/components/responses/Unauthorized"
1373
+ "403":
1374
+ $ref: "#/components/responses/Forbidden"
1375
+ "404":
1376
+ $ref: "#/components/responses/NotFound"
1377
+ "502":
1378
+ $ref: "#/components/responses/ProviderTerminal"
1379
+ "503":
1380
+ $ref: "#/components/responses/ProviderRetryable"
1381
+ /v1/projects/{project_id}/environments/{environment_id}/customer-endpoints/{endpoint_id}/rotate:
1382
+ parameters:
1383
+ - $ref: "#/components/parameters/ProjectId"
1384
+ - $ref: "#/components/parameters/EnvironmentId"
1385
+ - $ref: "#/components/parameters/CustomerEndpointId"
1386
+ post:
1387
+ operationId: rotateCustomerEndpoint
1388
+ summary: Create a new signing version with bounded old/new overlap
1389
+ tags:
1390
+ - Customer endpoints
1391
+ security:
1392
+ - clerkSession: []
1393
+ - bearerCredential: []
1394
+ - bearerGrant: []
1395
+ x-required-scopes:
1396
+ - messages:write
1397
+ x-idempotency:
1398
+ required: true
1399
+ retention_seconds: 604800
1400
+ scope:
1401
+ - authenticated_environment
1402
+ - operation_id
1403
+ - key
1404
+ equivalence: endpoint_and_validated_request
1405
+ replay_retention_extends: false
1406
+ x-secret-reveal:
1407
+ responses: 1
1408
+ replayable: false
1409
+ later_reads: metadata_only
1410
+ parameters:
1411
+ - $ref: "#/components/parameters/IdempotencyKey"
1412
+ requestBody:
1413
+ required: true
1414
+ content:
1415
+ application/json:
1416
+ schema:
1417
+ $ref: "#/components/schemas/RotateCustomerEndpointRequest"
1418
+ examples:
1419
+ rotate:
1420
+ externalValue: ../fixtures/core-v1/requests/rotate-customer-endpoint.json
1421
+ responses:
1422
+ "201":
1423
+ description: Rotated endpoint and one-time new secret.
1424
+ content:
1425
+ application/json:
1426
+ schema:
1427
+ $ref: "#/components/schemas/CustomerEndpointMutationResult"
1428
+ examples:
1429
+ rotated:
1430
+ externalValue: ../fixtures/core-v1/success/customer-endpoint-rotated.json
1431
+ "200":
1432
+ description: Equivalent replay without another secret reveal.
1433
+ content:
1434
+ application/json:
1435
+ schema:
1436
+ $ref: "#/components/schemas/CustomerEndpointMutationResult"
1437
+ "400":
1438
+ $ref: "#/components/responses/BadRequest"
1439
+ "401":
1440
+ $ref: "#/components/responses/Unauthorized"
1441
+ "403":
1442
+ $ref: "#/components/responses/Forbidden"
1443
+ "404":
1444
+ $ref: "#/components/responses/NotFound"
1445
+ "409":
1446
+ $ref: "#/components/responses/EndpointRotationConflict"
1447
+ /v1/projects/{project_id}/environments/{environment_id}/customer-endpoints/{endpoint_id}/{action}:
1448
+ parameters:
1449
+ - $ref: "#/components/parameters/ProjectId"
1450
+ - $ref: "#/components/parameters/EnvironmentId"
1451
+ - $ref: "#/components/parameters/CustomerEndpointId"
1452
+ - name: action
1453
+ in: path
1454
+ required: true
1455
+ schema:
1456
+ type: string
1457
+ enum: [pause, resume, disable]
1458
+ post:
1459
+ operationId: transitionCustomerEndpoint
1460
+ summary: Pause, resume, or terminally disable an endpoint
1461
+ tags:
1462
+ - Customer endpoints
1463
+ security:
1464
+ - clerkSession: []
1465
+ - bearerCredential: []
1466
+ - bearerGrant: []
1467
+ x-required-scopes:
1468
+ - messages:write
1469
+ x-repeat-semantics:
1470
+ same_target: idempotent
1471
+ secret_returned: false
1472
+ responses:
1473
+ "200":
1474
+ description: Updated safe endpoint metadata.
1475
+ content:
1476
+ application/json:
1477
+ schema:
1478
+ $ref: "#/components/schemas/CustomerEndpoint"
1479
+ "400":
1480
+ $ref: "#/components/responses/BadRequest"
1481
+ "401":
1482
+ $ref: "#/components/responses/Unauthorized"
1483
+ "403":
1484
+ $ref: "#/components/responses/Forbidden"
1485
+ "404":
1486
+ $ref: "#/components/responses/NotFound"
1487
+ /v1/projects/{project_id}/environments/{environment_id}/customer-endpoints/{endpoint_id}/attempts:
1488
+ parameters:
1489
+ - $ref: "#/components/parameters/ProjectId"
1490
+ - $ref: "#/components/parameters/EnvironmentId"
1491
+ - $ref: "#/components/parameters/CustomerEndpointId"
1492
+ get:
1493
+ operationId: listCustomerEndpointAttempts
1494
+ summary: Inspect protected content-free delivery diagnostics
1495
+ tags:
1496
+ - Customer endpoints
1497
+ security:
1498
+ - clerkSession: []
1499
+ - bearerCredential: []
1500
+ - bearerGrant: []
1501
+ x-required-scopes:
1502
+ - messages:read
1503
+ responses:
1504
+ "200":
1505
+ description: Safe status, timing, and failure categories only.
1506
+ content:
1507
+ application/json:
1508
+ schema:
1509
+ $ref: "#/components/schemas/CustomerEndpointAttemptCollection"
1510
+ examples:
1511
+ attempts:
1512
+ externalValue: ../fixtures/core-v1/success/customer-endpoint-attempts.json
1513
+ "401":
1514
+ $ref: "#/components/responses/Unauthorized"
1515
+ "403":
1516
+ $ref: "#/components/responses/Forbidden"
1517
+ "404":
1518
+ $ref: "#/components/responses/NotFound"
1519
+ /v1/capabilities:
1520
+ get:
1521
+ operationId: getCapabilities
1522
+ summary: Inspect provider-neutral capabilities
1523
+ tags:
1524
+ - Capabilities
1525
+ security:
1526
+ - bearerCredential: []
1527
+ x-required-scopes:
1528
+ - capabilities:read
1529
+ responses:
1530
+ "200":
1531
+ description: Current stable capability vocabulary and active degradation.
1532
+ headers:
1533
+ WhooshBang-Diagnostic-Id:
1534
+ $ref: "#/components/headers/DiagnosticId"
1535
+ content:
1536
+ application/json:
1537
+ schema:
1538
+ $ref: "#/components/schemas/ProviderCapabilitiesCollection"
1539
+ examples:
1540
+ providers:
1541
+ externalValue: ../fixtures/interaction-machine-v1/capabilities/providers.json
1542
+ "401":
1543
+ $ref: "#/components/responses/Unauthorized"
1544
+ "403":
1545
+ $ref: "#/components/responses/Forbidden"
1546
+ "429":
1547
+ $ref: "#/components/responses/RateLimited"
1548
+ /v1/projects/{project_id}/environments/{environment_id}/subscription-links:
1549
+ parameters:
1550
+ - $ref: "#/components/parameters/ProjectId"
1551
+ - $ref: "#/components/parameters/EnvironmentId"
1552
+ post:
1553
+ operationId: createSubscriptionLinkInEnvironment
1554
+ summary: Create a subscription link in a named project environment
1555
+ description: |
1556
+ The environment-scoped form of `createSubscriptionLink`, for a caller
1557
+ whose authority selects an account rather than a project. Behavior,
1558
+ request, and response are identical; the path names the scope the
1559
+ credential form takes from its bearer, and the service checks it
1560
+ against the granting person's membership before acting.
1561
+ tags:
1562
+ - Subscription links
1563
+ security:
1564
+ - bearerGrant: []
1565
+ x-required-scopes:
1566
+ - subscriptions:write
1567
+ x-idempotency:
1568
+ required: true
1569
+ retention_seconds: 604800
1570
+ scope:
1571
+ - authenticated_account
1572
+ - operation_id
1573
+ - key
1574
+ equivalence: validated_request
1575
+ replay_retention_extends: false
1576
+ parameters:
1577
+ - $ref: "#/components/parameters/IdempotencyKey"
1578
+ requestBody:
1579
+ required: true
1580
+ content:
1581
+ application/json:
1582
+ schema:
1583
+ $ref: "#/components/schemas/CreateSubscriptionLinkRequest"
1584
+ responses:
1585
+ "201":
1586
+ description: The link was created in the named environment.
1587
+ headers:
1588
+ WhooshBang-Diagnostic-Id:
1589
+ $ref: "#/components/headers/DiagnosticId"
1590
+ content:
1591
+ application/json:
1592
+ schema:
1593
+ $ref: "#/components/schemas/SubscriptionLink"
1594
+ examples:
1595
+ pending:
1596
+ externalValue: ../fixtures/core-v1/success/subscription-link-pending.json
1597
+ "400":
1598
+ $ref: "#/components/responses/BadRequest"
1599
+ "401":
1600
+ $ref: "#/components/responses/Unauthorized"
1601
+ "403":
1602
+ $ref: "#/components/responses/Forbidden"
1603
+ "404":
1604
+ $ref: "#/components/responses/NotFound"
1605
+ "409":
1606
+ $ref: "#/components/responses/Conflict"
1607
+ "429":
1608
+ $ref: "#/components/responses/RateLimited"
1609
+ /v1/projects/{project_id}/environments/{environment_id}/subscription-links/{subscription_link_id}:
1610
+ parameters:
1611
+ - $ref: "#/components/parameters/ProjectId"
1612
+ - $ref: "#/components/parameters/EnvironmentId"
1613
+ - $ref: "#/components/parameters/SubscriptionLinkId"
1614
+ get:
1615
+ operationId: getSubscriptionLinkInEnvironment
1616
+ summary: Inspect a subscription link in a named project environment
1617
+ description: |
1618
+ The environment-scoped form of `getSubscriptionLink`. A link outside the
1619
+ named environment is absent, exactly as it is for a credential.
1620
+ tags:
1621
+ - Subscription links
1622
+ security:
1623
+ - bearerGrant: []
1624
+ x-required-scopes:
1625
+ - subscriptions:read
1626
+ responses:
1627
+ "200":
1628
+ description: Current link state and, once completed, its safe binding summary.
1629
+ headers:
1630
+ WhooshBang-Diagnostic-Id:
1631
+ $ref: "#/components/headers/DiagnosticId"
1632
+ content:
1633
+ application/json:
1634
+ schema:
1635
+ $ref: "#/components/schemas/SubscriptionLink"
1636
+ examples:
1637
+ activated:
1638
+ externalValue: ../fixtures/core-v1/success/subscription-link-activated.json
1639
+ "401":
1640
+ $ref: "#/components/responses/Unauthorized"
1641
+ "403":
1642
+ $ref: "#/components/responses/Forbidden"
1643
+ "404":
1644
+ $ref: "#/components/responses/NotFound"
1645
+ "429":
1646
+ $ref: "#/components/responses/RateLimited"
1647
+ /v1/projects/{project_id}/environments/{environment_id}/messages:
1648
+ parameters:
1649
+ - $ref: "#/components/parameters/ProjectId"
1650
+ - $ref: "#/components/parameters/EnvironmentId"
1651
+ post:
1652
+ operationId: createMessageInEnvironment
1653
+ summary: Create an asynchronous message in a named project environment
1654
+ description: |
1655
+ The environment-scoped form of `createMessage`. The path names the
1656
+ account, project, and environment the credential form takes from its
1657
+ bearer; test and live remain a property of the named environment and are
1658
+ never selected by the request body.
1659
+ tags:
1660
+ - Messages
1661
+ security:
1662
+ - bearerGrant: []
1663
+ x-required-scopes:
1664
+ - messages:write
1665
+ x-idempotency:
1666
+ required: true
1667
+ retention_seconds: 604800
1668
+ scope:
1669
+ - authenticated_account
1670
+ - operation_id
1671
+ - key
1672
+ equivalence: validated_request
1673
+ replay_retention_extends: false
1674
+ parameters:
1675
+ - $ref: "#/components/parameters/IdempotencyKey"
1676
+ requestBody:
1677
+ required: true
1678
+ content:
1679
+ application/json:
1680
+ schema:
1681
+ $ref: "#/components/schemas/CreateMessageRequest"
1682
+ responses:
1683
+ "202":
1684
+ description: The message was accepted in the named environment.
1685
+ headers:
1686
+ WhooshBang-Diagnostic-Id:
1687
+ $ref: "#/components/headers/DiagnosticId"
1688
+ content:
1689
+ application/json:
1690
+ schema:
1691
+ $ref: "#/components/schemas/Message"
1692
+ examples:
1693
+ accepted:
1694
+ externalValue: ../fixtures/core-v1/success/message-accepted.json
1695
+ "400":
1696
+ $ref: "#/components/responses/BadRequest"
1697
+ "401":
1698
+ $ref: "#/components/responses/Unauthorized"
1699
+ "403":
1700
+ $ref: "#/components/responses/Forbidden"
1701
+ "404":
1702
+ $ref: "#/components/responses/NotFound"
1703
+ "409":
1704
+ $ref: "#/components/responses/Conflict"
1705
+ "422":
1706
+ $ref: "#/components/responses/Unprocessable"
1707
+ "429":
1708
+ $ref: "#/components/responses/RateLimited"
1709
+ /v1/projects/{project_id}/environments/{environment_id}/messages/{message_id}:
1710
+ parameters:
1711
+ - $ref: "#/components/parameters/ProjectId"
1712
+ - $ref: "#/components/parameters/EnvironmentId"
1713
+ - $ref: "#/components/parameters/MessageId"
1714
+ get:
1715
+ operationId: getMessageInEnvironment
1716
+ summary: Inspect a message in a named project environment
1717
+ description: |
1718
+ The environment-scoped form of `getMessage`, including the same bounded
1719
+ long poll. Inspection acknowledges, consumes, retries, and replays
1720
+ nothing.
1721
+ parameters:
1722
+ - $ref: "#/components/parameters/ResponseInspectionWait"
1723
+ tags:
1724
+ - Messages
1725
+ security:
1726
+ - bearerGrant: []
1727
+ x-required-scopes:
1728
+ - messages:read
1729
+ responses:
1730
+ "200":
1731
+ description: Canonical message state at the moment the read completed.
1732
+ headers:
1733
+ WhooshBang-Diagnostic-Id:
1734
+ $ref: "#/components/headers/DiagnosticId"
1735
+ content:
1736
+ application/json:
1737
+ schema:
1738
+ $ref: "#/components/schemas/Message"
1739
+ examples:
1740
+ accepted:
1741
+ externalValue: ../fixtures/core-v1/success/message-provider-accepted.json
1742
+ "400":
1743
+ $ref: "#/components/responses/BadRequest"
1744
+ "401":
1745
+ $ref: "#/components/responses/Unauthorized"
1746
+ "403":
1747
+ $ref: "#/components/responses/Forbidden"
1748
+ "404":
1749
+ $ref: "#/components/responses/NotFound"
1750
+ "429":
1751
+ $ref: "#/components/responses/RateLimited"
1752
+ /v1/projects/{project_id}/environments/{environment_id}/interactions/{interaction_id}:
1753
+ parameters:
1754
+ - $ref: "#/components/parameters/ProjectId"
1755
+ - $ref: "#/components/parameters/EnvironmentId"
1756
+ - $ref: "#/components/parameters/InteractionId"
1757
+ get:
1758
+ operationId: getInteractionInEnvironment
1759
+ summary: Inspect an interaction response in a named project environment
1760
+ description: |
1761
+ The environment-scoped form of `getInteraction`, including the same
1762
+ bounded long poll and the same retained-answer semantics.
1763
+ parameters:
1764
+ - $ref: "#/components/parameters/ResponseInspectionWait"
1765
+ tags:
1766
+ - Messages
1767
+ security:
1768
+ - bearerGrant: []
1769
+ x-required-scopes:
1770
+ - messages:read
1771
+ responses:
1772
+ "200":
1773
+ description: Canonical interaction state at the moment the read completed.
1774
+ headers:
1775
+ WhooshBang-Diagnostic-Id:
1776
+ $ref: "#/components/headers/DiagnosticId"
1777
+ content:
1778
+ application/json:
1779
+ schema:
1780
+ $ref: "#/components/schemas/InteractionSummary"
1781
+ examples:
1782
+ answered:
1783
+ externalValue: ../fixtures/interaction-machine-v1/success/interaction-answered-confirm.json
1784
+ "400":
1785
+ $ref: "#/components/responses/BadRequest"
1786
+ "401":
1787
+ $ref: "#/components/responses/Unauthorized"
1788
+ "403":
1789
+ $ref: "#/components/responses/Forbidden"
1790
+ "404":
1791
+ $ref: "#/components/responses/NotFound"
1792
+ "429":
1793
+ $ref: "#/components/responses/RateLimited"
1794
+ /v1/projects/{project_id}/environments/{environment_id}/machine-clients:
1795
+ parameters:
1796
+ - $ref: "#/components/parameters/ProjectId"
1797
+ - $ref: "#/components/parameters/EnvironmentId"
1798
+ post:
1799
+ operationId: createMachineClientInEnvironment
1800
+ summary: Create a destination-bound machine client in a named project environment
1801
+ description: |
1802
+ The environment-scoped form of `createMachineClient`. Scope remains the
1803
+ exact bound destination; the path only names where the client is created.
1804
+ tags:
1805
+ - Machine clients
1806
+ security:
1807
+ - bearerGrant: []
1808
+ x-required-scopes:
1809
+ - machine-clients:write
1810
+ x-idempotency:
1811
+ required: true
1812
+ retention_seconds: 604800
1813
+ scope:
1814
+ - authenticated_account
1815
+ - operation_id
1816
+ - key
1817
+ equivalence: validated_request
1818
+ replay_retention_extends: false
1819
+ parameters:
1820
+ - $ref: "#/components/parameters/IdempotencyKey"
1821
+ requestBody:
1822
+ required: true
1823
+ content:
1824
+ application/json:
1825
+ schema:
1826
+ $ref: "#/components/schemas/CreateMachineClientRequest"
1827
+ responses:
1828
+ "201":
1829
+ description: The machine client was created in the named environment.
1830
+ headers:
1831
+ WhooshBang-Diagnostic-Id:
1832
+ $ref: "#/components/headers/DiagnosticId"
1833
+ content:
1834
+ application/json:
1835
+ schema:
1836
+ $ref: "#/components/schemas/MachineClient"
1837
+ examples:
1838
+ provisioning:
1839
+ externalValue: ../fixtures/interaction-machine-v1/success/machine-client-provisioning.json
1840
+ "400":
1841
+ $ref: "#/components/responses/BadRequest"
1842
+ "401":
1843
+ $ref: "#/components/responses/Unauthorized"
1844
+ "403":
1845
+ $ref: "#/components/responses/Forbidden"
1846
+ "404":
1847
+ $ref: "#/components/responses/NotFound"
1848
+ "409":
1849
+ $ref: "#/components/responses/Conflict"
1850
+ "422":
1851
+ $ref: "#/components/responses/Unprocessable"
1852
+ "429":
1853
+ $ref: "#/components/responses/RateLimited"
1854
+ /v1/projects/{project_id}/environments/{environment_id}/capabilities:
1855
+ parameters:
1856
+ - $ref: "#/components/parameters/ProjectId"
1857
+ - $ref: "#/components/parameters/EnvironmentId"
1858
+ get:
1859
+ operationId: getCapabilitiesInEnvironment
1860
+ summary: Inspect provider-neutral capabilities for a named project environment
1861
+ description: |
1862
+ The environment-scoped form of `getCapabilities`. The vocabulary is
1863
+ provider-neutral and identical; the path names the environment whose
1864
+ active degradation is reported.
1865
+ tags:
1866
+ - Capabilities
1867
+ security:
1868
+ - bearerGrant: []
1869
+ x-required-scopes:
1870
+ - capabilities:read
1871
+ responses:
1872
+ "200":
1873
+ description: Current stable capability vocabulary and active degradation.
1874
+ headers:
1875
+ WhooshBang-Diagnostic-Id:
1876
+ $ref: "#/components/headers/DiagnosticId"
1877
+ content:
1878
+ application/json:
1879
+ schema:
1880
+ $ref: "#/components/schemas/ProviderCapabilitiesCollection"
1881
+ examples:
1882
+ providers:
1883
+ externalValue: ../fixtures/interaction-machine-v1/capabilities/providers.json
1884
+ "401":
1885
+ $ref: "#/components/responses/Unauthorized"
1886
+ "403":
1887
+ $ref: "#/components/responses/Forbidden"
1888
+ "404":
1889
+ $ref: "#/components/responses/NotFound"
1890
+ "429":
1891
+ $ref: "#/components/responses/RateLimited"
1892
+ components:
1893
+ securitySchemes:
1894
+ clerkSession:
1895
+ type: http
1896
+ scheme: bearer
1897
+ bearerFormat: Clerk session JWT
1898
+ description: |
1899
+ A verified human session whose active Clerk organization selects exactly
1900
+ one WhooshBang account. Every administration operation rechecks the
1901
+ projected account membership; session identity never selects a project
1902
+ or environment from request data.
1903
+ bearerGrant:
1904
+ type: http
1905
+ scheme: bearer
1906
+ bearerFormat: OAuth 2.0 access token
1907
+ description: |
1908
+ An access token issued by the WhooshBang authorization server for one
1909
+ consenting account member. It selects exactly one account and carries
1910
+ the scopes that member consented to, and never a project: an operation
1911
+ names its project and environment in the path, and the service checks
1912
+ both against the granting person's membership before acting. It can
1913
+ hold account-level scopes, which no credential can.
1914
+ bearerCredential:
1915
+ type: http
1916
+ scheme: bearer
1917
+ bearerFormat: wb_pc1.pcred_<16-byte-base64url>.<32-byte-base64url-secret>
1918
+ description: |
1919
+ Selects exactly one account, project, and `test` or `live` environment.
1920
+ Credentials cannot be read after creation. Except for explicitly
1921
+ synthetic creation/rotation reveal fixtures, complete bearer values
1922
+ must never appear in fixtures, errors, logs, metrics, or inspection
1923
+ surfaces.
1924
+ machineCredential:
1925
+ type: http
1926
+ scheme: bearer
1927
+ bearerFormat: wb_mc1.mcred_<16-byte-base64url>.<32-byte-base64url-secret>
1928
+ description: |
1929
+ A locally generated runtime credential bound server-side to exactly one
1930
+ project/environment, machine client, notifier, subscriber, binding, and
1931
+ event stream. Project credentials cannot use machine-only endpoints.
1932
+ Revoked credentials fail before resource lookup.
1933
+ parameters:
1934
+ IdempotencyKey:
1935
+ name: Idempotency-Key
1936
+ in: header
1937
+ required: true
1938
+ description: |
1939
+ Visible ASCII key retained for seven days from first acceptance.
1940
+ Equivalent replay returns the original status and logical resource;
1941
+ materially different validated input returns `idempotency_conflict`.
1942
+ schema:
1943
+ $ref: "#/components/schemas/IdempotencyKey"
1944
+ SubscriptionLinkId:
1945
+ name: subscription_link_id
1946
+ in: path
1947
+ required: true
1948
+ description: Opaque subscription-link identity; never authorization.
1949
+ schema:
1950
+ $ref: "#/components/schemas/OpaqueIdentifier"
1951
+ ProjectId:
1952
+ name: project_id
1953
+ in: path
1954
+ required: true
1955
+ description: Opaque project identity; never authorization.
1956
+ schema:
1957
+ $ref: "#/components/schemas/OpaqueIdentifier"
1958
+ EnvironmentId:
1959
+ name: environment_id
1960
+ in: path
1961
+ required: true
1962
+ description: Opaque project-environment identity; never authorization.
1963
+ schema:
1964
+ $ref: "#/components/schemas/OpaqueIdentifier"
1965
+ ApiCredentialId:
1966
+ name: credential_id
1967
+ in: path
1968
+ required: true
1969
+ description: Canonical opaque project credential identity; never a readable secret.
1970
+ schema:
1971
+ $ref: "#/components/schemas/ApiCredentialId"
1972
+ ApiCredentialAfterCursor:
1973
+ name: after
1974
+ in: query
1975
+ required: false
1976
+ description: Opaque cursor returned by the previous credential page.
1977
+ schema:
1978
+ type: string
1979
+ minLength: 1
1980
+ maxLength: 256
1981
+ pattern: "^[A-Za-z0-9_-]+$"
1982
+ ApiCredentialPageLimit:
1983
+ name: limit
1984
+ in: query
1985
+ required: false
1986
+ description: Maximum credential metadata records returned in one page.
1987
+ schema:
1988
+ type: integer
1989
+ minimum: 1
1990
+ maximum: 100
1991
+ default: 50
1992
+ ProjectAfterCursor:
1993
+ name: after
1994
+ in: query
1995
+ required: false
1996
+ description: Opaque cursor returned by the previous project page.
1997
+ schema:
1998
+ type: string
1999
+ minLength: 1
2000
+ maxLength: 256
2001
+ pattern: "^[A-Za-z0-9_-]+$"
2002
+ ProjectPageLimit:
2003
+ name: limit
2004
+ in: query
2005
+ required: false
2006
+ description: Maximum projects returned in one page.
2007
+ schema:
2008
+ type: integer
2009
+ minimum: 1
2010
+ maximum: 100
2011
+ default: 50
2012
+ MessageId:
2013
+ name: message_id
2014
+ in: path
2015
+ required: true
2016
+ description: Opaque logical message identity; never authorization.
2017
+ schema:
2018
+ $ref: "#/components/schemas/OpaqueIdentifier"
2019
+ InteractionId:
2020
+ name: interaction_id
2021
+ in: path
2022
+ required: true
2023
+ description: Opaque interaction identity; never authorization.
2024
+ schema:
2025
+ $ref: "#/components/schemas/OpaqueIdentifier"
2026
+ MachineClientId:
2027
+ name: machine_client_id
2028
+ in: path
2029
+ required: true
2030
+ description: Opaque machine-client identity; never authorization.
2031
+ schema:
2032
+ $ref: "#/components/schemas/OpaqueIdentifier"
2033
+ MachineCredentialId:
2034
+ name: credential_id
2035
+ in: path
2036
+ required: true
2037
+ description: Canonical opaque credential identifier; never a readable secret.
2038
+ schema:
2039
+ $ref: "#/components/schemas/MachineCredentialId"
2040
+ MachineEventId:
2041
+ name: event_id
2042
+ in: path
2043
+ required: true
2044
+ description: Opaque event identity constrained to the authenticated machine stream.
2045
+ schema:
2046
+ $ref: "#/components/schemas/OpaqueIdentifier"
2047
+ CustomerEndpointId:
2048
+ name: endpoint_id
2049
+ in: path
2050
+ required: true
2051
+ description: Opaque endpoint identity; never authorization and never a URL.
2052
+ schema:
2053
+ $ref: "#/components/schemas/OpaqueIdentifier"
2054
+ MachineAfterCursor:
2055
+ name: after
2056
+ in: query
2057
+ required: false
2058
+ description: |
2059
+ Exact atomically committed cursor returned by the previous successful
2060
+ poll or acknowledgement. Omit only for the first poll. A foreign,
2061
+ unknown, or known-but-uncommitted cursor fails closed and cannot rewind
2062
+ the stream.
2063
+ schema:
2064
+ $ref: "#/components/schemas/MachineCursor"
2065
+ MachinePollWait:
2066
+ name: wait
2067
+ in: query
2068
+ required: false
2069
+ description: Bounded server hold time in seconds.
2070
+ schema:
2071
+ type: integer
2072
+ minimum: 0
2073
+ maximum: 30
2074
+ default: 30
2075
+ ResponseInspectionWait:
2076
+ name: wait
2077
+ in: query
2078
+ required: false
2079
+ description: |
2080
+ Bounded server hold time in whole seconds. Omission defaults to 30;
2081
+ zero requests an immediate read. A wait that expires returns the
2082
+ current resource successfully rather than a timeout problem.
2083
+ schema:
2084
+ type: integer
2085
+ minimum: 0
2086
+ maximum: 30
2087
+ default: 30
2088
+ MachinePollLimit:
2089
+ name: limit
2090
+ in: query
2091
+ required: false
2092
+ description: Maximum stable-ordered events returned.
2093
+ schema:
2094
+ type: integer
2095
+ minimum: 1
2096
+ maximum: 50
2097
+ default: 25
2098
+ headers:
2099
+ DiagnosticId:
2100
+ description: Safe public correlation identifier for protected diagnostics.
2101
+ schema:
2102
+ $ref: "#/components/schemas/DiagnosticId"
2103
+ schemas:
2104
+ OpaqueIdentifier:
2105
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/OpaqueIdentifier
2106
+ DiagnosticId:
2107
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/DiagnosticId
2108
+ IdempotencyKey:
2109
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/IdempotencyKey
2110
+ AccountProjection:
2111
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/AccountProjection
2112
+ CreateProjectRequest:
2113
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/CreateProjectRequest
2114
+ DefaultNotifierSummary:
2115
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/DefaultNotifierSummary
2116
+ ProjectEnvironment:
2117
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/ProjectEnvironment
2118
+ Project:
2119
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/Project
2120
+ ProjectCollection:
2121
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/ProjectCollection
2122
+ CreateApiCredentialRequest:
2123
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/CreateApiCredentialRequest
2124
+ RotateApiCredentialRequest:
2125
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/RotateApiCredentialRequest
2126
+ ApiCredentialId:
2127
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/ApiCredentialId
2128
+ ApiCredential:
2129
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/ApiCredential
2130
+ ApiCredentialCollection:
2131
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/ApiCredentialCollection
2132
+ ApiCredentialSecretReveal:
2133
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/ApiCredentialSecretReveal
2134
+ ApiCredentialRotation:
2135
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/ApiCredentialRotation
2136
+ CreateCustomerEndpointRequest:
2137
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/CreateCustomerEndpointRequest
2138
+ RotateCustomerEndpointRequest:
2139
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/RotateCustomerEndpointRequest
2140
+ CustomerEndpoint:
2141
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/CustomerEndpoint
2142
+ CustomerEndpointCollection:
2143
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/CustomerEndpointCollection
2144
+ CustomerEndpointMutationResult:
2145
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/CustomerEndpointMutationResult
2146
+ CustomerEndpointAttemptCollection:
2147
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/CustomerEndpointAttemptCollection
2148
+ CustomerEndpointVerificationChallenge:
2149
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/CustomerEndpointVerificationChallenge
2150
+ BindingSummary:
2151
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/BindingSummary
2152
+ CreateSubscriptionLinkRequest:
2153
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/CreateSubscriptionLinkRequest
2154
+ SubscriptionLink:
2155
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/SubscriptionLink
2156
+ CreateMessageRequest:
2157
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/CreateMessageRequest
2158
+ DeliveryAttemptSummary:
2159
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/DeliveryAttemptSummary
2160
+ Message:
2161
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/Message
2162
+ Problem:
2163
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/Problem
2164
+ InteractionRequest:
2165
+ $ref: ../schemas/interaction-v1.schema.json#/$defs/InteractionRequest
2166
+ InteractionSummary:
2167
+ $ref: ../schemas/interaction-v1.schema.json#/$defs/InteractionSummary
2168
+ InteractionEvent:
2169
+ $ref: ../schemas/interaction-v1.schema.json#/$defs/InteractionEvent
2170
+ CreateMachineClientRequest:
2171
+ $ref: ../schemas/machine-v1.schema.json#/$defs/CreateMachineClientRequest
2172
+ MachineClient:
2173
+ $ref: ../schemas/machine-v1.schema.json#/$defs/MachineClient
2174
+ MachineCredentialId:
2175
+ $ref: ../schemas/machine-v1.schema.json#/$defs/MachineCredentialId
2176
+ RegisterMachineCredentialRequest:
2177
+ $ref: ../schemas/machine-v1.schema.json#/$defs/RegisterMachineCredentialRequest
2178
+ MachineCredential:
2179
+ $ref: ../schemas/machine-v1.schema.json#/$defs/MachineCredential
2180
+ MachineCursor:
2181
+ $ref: ../schemas/machine-v1.schema.json#/$defs/MachineCursor
2182
+ MachineEventPollResponse:
2183
+ $ref: ../schemas/machine-v1.schema.json#/$defs/MachineEventPollResponse
2184
+ MachineEventAckRequest:
2185
+ $ref: ../schemas/machine-v1.schema.json#/$defs/MachineEventAckRequest
2186
+ MachineEventAckResponse:
2187
+ $ref: ../schemas/machine-v1.schema.json#/$defs/MachineEventAckResponse
2188
+ ProviderCapabilities:
2189
+ $ref: ../schemas/provider-capabilities-v1.schema.json
2190
+ ProviderCapabilitiesCollection:
2191
+ $ref: ../schemas/whooshbang-v1.schema.json#/$defs/ProviderCapabilitiesCollection
2192
+ responses:
2193
+ BadRequest:
2194
+ description: The request or required idempotency key is invalid.
2195
+ headers:
2196
+ WhooshBang-Diagnostic-Id:
2197
+ $ref: "#/components/headers/DiagnosticId"
2198
+ content:
2199
+ application/problem+json:
2200
+ schema:
2201
+ $ref: "#/components/schemas/Problem"
2202
+ examples:
2203
+ requestInvalid:
2204
+ externalValue: ../fixtures/core-v1/problems/request-invalid.json
2205
+ idempotencyKeyRequired:
2206
+ externalValue: ../fixtures/core-v1/problems/idempotency-key-required.json
2207
+ Unauthorized:
2208
+ description: A bearer credential is absent, malformed, invalid, or revoked.
2209
+ headers:
2210
+ WhooshBang-Diagnostic-Id:
2211
+ $ref: "#/components/headers/DiagnosticId"
2212
+ content:
2213
+ application/problem+json:
2214
+ schema:
2215
+ $ref: "#/components/schemas/Problem"
2216
+ examples:
2217
+ authenticationRequired:
2218
+ externalValue: ../fixtures/core-v1/problems/authentication-required.json
2219
+ credentialInvalid:
2220
+ externalValue: ../fixtures/core-v1/problems/auth-invalid.json
2221
+ Forbidden:
2222
+ description: The credential lacks scope or cannot address the requested environment.
2223
+ headers:
2224
+ WhooshBang-Diagnostic-Id:
2225
+ $ref: "#/components/headers/DiagnosticId"
2226
+ content:
2227
+ application/problem+json:
2228
+ schema:
2229
+ $ref: "#/components/schemas/Problem"
2230
+ examples:
2231
+ scopeForbidden:
2232
+ externalValue: ../fixtures/core-v1/problems/scope-forbidden.json
2233
+ environmentMismatch:
2234
+ externalValue: ../fixtures/core-v1/problems/environment-mismatch.json
2235
+ NotFound:
2236
+ description: |
2237
+ The resource is absent or outside the authenticated project/environment.
2238
+ The response never confirms cross-tenant existence.
2239
+ headers:
2240
+ WhooshBang-Diagnostic-Id:
2241
+ $ref: "#/components/headers/DiagnosticId"
2242
+ content:
2243
+ application/problem+json:
2244
+ schema:
2245
+ $ref: "#/components/schemas/Problem"
2246
+ examples:
2247
+ resourceNotFound:
2248
+ externalValue: ../fixtures/core-v1/problems/resource-not-found.json
2249
+ resourceExpired:
2250
+ externalValue: ../fixtures/core-v1/problems/resource-expired.json
2251
+ Conflict:
2252
+ description: |
2253
+ An idempotency key, project slug, credential identity, existing
2254
+ acknowledgement, or resource state conflicts with the authorized
2255
+ account or request.
2256
+ headers:
2257
+ WhooshBang-Diagnostic-Id:
2258
+ $ref: "#/components/headers/DiagnosticId"
2259
+ content:
2260
+ application/problem+json:
2261
+ schema:
2262
+ $ref: "#/components/schemas/Problem"
2263
+ examples:
2264
+ idempotencyConflict:
2265
+ externalValue: ../fixtures/core-v1/problems/idempotency-conflict.json
2266
+ projectSlugConflict:
2267
+ externalValue: ../fixtures/core-v1/problems/project-slug-conflict.json
2268
+ replayUnavailable:
2269
+ externalValue: ../fixtures/core-v1/problems/replay-unavailable-rollout.json
2270
+ Unprocessable:
2271
+ description: The destination is valid in shape but has no authorized channel binding.
2272
+ headers:
2273
+ WhooshBang-Diagnostic-Id:
2274
+ $ref: "#/components/headers/DiagnosticId"
2275
+ content:
2276
+ application/problem+json:
2277
+ schema:
2278
+ $ref: "#/components/schemas/Problem"
2279
+ examples:
2280
+ subscriberUnbound:
2281
+ externalValue: ../fixtures/core-v1/problems/subscriber-unbound.json
2282
+ ProviderTerminal:
2283
+ description: The endpoint challenge failed in a way that requires developer action.
2284
+ headers:
2285
+ WhooshBang-Diagnostic-Id:
2286
+ $ref: "#/components/headers/DiagnosticId"
2287
+ content:
2288
+ application/problem+json:
2289
+ schema:
2290
+ $ref: "#/components/schemas/Problem"
2291
+ examples:
2292
+ providerTerminal:
2293
+ externalValue: ../fixtures/core-v1/problems/provider-terminal.json
2294
+ ProviderRetryable:
2295
+ description: The endpoint challenge failed transiently and can be retried safely.
2296
+ headers:
2297
+ WhooshBang-Diagnostic-Id:
2298
+ $ref: "#/components/headers/DiagnosticId"
2299
+ content:
2300
+ application/problem+json:
2301
+ schema:
2302
+ $ref: "#/components/schemas/Problem"
2303
+ examples:
2304
+ providerRetryable:
2305
+ externalValue: ../fixtures/core-v1/problems/provider-retryable.json
2306
+ EndpointRotationConflict:
2307
+ description: A previous signing-secret overlap must finish before another rotation.
2308
+ headers:
2309
+ WhooshBang-Diagnostic-Id:
2310
+ $ref: "#/components/headers/DiagnosticId"
2311
+ content:
2312
+ application/problem+json:
2313
+ schema:
2314
+ $ref: "#/components/schemas/Problem"
2315
+ examples:
2316
+ endpointRotationConflict:
2317
+ externalValue: ../fixtures/core-v1/problems/endpoint-rotation-conflict.json
2318
+ RateLimited:
2319
+ description: A project or operation rate limit was exceeded.
2320
+ headers:
2321
+ WhooshBang-Diagnostic-Id:
2322
+ $ref: "#/components/headers/DiagnosticId"
2323
+ Retry-After:
2324
+ description: Safe delay in seconds when known.
2325
+ schema:
2326
+ type: integer
2327
+ minimum: 1
2328
+ content:
2329
+ application/problem+json:
2330
+ schema:
2331
+ $ref: "#/components/schemas/Problem"
2332
+ examples:
2333
+ rateLimited:
2334
+ externalValue: ../fixtures/core-v1/problems/rate-limited.json