@whooshbang/contracts 1.0.0-rc.21 → 1.0.0-rc.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/README.md +9 -3
- package/contract-manifest.json +43 -41
- package/dist/generated/artifact-index.d.ts +35 -35
- package/dist/generated/artifact-index.js +43 -41
- package/dist/generated/artifact-index.js.map +1 -1
- package/dist/generated/validators-standalone.d.ts +340 -288
- package/dist/generated/validators-standalone.js +5560 -2925
- package/dist/generated/validators-standalone.js.map +1 -1
- package/dist/generated/validators.d.ts +12 -8
- package/dist/generated/validators.js +22 -18
- package/dist/generated/validators.js.map +1 -1
- package/dist/generated/whooshbang-event-v1.d.ts +1 -1
- package/dist/generated/whooshbang-v1.d.ts +211 -121
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/fixtures/core-v1/fixture-index.json +50 -34
- package/fixtures/core-v1/problems/credential-organization-mismatch.json +9 -0
- package/fixtures/core-v1/problems/live-simulator-refused.json +16 -0
- package/fixtures/core-v1/problems/project-slug-conflict.json +1 -1
- package/fixtures/core-v1/requests/create-organization-credential.json +4 -0
- package/fixtures/core-v1/requests/update-project.json +3 -0
- package/fixtures/core-v1/scenarios/api-credential-invalid-indistinguishable.json +1 -1
- package/fixtures/core-v1/scenarios/api-credential-one-time-reveal.json +1 -1
- package/fixtures/core-v1/scenarios/api-credential-revocation-replay.json +1 -1
- package/fixtures/core-v1/scenarios/api-credential-rotation-overlap.json +1 -1
- package/fixtures/core-v1/scenarios/cancellation-too-late.json +1 -1
- package/fixtures/core-v1/scenarios/cross-organization-project.json +14 -0
- package/fixtures/core-v1/scenarios/cross-project-resource.json +1 -1
- package/fixtures/core-v1/scenarios/environment-mismatch.json +1 -1
- package/fixtures/core-v1/scenarios/idempotency-conflict.json +1 -1
- package/fixtures/core-v1/scenarios/idempotency-equivalent-replay.json +1 -1
- package/fixtures/core-v1/scenarios/malformed-bearer.json +1 -1
- package/fixtures/core-v1/scenarios/metadata-overrun.json +1 -1
- package/fixtures/core-v1/scenarios/missing-scope.json +1 -1
- package/fixtures/core-v1/scenarios/project-create-equivalent-replay.json +2 -2
- package/fixtures/core-v1/scenarios/project-slug-conflict.json +2 -2
- package/fixtures/core-v1/scenarios/provider-outcome-unknown.json +1 -1
- package/fixtures/core-v1/scenarios/subscription-activation-replay.json +1 -1
- package/fixtures/core-v1/scenarios/subscription-authorization-capability-opacity.json +1 -1
- package/fixtures/core-v1/scenarios/subscription-cross-connection-callback-rejected.json +1 -1
- package/fixtures/core-v1/scenarios/subscription-expired-replay.json +1 -1
- package/fixtures/core-v1/scenarios/subscription-selected-connection-replay.json +1 -1
- package/fixtures/core-v1/success/{account-credential-collection.json → organization-credential-collection.json} +3 -3
- package/fixtures/core-v1/success/organization-credential-created.json +12 -0
- package/fixtures/core-v1/success/{account-credential-revoked.json → organization-credential-revoked.json} +3 -3
- package/fixtures/core-v1/success/{account-credential-rotated.json → organization-credential-rotated.json} +7 -7
- package/fixtures/core-v1/success/{account-projection.json → organization-projection.json} +2 -2
- package/fixtures/core-v1/success/project-collection.json +3 -2
- package/fixtures/core-v1/success/project-created.json +3 -2
- package/fixtures/interaction-machine-v1/scenarios/ack-conflict.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/ack-cross-machine.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/ack-out-of-order.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/ack-replay.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/ambiguous-free-text.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/callback-token-opacity.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/credential-registration-conflict.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/credential-registration-replay.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/credential-revocation-replay.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/credential-rotation.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/first-credential-activates.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/interaction-duplicate.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/interaction-expired.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/interaction-mismatch.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/interaction-retired.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/interaction-stale.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/machine-admin-denied.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/machine-bound-message-create.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/machine-cancel-denied.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/machine-crash-before-ack.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/machine-notifier-mismatch.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/machine-other-message-read.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/machine-owned-message-read.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/machine-subscriber-mismatch.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/poll-uncommitted-cursor-rejected.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/project-credential-machine-endpoint-denied.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/quarantine-integrity-rejected.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/quarantine-signature-rejected.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/quarantine-valid.json +1 -1
- package/fixtures/interaction-machine-v1/scenarios/revoked-machine-credential.json +1 -1
- package/fixtures/recipient-experience-v1/requests/create-recipient-group.json +1 -1
- package/fixtures/recipient-experience-v1/requests/create-subscriber-with-groups.json +1 -1
- package/fixtures/recipient-experience-v1/scenarios/membership-broadcast-snapshot.json +1 -1
- package/fixtures/recipient-experience-v1/scenarios/preferred-binding-resolution.json +1 -1
- package/fixtures/recipient-experience-v1/scenarios/recipient-session-security.json +1 -1
- package/fixtures/recipient-experience-v1/scenarios/subscriber-initial-groups-transaction.json +2 -2
- package/fixtures/recipient-experience-v1/success/recipient-group.json +1 -1
- package/fixtures/whooshbang-events-v1/events/agent-binding-degraded.json +1 -1
- package/fixtures/whooshbang-events-v1/events/interaction-expired.json +1 -1
- package/fixtures/whooshbang-events-v1/events/interaction-received.json +1 -1
- package/fixtures/whooshbang-events-v1/events/message-delivered.json +1 -1
- package/fixtures/whooshbang-events-v1/events/message-expired.json +1 -1
- package/fixtures/whooshbang-events-v1/events/message-failed.json +1 -1
- package/fixtures/whooshbang-events-v1/events/message-provider-accepted.json +1 -1
- package/fixtures/whooshbang-events-v1/events/subscription-activated.json +1 -1
- package/fixtures/whooshbang-events-v1/events/subscription-revoked.json +1 -1
- package/fixtures/whooshbang-events-v1/signing/vectors.json +29 -29
- package/openapi/generated/whooshbang-v1.bundle.json +641 -248
- package/openapi/whooshbang-v1.yaml +403 -189
- package/package.json +1 -1
- package/schemas/core-scenario.schema.json +1 -1
- package/schemas/events/agent-binding-degraded-v1.schema.json +1 -1
- package/schemas/events/interaction-expired-v1.schema.json +1 -1
- package/schemas/events/interaction-received-v1.schema.json +1 -1
- package/schemas/events/message-delivered-v1.schema.json +1 -1
- package/schemas/events/message-expired-v1.schema.json +1 -1
- package/schemas/events/message-failed-v1.schema.json +1 -1
- package/schemas/events/message-provider-accepted-v1.schema.json +1 -1
- package/schemas/events/subscription-activated-v1.schema.json +1 -1
- package/schemas/events/subscription-revoked-v1.schema.json +1 -1
- package/schemas/events/whooshbang-event-v1.schema.json +3 -3
- package/schemas/fixture-index.schema.json +1 -1
- package/schemas/interaction-machine-scenario.schema.json +1 -1
- package/schemas/interaction-v1.schema.json +1 -1
- package/schemas/machine-v1.schema.json +1 -1
- package/schemas/provider-capabilities-v1.schema.json +1 -1
- package/schemas/webhooks/webhook-delivery-case-v1.schema.json +1 -1
- package/schemas/webhooks/webhook-signing-vector-v1.schema.json +1 -1
- package/schemas/whooshbang-v1.schema.json +289 -67
- package/fixtures/core-v1/problems/credential-account-mismatch.json +0 -9
- package/fixtures/core-v1/requests/create-account-credential.json +0 -4
- package/fixtures/core-v1/scenarios/cross-account-project.json +0 -14
- package/fixtures/core-v1/success/account-credential-created.json +0 -12
- /package/fixtures/core-v1/requests/{rotate-account-credential.json → rotate-organization-credential.json} +0 -0
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"openapi": "3.1.1",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "WhooshBang API",
|
|
5
|
-
"version": "1.0.0-rc.
|
|
6
|
-
"description": "The V1 contract for human
|
|
5
|
+
"version": "1.0.0-rc.23",
|
|
6
|
+
"description": "The V1 contract for human organization/project administration, project-scoped\nsubscription links, and asynchronous text messages. A Clerk session selects\none organization for administration. A project credential selects one organization,\nproject, and `test` or `live` environment for product operations; request\nbodies cannot override either authenticated scope.\n\nA person's OAuth grant selects one organization and carries scopes, but no\nproject. It names the project and environment it acts in through the URL\npath, on the environment-scoped form of each operation; the service checks\nthat path against the granting person's membership on every call. The flat\nforms remain credential-only and are unchanged.\n\nResource identifiers are opaque and are not authorization. Reads outside the\ncredential scope return the same `404` shape as absent resources. Provider\ncredentials, raw Telegram identity, and protected provider responses are\nnever part of this API.\n",
|
|
7
7
|
"termsOfService": "https://flowxo.com/terms",
|
|
8
8
|
"contact": {
|
|
9
9
|
"name": "WhooshBang Support",
|
|
@@ -21,20 +21,20 @@
|
|
|
21
21
|
"security": [{ "bearerCredential": [] }],
|
|
22
22
|
"tags": [
|
|
23
23
|
{
|
|
24
|
-
"name": "
|
|
25
|
-
"description": "The current Clerk organization projected as a WhooshBang
|
|
24
|
+
"name": "Organization",
|
|
25
|
+
"description": "The current Clerk organization projected as a WhooshBang organization."
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
"name": "Projects",
|
|
29
|
-
"description": "
|
|
29
|
+
"description": "Organization-scoped applications with transactionally bootstrapped test/live environments."
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
"name": "API credentials",
|
|
33
33
|
"description": "Human-administered, environment-scoped bearer credentials with one-time secret reveal."
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
|
-
"name": "
|
|
37
|
-
"description": "Human-administered,
|
|
36
|
+
"name": "Organization credentials",
|
|
37
|
+
"description": "Human-administered, organization-scoped bearer credentials that name their project and environment per call."
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
"name": "Subscription links",
|
|
@@ -82,17 +82,17 @@
|
|
|
82
82
|
}
|
|
83
83
|
],
|
|
84
84
|
"paths": {
|
|
85
|
-
"/v1/
|
|
85
|
+
"/v1/organization": {
|
|
86
86
|
"get": {
|
|
87
|
-
"operationId": "
|
|
88
|
-
"summary": "Read the current
|
|
89
|
-
"description": "Returns the WhooshBang
|
|
90
|
-
"tags": ["
|
|
87
|
+
"operationId": "getOrganization",
|
|
88
|
+
"summary": "Read the current organization projection",
|
|
89
|
+
"description": "Returns the WhooshBang organization selected by the verified Clerk\norganization session and the caller's projected role. Clerk organization\nand user identifiers are never public response fields.\n",
|
|
90
|
+
"tags": ["Organization"],
|
|
91
91
|
"security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
|
|
92
|
-
"x-
|
|
92
|
+
"x-organization-membership": "required",
|
|
93
93
|
"responses": {
|
|
94
94
|
"200": {
|
|
95
|
-
"description": "The current
|
|
95
|
+
"description": "The current organization projection.",
|
|
96
96
|
"headers": {
|
|
97
97
|
"WhooshBang-Diagnostic-Id": {
|
|
98
98
|
"$ref": "#/components/headers/DiagnosticId"
|
|
@@ -100,17 +100,19 @@
|
|
|
100
100
|
},
|
|
101
101
|
"content": {
|
|
102
102
|
"application/json": {
|
|
103
|
-
"schema": {
|
|
103
|
+
"schema": {
|
|
104
|
+
"$ref": "#/components/schemas/OrganizationProjection"
|
|
105
|
+
},
|
|
104
106
|
"examples": {
|
|
105
|
-
"
|
|
107
|
+
"projectedOrganization": {
|
|
106
108
|
"value": {
|
|
107
|
-
"id": "
|
|
109
|
+
"id": "organization_synthetic_001",
|
|
108
110
|
"name": "Synthetic Organization",
|
|
109
111
|
"status": "active",
|
|
110
112
|
"membership": { "role": "admin" },
|
|
111
113
|
"created_at": "2026-07-28T12:00:00Z",
|
|
112
114
|
"updated_at": "2026-07-28T12:00:00Z",
|
|
113
|
-
"diagnostic_id": "
|
|
115
|
+
"diagnostic_id": "diag_organization_synthetic_001"
|
|
114
116
|
}
|
|
115
117
|
}
|
|
116
118
|
}
|
|
@@ -123,14 +125,61 @@
|
|
|
123
125
|
}
|
|
124
126
|
}
|
|
125
127
|
},
|
|
126
|
-
"/v1/
|
|
128
|
+
"/v1/organization/close": {
|
|
129
|
+
"post": {
|
|
130
|
+
"operationId": "closeOrganization",
|
|
131
|
+
"summary": "Close the current customer organization",
|
|
132
|
+
"description": "Terminally closes the organization selected by the verified Clerk\norganization session. Only an administrator may close it. OAuth grants\nand API credentials are deliberately excluded: delegated authority must\nnot be able to erase the organization that granted it.\n\nThe request requires the exact confirmation `close-organization`. Repeating a\ncompleted closure is safe and returns the original `closed_at`. The\nresult names provider-owned resources the administrator must still retire\noutside WhooshBang, such as revoking a customer-managed Telegram bot token\nin BotFather; no provider credential is returned.\n",
|
|
133
|
+
"tags": ["Organization"],
|
|
134
|
+
"security": [{ "clerkSession": [] }],
|
|
135
|
+
"x-organization-membership": "required",
|
|
136
|
+
"x-required-membership-role": "admin",
|
|
137
|
+
"x-repeat-semantics": {
|
|
138
|
+
"same_target": "idempotent",
|
|
139
|
+
"secret_returned": false
|
|
140
|
+
},
|
|
141
|
+
"requestBody": {
|
|
142
|
+
"required": true,
|
|
143
|
+
"content": {
|
|
144
|
+
"application/json": {
|
|
145
|
+
"schema": {
|
|
146
|
+
"$ref": "#/components/schemas/CloseOrganizationRequest"
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
"responses": {
|
|
152
|
+
"200": {
|
|
153
|
+
"description": "The organization is closed, with any manual provider retirement still required.",
|
|
154
|
+
"headers": {
|
|
155
|
+
"WhooshBang-Diagnostic-Id": {
|
|
156
|
+
"$ref": "#/components/headers/DiagnosticId"
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
"content": {
|
|
160
|
+
"application/json": {
|
|
161
|
+
"schema": {
|
|
162
|
+
"$ref": "#/components/schemas/OrganizationClosureResult"
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"400": { "$ref": "#/components/responses/BadRequest" },
|
|
168
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
169
|
+
"403": { "$ref": "#/components/responses/Forbidden" },
|
|
170
|
+
"409": { "$ref": "#/components/responses/Conflict" },
|
|
171
|
+
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
"/v1/organization/credentials": {
|
|
127
176
|
"get": {
|
|
128
|
-
"operationId": "
|
|
129
|
-
"summary": "List safe
|
|
130
|
-
"description": "Returns only credentials owned by the
|
|
131
|
-
"tags": ["
|
|
177
|
+
"operationId": "listOrganizationCredentials",
|
|
178
|
+
"summary": "List safe organization credential metadata",
|
|
179
|
+
"description": "Returns only credentials owned by the organization selected by the verified\nClerk organization session. Secrets and digest material are never\nreturned.\n",
|
|
180
|
+
"tags": ["Organization credentials"],
|
|
132
181
|
"security": [{ "clerkSession": [] }],
|
|
133
|
-
"x-
|
|
182
|
+
"x-organization-membership": "required",
|
|
134
183
|
"parameters": [
|
|
135
184
|
{ "$ref": "#/components/parameters/ApiCredentialAfterCursor" },
|
|
136
185
|
{ "$ref": "#/components/parameters/ApiCredentialPageLimit" },
|
|
@@ -138,7 +187,7 @@
|
|
|
138
187
|
],
|
|
139
188
|
"responses": {
|
|
140
189
|
"200": {
|
|
141
|
-
"description": "A stable page of safe
|
|
190
|
+
"description": "A stable page of safe organization credential metadata.",
|
|
142
191
|
"headers": {
|
|
143
192
|
"WhooshBang-Diagnostic-Id": {
|
|
144
193
|
"$ref": "#/components/headers/DiagnosticId"
|
|
@@ -147,18 +196,18 @@
|
|
|
147
196
|
"content": {
|
|
148
197
|
"application/json": {
|
|
149
198
|
"schema": {
|
|
150
|
-
"$ref": "#/components/schemas/
|
|
199
|
+
"$ref": "#/components/schemas/OrganizationCredentialCollection"
|
|
151
200
|
},
|
|
152
201
|
"examples": {
|
|
153
|
-
"
|
|
202
|
+
"organizationCredentials": {
|
|
154
203
|
"value": {
|
|
155
204
|
"items": [
|
|
156
205
|
{
|
|
157
|
-
"id": "
|
|
158
|
-
"prefix": "
|
|
206
|
+
"id": "ocred_AAAAAAAAAAAAAAAAAAAAAA",
|
|
207
|
+
"prefix": "wb_oc1.ocred_AAAAAAAA",
|
|
159
208
|
"label": "Synthetic release automation",
|
|
160
209
|
"scopes": [
|
|
161
|
-
"
|
|
210
|
+
"organization:read",
|
|
162
211
|
"messages:write",
|
|
163
212
|
"messages:read"
|
|
164
213
|
],
|
|
@@ -185,12 +234,12 @@
|
|
|
185
234
|
}
|
|
186
235
|
},
|
|
187
236
|
"post": {
|
|
188
|
-
"operationId": "
|
|
189
|
-
"summary": "Create an
|
|
190
|
-
"description": "Creates one credential against the whole
|
|
191
|
-
"tags": ["
|
|
237
|
+
"operationId": "createOrganizationCredential",
|
|
238
|
+
"summary": "Create an organization-scoped API credential",
|
|
239
|
+
"description": "Creates one credential against the whole organization. It names no project\nand no environment: a request names them in its path, and the\ncredential's authority on that path is the intersection of its scopes\nwith the project-credential vocabulary, so it is never wider than a\nproject credential would have been for the same project environment.\nThe complete bearer secret appears only in this creation response. It\ncannot be read later and is never replayed from an idempotency cache.\n",
|
|
240
|
+
"tags": ["Organization credentials"],
|
|
192
241
|
"security": [{ "clerkSession": [] }],
|
|
193
|
-
"x-
|
|
242
|
+
"x-organization-membership": "required",
|
|
194
243
|
"x-secret-reveal": {
|
|
195
244
|
"responses": 1,
|
|
196
245
|
"replayable": false,
|
|
@@ -201,14 +250,14 @@
|
|
|
201
250
|
"content": {
|
|
202
251
|
"application/json": {
|
|
203
252
|
"schema": {
|
|
204
|
-
"$ref": "#/components/schemas/
|
|
253
|
+
"$ref": "#/components/schemas/CreateOrganizationCredentialRequest"
|
|
205
254
|
},
|
|
206
255
|
"examples": {
|
|
207
|
-
"
|
|
256
|
+
"createOrganizationCredential": {
|
|
208
257
|
"value": {
|
|
209
258
|
"label": "Release automation",
|
|
210
259
|
"scopes": [
|
|
211
|
-
"
|
|
260
|
+
"organization:read",
|
|
212
261
|
"messages:write",
|
|
213
262
|
"messages:read"
|
|
214
263
|
]
|
|
@@ -229,17 +278,17 @@
|
|
|
229
278
|
"content": {
|
|
230
279
|
"application/json": {
|
|
231
280
|
"schema": {
|
|
232
|
-
"$ref": "#/components/schemas/
|
|
281
|
+
"$ref": "#/components/schemas/OrganizationCredentialSecretReveal"
|
|
233
282
|
},
|
|
234
283
|
"examples": {
|
|
235
|
-
"
|
|
284
|
+
"createdOrganizationCredential": {
|
|
236
285
|
"value": {
|
|
237
286
|
"credential": {
|
|
238
|
-
"id": "
|
|
239
|
-
"prefix": "
|
|
287
|
+
"id": "ocred_AAAAAAAAAAAAAAAAAAAAAA",
|
|
288
|
+
"prefix": "wb_oc1.ocred_AAAAAAAA",
|
|
240
289
|
"label": "Synthetic release automation",
|
|
241
290
|
"scopes": [
|
|
242
|
-
"
|
|
291
|
+
"organization:read",
|
|
243
292
|
"messages:write",
|
|
244
293
|
"messages:read"
|
|
245
294
|
],
|
|
@@ -247,7 +296,7 @@
|
|
|
247
296
|
"created_at": "2026-07-25T17:45:00Z",
|
|
248
297
|
"status": "active"
|
|
249
298
|
},
|
|
250
|
-
"secret": "
|
|
299
|
+
"secret": "wb_oc1.ocred_AAAAAAAAAAAAAAAAAAAAAA.AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
|
251
300
|
}
|
|
252
301
|
}
|
|
253
302
|
}
|
|
@@ -262,15 +311,17 @@
|
|
|
262
311
|
}
|
|
263
312
|
}
|
|
264
313
|
},
|
|
265
|
-
"/v1/
|
|
266
|
-
"parameters": [
|
|
314
|
+
"/v1/organization/credentials/{organization_credential_id}/rotate": {
|
|
315
|
+
"parameters": [
|
|
316
|
+
{ "$ref": "#/components/parameters/OrganizationCredentialId" }
|
|
317
|
+
],
|
|
267
318
|
"post": {
|
|
268
|
-
"operationId": "
|
|
269
|
-
"summary": "Rotate an
|
|
270
|
-
"description": "Creates one replacement with the same label and scopes. The complete new\nbearer secret appears only in this response. The replaced credential\nremains active for the explicitly declared overlap, from zero through\n86400 seconds, then becomes terminally revoked. A revoked credential\ncannot be rotated. Missing and out-of-
|
|
271
|
-
"tags": ["
|
|
319
|
+
"operationId": "rotateOrganizationCredential",
|
|
320
|
+
"summary": "Rotate an organization-scoped API credential",
|
|
321
|
+
"description": "Creates one replacement with the same label and scopes. The complete new\nbearer secret appears only in this response. The replaced credential\nremains active for the explicitly declared overlap, from zero through\n86400 seconds, then becomes terminally revoked. A revoked credential\ncannot be rotated. Missing and out-of-organization credentials use the same\nnon-enumerating `404`.\n",
|
|
322
|
+
"tags": ["Organization credentials"],
|
|
272
323
|
"security": [{ "clerkSession": [] }],
|
|
273
|
-
"x-
|
|
324
|
+
"x-organization-membership": "required",
|
|
274
325
|
"x-secret-reveal": {
|
|
275
326
|
"responses": 1,
|
|
276
327
|
"replayable": false,
|
|
@@ -281,10 +332,10 @@
|
|
|
281
332
|
"content": {
|
|
282
333
|
"application/json": {
|
|
283
334
|
"schema": {
|
|
284
|
-
"$ref": "#/components/schemas/
|
|
335
|
+
"$ref": "#/components/schemas/RotateOrganizationCredentialRequest"
|
|
285
336
|
},
|
|
286
337
|
"examples": {
|
|
287
|
-
"
|
|
338
|
+
"rotateOrganizationCredential": {
|
|
288
339
|
"value": { "overlap_seconds": 3600 }
|
|
289
340
|
}
|
|
290
341
|
}
|
|
@@ -302,18 +353,18 @@
|
|
|
302
353
|
"content": {
|
|
303
354
|
"application/json": {
|
|
304
355
|
"schema": {
|
|
305
|
-
"$ref": "#/components/schemas/
|
|
356
|
+
"$ref": "#/components/schemas/OrganizationCredentialRotation"
|
|
306
357
|
},
|
|
307
358
|
"examples": {
|
|
308
|
-
"
|
|
359
|
+
"rotatedOrganizationCredential": {
|
|
309
360
|
"value": {
|
|
310
361
|
"credential": {
|
|
311
362
|
"credential": {
|
|
312
|
-
"id": "
|
|
313
|
-
"prefix": "
|
|
363
|
+
"id": "ocred_BBBBBBBBBBBBBBBBBBBBBA",
|
|
364
|
+
"prefix": "wb_oc1.ocred_BBBBBBBB",
|
|
314
365
|
"label": "Synthetic release automation",
|
|
315
366
|
"scopes": [
|
|
316
|
-
"
|
|
367
|
+
"organization:read",
|
|
317
368
|
"messages:write",
|
|
318
369
|
"messages:read"
|
|
319
370
|
],
|
|
@@ -321,14 +372,14 @@
|
|
|
321
372
|
"created_at": "2026-07-25T17:45:00Z",
|
|
322
373
|
"status": "active"
|
|
323
374
|
},
|
|
324
|
-
"secret": "
|
|
375
|
+
"secret": "wb_oc1.ocred_BBBBBBBBBBBBBBBBBBBBBA.BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBA"
|
|
325
376
|
},
|
|
326
377
|
"replaced_credential": {
|
|
327
|
-
"id": "
|
|
328
|
-
"prefix": "
|
|
378
|
+
"id": "ocred_AAAAAAAAAAAAAAAAAAAAAA",
|
|
379
|
+
"prefix": "wb_oc1.ocred_AAAAAAAA",
|
|
329
380
|
"label": "Synthetic release automation",
|
|
330
381
|
"scopes": [
|
|
331
|
-
"
|
|
382
|
+
"organization:read",
|
|
332
383
|
"messages:write",
|
|
333
384
|
"messages:read"
|
|
334
385
|
],
|
|
@@ -352,15 +403,17 @@
|
|
|
352
403
|
}
|
|
353
404
|
}
|
|
354
405
|
},
|
|
355
|
-
"/v1/
|
|
356
|
-
"parameters": [
|
|
406
|
+
"/v1/organization/credentials/{organization_credential_id}/revoke": {
|
|
407
|
+
"parameters": [
|
|
408
|
+
{ "$ref": "#/components/parameters/OrganizationCredentialId" }
|
|
409
|
+
],
|
|
357
410
|
"post": {
|
|
358
|
-
"operationId": "
|
|
359
|
-
"summary": "Revoke an
|
|
360
|
-
"description": "Immediately and terminally revokes the selected credential. Repeating\nthe request for the same visible credential is safe and returns the\nsame revoked metadata without revealing secret or digest material.\nMissing and out-of-
|
|
361
|
-
"tags": ["
|
|
411
|
+
"operationId": "revokeOrganizationCredential",
|
|
412
|
+
"summary": "Revoke an organization-scoped API credential",
|
|
413
|
+
"description": "Immediately and terminally revokes the selected credential. Repeating\nthe request for the same visible credential is safe and returns the\nsame revoked metadata without revealing secret or digest material.\nMissing and out-of-organization credentials use the same non-enumerating\n`404`.\n",
|
|
414
|
+
"tags": ["Organization credentials"],
|
|
362
415
|
"security": [{ "clerkSession": [] }],
|
|
363
|
-
"x-
|
|
416
|
+
"x-organization-membership": "required",
|
|
364
417
|
"x-repeat-semantics": {
|
|
365
418
|
"same_target": "idempotent",
|
|
366
419
|
"secret_returned": false
|
|
@@ -375,15 +428,17 @@
|
|
|
375
428
|
},
|
|
376
429
|
"content": {
|
|
377
430
|
"application/json": {
|
|
378
|
-
"schema": {
|
|
431
|
+
"schema": {
|
|
432
|
+
"$ref": "#/components/schemas/OrganizationCredential"
|
|
433
|
+
},
|
|
379
434
|
"examples": {
|
|
380
|
-
"
|
|
435
|
+
"revokedOrganizationCredential": {
|
|
381
436
|
"value": {
|
|
382
|
-
"id": "
|
|
383
|
-
"prefix": "
|
|
437
|
+
"id": "ocred_AAAAAAAAAAAAAAAAAAAAAA",
|
|
438
|
+
"prefix": "wb_oc1.ocred_AAAAAAAA",
|
|
384
439
|
"label": "Synthetic release automation",
|
|
385
440
|
"scopes": [
|
|
386
|
-
"
|
|
441
|
+
"organization:read",
|
|
387
442
|
"messages:write",
|
|
388
443
|
"messages:read"
|
|
389
444
|
],
|
|
@@ -408,16 +463,16 @@
|
|
|
408
463
|
"/v1/projects": {
|
|
409
464
|
"get": {
|
|
410
465
|
"operationId": "listProjects",
|
|
411
|
-
"summary": "List projects in the current
|
|
412
|
-
"description": "Returns only projects owned by the
|
|
466
|
+
"summary": "List projects in the current organization",
|
|
467
|
+
"description": "Returns only projects owned by the organization selected by the verified\nClerk organization session. Every project includes its complete test/live\nenvironment and default-notifier bootstrap.\n",
|
|
413
468
|
"tags": ["Projects"],
|
|
414
469
|
"security": [
|
|
415
470
|
{ "clerkSession": [] },
|
|
416
471
|
{ "bearerGrant": [] },
|
|
417
|
-
{ "
|
|
472
|
+
{ "bearerOrganizationCredential": [] }
|
|
418
473
|
],
|
|
419
474
|
"x-required-scopes": ["projects:read"],
|
|
420
|
-
"x-
|
|
475
|
+
"x-organization-membership": "required",
|
|
421
476
|
"parameters": [
|
|
422
477
|
{ "$ref": "#/components/parameters/ProjectAfterCursor" },
|
|
423
478
|
{ "$ref": "#/components/parameters/ProjectPageLimit" },
|
|
@@ -425,7 +480,7 @@
|
|
|
425
480
|
],
|
|
426
481
|
"responses": {
|
|
427
482
|
"200": {
|
|
428
|
-
"description": "A stable page of projects in the current
|
|
483
|
+
"description": "A stable page of projects in the current organization.",
|
|
429
484
|
"headers": {
|
|
430
485
|
"WhooshBang-Diagnostic-Id": {
|
|
431
486
|
"$ref": "#/components/headers/DiagnosticId"
|
|
@@ -440,7 +495,7 @@
|
|
|
440
495
|
"items": [
|
|
441
496
|
{
|
|
442
497
|
"id": "project_synthetic_001",
|
|
443
|
-
"
|
|
498
|
+
"organization_id": "organization_synthetic_001",
|
|
444
499
|
"name": "Synthetic Alerts",
|
|
445
500
|
"slug": "synthetic-alerts",
|
|
446
501
|
"status": "active",
|
|
@@ -475,7 +530,8 @@
|
|
|
475
530
|
],
|
|
476
531
|
"created_at": "2026-07-28T12:05:00Z",
|
|
477
532
|
"updated_at": "2026-07-28T12:05:00Z",
|
|
478
|
-
"diagnostic_id": "diag_project_synthetic_001"
|
|
533
|
+
"diagnostic_id": "diag_project_synthetic_001",
|
|
534
|
+
"privacy_mode": "minimal"
|
|
479
535
|
}
|
|
480
536
|
],
|
|
481
537
|
"page": 1,
|
|
@@ -496,15 +552,15 @@
|
|
|
496
552
|
"post": {
|
|
497
553
|
"operationId": "createProject",
|
|
498
554
|
"summary": "Create a project and its default environments",
|
|
499
|
-
"description": "Creates one project inside the authenticated
|
|
555
|
+
"description": "Creates one project inside the authenticated organization. The project, its\n`test` and `live` environments, and one `Default` notifier per\nenvironment are one atomic logical resource. Equivalent replay returns\nthe original `201` response without extending idempotency retention.\n",
|
|
500
556
|
"tags": ["Projects"],
|
|
501
557
|
"security": [{ "clerkSession": [] }, { "bearerGrant": [] }],
|
|
502
558
|
"x-required-scopes": ["projects:write"],
|
|
503
|
-
"x-
|
|
559
|
+
"x-organization-membership": "required",
|
|
504
560
|
"x-idempotency": {
|
|
505
561
|
"required": true,
|
|
506
562
|
"retention_seconds": 604800,
|
|
507
|
-
"scope": ["
|
|
563
|
+
"scope": ["authenticated_organization", "operation_id", "key"],
|
|
508
564
|
"equivalence": "validated_request",
|
|
509
565
|
"replay_retention_extends": false
|
|
510
566
|
},
|
|
@@ -541,7 +597,7 @@
|
|
|
541
597
|
"createdProject": {
|
|
542
598
|
"value": {
|
|
543
599
|
"id": "project_synthetic_001",
|
|
544
|
-
"
|
|
600
|
+
"organization_id": "organization_synthetic_001",
|
|
545
601
|
"name": "Synthetic Alerts",
|
|
546
602
|
"slug": "synthetic-alerts",
|
|
547
603
|
"status": "active",
|
|
@@ -576,7 +632,8 @@
|
|
|
576
632
|
],
|
|
577
633
|
"created_at": "2026-07-28T12:05:00Z",
|
|
578
634
|
"updated_at": "2026-07-28T12:05:00Z",
|
|
579
|
-
"diagnostic_id": "diag_project_synthetic_001"
|
|
635
|
+
"diagnostic_id": "diag_project_synthetic_001",
|
|
636
|
+
"privacy_mode": "minimal"
|
|
580
637
|
}
|
|
581
638
|
}
|
|
582
639
|
}
|
|
@@ -595,16 +652,16 @@
|
|
|
595
652
|
"parameters": [{ "$ref": "#/components/parameters/ProjectId" }],
|
|
596
653
|
"get": {
|
|
597
654
|
"operationId": "getProject",
|
|
598
|
-
"summary": "Read one project in the current
|
|
599
|
-
"description": "Returns the complete project bootstrap. An absent project and a project\noutside the authenticated
|
|
655
|
+
"summary": "Read one project in the current organization",
|
|
656
|
+
"description": "Returns the complete project bootstrap. An absent project and a project\noutside the authenticated organization use the same non-enumerating `404`.\n",
|
|
600
657
|
"tags": ["Projects"],
|
|
601
658
|
"security": [
|
|
602
659
|
{ "clerkSession": [] },
|
|
603
660
|
{ "bearerGrant": [] },
|
|
604
|
-
{ "
|
|
661
|
+
{ "bearerOrganizationCredential": [] }
|
|
605
662
|
],
|
|
606
663
|
"x-required-scopes": ["projects:read"],
|
|
607
|
-
"x-
|
|
664
|
+
"x-organization-membership": "required",
|
|
608
665
|
"responses": {
|
|
609
666
|
"200": {
|
|
610
667
|
"description": "The current project and its two environments.",
|
|
@@ -620,7 +677,7 @@
|
|
|
620
677
|
"project": {
|
|
621
678
|
"value": {
|
|
622
679
|
"id": "project_synthetic_001",
|
|
623
|
-
"
|
|
680
|
+
"organization_id": "organization_synthetic_001",
|
|
624
681
|
"name": "Synthetic Alerts",
|
|
625
682
|
"slug": "synthetic-alerts",
|
|
626
683
|
"status": "active",
|
|
@@ -655,7 +712,8 @@
|
|
|
655
712
|
],
|
|
656
713
|
"created_at": "2026-07-28T12:05:00Z",
|
|
657
714
|
"updated_at": "2026-07-28T12:05:00Z",
|
|
658
|
-
"diagnostic_id": "diag_project_synthetic_001"
|
|
715
|
+
"diagnostic_id": "diag_project_synthetic_001",
|
|
716
|
+
"privacy_mode": "minimal"
|
|
659
717
|
}
|
|
660
718
|
}
|
|
661
719
|
}
|
|
@@ -667,6 +725,51 @@
|
|
|
667
725
|
"404": { "$ref": "#/components/responses/NotFound" },
|
|
668
726
|
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
669
727
|
}
|
|
728
|
+
},
|
|
729
|
+
"patch": {
|
|
730
|
+
"operationId": "updateProject",
|
|
731
|
+
"summary": "Set a project's privacy policy",
|
|
732
|
+
"description": "Changes profile collection for both project environments. minimal is the\ndefault for new and existing projects. standard permits messenger profiles;\nminimal keeps recipient language only; private keeps delivery routing and\nthe customer-supplied subscriber identifier, with no profile data.\nMoving standard to minimal erases existing identifying profile fields.\nMoving to private also erases recipient language. Increasing collection\ndoes not restore erased data. The operation is naturally idempotent.\nAn absent project and one outside the organization return the same 404.\n",
|
|
733
|
+
"tags": ["Projects"],
|
|
734
|
+
"security": [
|
|
735
|
+
{ "clerkSession": [] },
|
|
736
|
+
{ "bearerGrant": [] },
|
|
737
|
+
{ "bearerCredential": [] },
|
|
738
|
+
{ "bearerOrganizationCredential": [] }
|
|
739
|
+
],
|
|
740
|
+
"x-required-scopes": ["projects:write"],
|
|
741
|
+
"x-organization-membership": "required",
|
|
742
|
+
"requestBody": {
|
|
743
|
+
"required": true,
|
|
744
|
+
"content": {
|
|
745
|
+
"application/json": {
|
|
746
|
+
"schema": { "$ref": "#/components/schemas/UpdateProjectRequest" },
|
|
747
|
+
"examples": {
|
|
748
|
+
"updateProject": { "value": { "privacy_mode": "private" } }
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
},
|
|
753
|
+
"responses": {
|
|
754
|
+
"200": {
|
|
755
|
+
"description": "The project after changing its privacy policy and clearing disallowed profile fields.",
|
|
756
|
+
"headers": {
|
|
757
|
+
"WhooshBang-Diagnostic-Id": {
|
|
758
|
+
"$ref": "#/components/headers/DiagnosticId"
|
|
759
|
+
}
|
|
760
|
+
},
|
|
761
|
+
"content": {
|
|
762
|
+
"application/json": {
|
|
763
|
+
"schema": { "$ref": "#/components/schemas/Project" }
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
},
|
|
767
|
+
"400": { "$ref": "#/components/responses/BadRequest" },
|
|
768
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
769
|
+
"403": { "$ref": "#/components/responses/Forbidden" },
|
|
770
|
+
"404": { "$ref": "#/components/responses/NotFound" },
|
|
771
|
+
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
772
|
+
}
|
|
670
773
|
}
|
|
671
774
|
},
|
|
672
775
|
"/v1/projects/{project_id}/recipient-copy-overrides": {
|
|
@@ -674,7 +777,7 @@
|
|
|
674
777
|
"get": {
|
|
675
778
|
"operationId": "listRecipientCopyOverrides",
|
|
676
779
|
"summary": "List sparse recipient-copy overrides for one project",
|
|
677
|
-
"description": "Returns only customer-authored overrides for the project in the\nauthenticated
|
|
780
|
+
"description": "Returns only customer-authored overrides for the project in the\nauthenticated organization. Missing values are intentionally absent and use\nWhooshBang's complete shipped catalog at render time. An optional\ncanonical language filter preserves the project + language + string\naddress without applying locale negotiation.\n",
|
|
678
781
|
"tags": ["Projects"],
|
|
679
782
|
"security": [
|
|
680
783
|
{ "clerkSession": [] },
|
|
@@ -682,7 +785,7 @@
|
|
|
682
785
|
{ "bearerCredential": [] }
|
|
683
786
|
],
|
|
684
787
|
"x-required-scopes": ["projects:read"],
|
|
685
|
-
"x-
|
|
788
|
+
"x-organization-membership": "required",
|
|
686
789
|
"parameters": [
|
|
687
790
|
{
|
|
688
791
|
"name": "language",
|
|
@@ -745,7 +848,7 @@
|
|
|
745
848
|
{ "bearerCredential": [] }
|
|
746
849
|
],
|
|
747
850
|
"x-required-scopes": ["projects:write"],
|
|
748
|
-
"x-
|
|
851
|
+
"x-organization-membership": "required",
|
|
749
852
|
"requestBody": {
|
|
750
853
|
"required": true,
|
|
751
854
|
"content": {
|
|
@@ -790,7 +893,7 @@
|
|
|
790
893
|
{ "bearerCredential": [] }
|
|
791
894
|
],
|
|
792
895
|
"x-required-scopes": ["projects:write"],
|
|
793
|
-
"x-
|
|
896
|
+
"x-organization-membership": "required",
|
|
794
897
|
"responses": {
|
|
795
898
|
"204": {
|
|
796
899
|
"description": "The shipped catalog value is effective at this address."
|
|
@@ -811,10 +914,10 @@
|
|
|
811
914
|
"get": {
|
|
812
915
|
"operationId": "listApiCredentials",
|
|
813
916
|
"summary": "List safe API credential metadata",
|
|
814
|
-
"description": "Returns only credentials in the selected project environment owned by\nthe
|
|
917
|
+
"description": "Returns only credentials in the selected project environment owned by\nthe organization selected by the verified Clerk organization session.\nSecrets and digest material are never returned. An absent or\nout-of-organization project or environment uses the same non-enumerating\n`404`.\n",
|
|
815
918
|
"tags": ["API credentials"],
|
|
816
919
|
"security": [{ "clerkSession": [] }],
|
|
817
|
-
"x-
|
|
920
|
+
"x-organization-membership": "required",
|
|
818
921
|
"parameters": [
|
|
819
922
|
{ "$ref": "#/components/parameters/ApiCredentialAfterCursor" },
|
|
820
923
|
{ "$ref": "#/components/parameters/ApiCredentialPageLimit" },
|
|
@@ -878,7 +981,7 @@
|
|
|
878
981
|
"description": "Creates one credential in the selected project environment. The complete\nbearer secret appears only in this creation response. It cannot be read\nlater and is never replayed from an idempotency cache. If a client loses\nthis response, it lists safe metadata and creates then revokes a\nreplacement.\n",
|
|
879
982
|
"tags": ["API credentials"],
|
|
880
983
|
"security": [{ "clerkSession": [] }],
|
|
881
|
-
"x-
|
|
984
|
+
"x-organization-membership": "required",
|
|
882
985
|
"x-secret-reveal": {
|
|
883
986
|
"responses": 1,
|
|
884
987
|
"replayable": false,
|
|
@@ -967,7 +1070,7 @@
|
|
|
967
1070
|
"description": "Creates one replacement with the same label and scopes. The complete new\nbearer secret appears only in this response. The replaced credential\nremains active for the explicitly declared overlap, from zero through\n86400 seconds, then becomes terminally revoked. A revoked credential\ncannot be rotated. Missing and out-of-scope credentials use the same\nnon-enumerating `404`.\n",
|
|
968
1071
|
"tags": ["API credentials"],
|
|
969
1072
|
"security": [{ "clerkSession": [] }],
|
|
970
|
-
"x-
|
|
1073
|
+
"x-organization-membership": "required",
|
|
971
1074
|
"x-secret-reveal": {
|
|
972
1075
|
"responses": 1,
|
|
973
1076
|
"replayable": false,
|
|
@@ -1067,7 +1170,7 @@
|
|
|
1067
1170
|
"description": "Immediately and terminally revokes the selected credential. Repeating\nthe request for the same visible credential is safe and returns the\nsame revoked metadata without revealing secret or digest material.\nMissing and out-of-scope credentials use the same non-enumerating `404`.\n",
|
|
1068
1171
|
"tags": ["API credentials"],
|
|
1069
1172
|
"security": [{ "clerkSession": [] }],
|
|
1070
|
-
"x-
|
|
1173
|
+
"x-organization-membership": "required",
|
|
1071
1174
|
"x-repeat-semantics": {
|
|
1072
1175
|
"same_target": "idempotent",
|
|
1073
1176
|
"secret_returned": false
|
|
@@ -1356,7 +1459,7 @@
|
|
|
1356
1459
|
"security": [
|
|
1357
1460
|
{ "bearerCredential": [] },
|
|
1358
1461
|
{ "bearerGrant": [] },
|
|
1359
|
-
{ "
|
|
1462
|
+
{ "bearerOrganizationCredential": [] }
|
|
1360
1463
|
],
|
|
1361
1464
|
"x-required-scopes": ["messages:write"],
|
|
1362
1465
|
"x-idempotency": {
|
|
@@ -1447,7 +1550,7 @@
|
|
|
1447
1550
|
"security": [
|
|
1448
1551
|
{ "bearerCredential": [] },
|
|
1449
1552
|
{ "bearerGrant": [] },
|
|
1450
|
-
{ "
|
|
1553
|
+
{ "bearerOrganizationCredential": [] }
|
|
1451
1554
|
],
|
|
1452
1555
|
"x-required-scopes": ["messages:write"],
|
|
1453
1556
|
"x-repeat-semantics": {
|
|
@@ -1469,7 +1572,7 @@
|
|
|
1469
1572
|
"post": {
|
|
1470
1573
|
"operationId": "createMessage",
|
|
1471
1574
|
"summary": "Create an asynchronous message",
|
|
1472
|
-
"description": "Durably accepts one logical text message for one subscriber and one\nresolved channel binding. `202` proves API acceptance only; it does not\nclaim provider acceptance or end-device delivery.\n",
|
|
1575
|
+
"description": "Durably accepts one logical text message for one subscriber and one\nresolved channel binding. `202` proves API acceptance only; it does not\nclaim provider acceptance or end-device delivery.\nThe reserved `test:` subscriber prefix and `delivery_target: simulator`\nare test-environment-only. Live sends are refused before acceptance or\nidempotent replay with `400 request_invalid`; reserved subscriber IDs\ncarry a field error at `/to/subscriber_id`.\n",
|
|
1473
1576
|
"tags": ["Messages"],
|
|
1474
1577
|
"security": [{ "bearerCredential": [] }, { "machineCredential": [] }],
|
|
1475
1578
|
"x-required-scopes": ["messages:write"],
|
|
@@ -2010,7 +2113,7 @@
|
|
|
2010
2113
|
"post": {
|
|
2011
2114
|
"operationId": "createMachineClient",
|
|
2012
2115
|
"summary": "Create a destination-bound machine client",
|
|
2013
|
-
"description": "Creates one machine client in the project/environment selected by the\nproject credential. The notifier, subscriber, and active binding become\nimmutable authorization bounds. The response never contains a readable\nsecret or digest.\n",
|
|
2116
|
+
"description": "Creates one machine client in the project/environment selected by the\nproject credential. The notifier, subscriber, and active binding become\nimmutable authorization bounds. The response never contains a readable\nsecret or digest.\nLive environments reject the reserved `test:` subscriber prefix with\n`400 request_invalid` and a field error at `/subscriber_id` before creation.\n",
|
|
2014
2117
|
"tags": ["Machine clients"],
|
|
2015
2118
|
"security": [{ "bearerCredential": [] }],
|
|
2016
2119
|
"x-required-scopes": ["machine-clients:write"],
|
|
@@ -2585,7 +2688,7 @@
|
|
|
2585
2688
|
{ "clerkSession": [] },
|
|
2586
2689
|
{ "bearerCredential": [] },
|
|
2587
2690
|
{ "bearerGrant": [] },
|
|
2588
|
-
{ "
|
|
2691
|
+
{ "bearerOrganizationCredential": [] }
|
|
2589
2692
|
],
|
|
2590
2693
|
"x-required-scopes": ["messages:read"],
|
|
2591
2694
|
"parameters": [
|
|
@@ -2659,7 +2762,7 @@
|
|
|
2659
2762
|
{ "clerkSession": [] },
|
|
2660
2763
|
{ "bearerCredential": [] },
|
|
2661
2764
|
{ "bearerGrant": [] },
|
|
2662
|
-
{ "
|
|
2765
|
+
{ "bearerOrganizationCredential": [] }
|
|
2663
2766
|
],
|
|
2664
2767
|
"x-required-scopes": ["messages:write"],
|
|
2665
2768
|
"x-idempotency": {
|
|
@@ -2793,7 +2896,7 @@
|
|
|
2793
2896
|
{ "clerkSession": [] },
|
|
2794
2897
|
{ "bearerCredential": [] },
|
|
2795
2898
|
{ "bearerGrant": [] },
|
|
2796
|
-
{ "
|
|
2899
|
+
{ "bearerOrganizationCredential": [] }
|
|
2797
2900
|
],
|
|
2798
2901
|
"x-required-scopes": ["messages:read"],
|
|
2799
2902
|
"responses": {
|
|
@@ -2825,7 +2928,7 @@
|
|
|
2825
2928
|
{ "clerkSession": [] },
|
|
2826
2929
|
{ "bearerCredential": [] },
|
|
2827
2930
|
{ "bearerGrant": [] },
|
|
2828
|
-
{ "
|
|
2931
|
+
{ "bearerOrganizationCredential": [] }
|
|
2829
2932
|
],
|
|
2830
2933
|
"x-required-scopes": ["messages:write"],
|
|
2831
2934
|
"responses": {
|
|
@@ -2859,7 +2962,7 @@
|
|
|
2859
2962
|
{ "clerkSession": [] },
|
|
2860
2963
|
{ "bearerCredential": [] },
|
|
2861
2964
|
{ "bearerGrant": [] },
|
|
2862
|
-
{ "
|
|
2965
|
+
{ "bearerOrganizationCredential": [] }
|
|
2863
2966
|
],
|
|
2864
2967
|
"x-required-scopes": ["messages:write"],
|
|
2865
2968
|
"x-idempotency": {
|
|
@@ -2963,7 +3066,7 @@
|
|
|
2963
3066
|
{ "clerkSession": [] },
|
|
2964
3067
|
{ "bearerCredential": [] },
|
|
2965
3068
|
{ "bearerGrant": [] },
|
|
2966
|
-
{ "
|
|
3069
|
+
{ "bearerOrganizationCredential": [] }
|
|
2967
3070
|
],
|
|
2968
3071
|
"x-required-scopes": ["messages:write"],
|
|
2969
3072
|
"x-repeat-semantics": {
|
|
@@ -3000,7 +3103,7 @@
|
|
|
3000
3103
|
{ "clerkSession": [] },
|
|
3001
3104
|
{ "bearerCredential": [] },
|
|
3002
3105
|
{ "bearerGrant": [] },
|
|
3003
|
-
{ "
|
|
3106
|
+
{ "bearerOrganizationCredential": [] }
|
|
3004
3107
|
],
|
|
3005
3108
|
"x-required-scopes": ["messages:read"],
|
|
3006
3109
|
"parameters": [
|
|
@@ -3061,7 +3164,7 @@
|
|
|
3061
3164
|
{ "clerkSession": [] },
|
|
3062
3165
|
{ "bearerCredential": [] },
|
|
3063
3166
|
{ "bearerGrant": [] },
|
|
3064
|
-
{ "
|
|
3167
|
+
{ "bearerOrganizationCredential": [] }
|
|
3065
3168
|
],
|
|
3066
3169
|
"x-required-scopes": ["connections:read"],
|
|
3067
3170
|
"responses": {
|
|
@@ -3136,7 +3239,7 @@
|
|
|
3136
3239
|
{ "clerkSession": [] },
|
|
3137
3240
|
{ "bearerCredential": [] },
|
|
3138
3241
|
{ "bearerGrant": [] },
|
|
3139
|
-
{ "
|
|
3242
|
+
{ "bearerOrganizationCredential": [] }
|
|
3140
3243
|
],
|
|
3141
3244
|
"x-required-scopes": ["connections:read"],
|
|
3142
3245
|
"parameters": [
|
|
@@ -3146,7 +3249,7 @@
|
|
|
3146
3249
|
],
|
|
3147
3250
|
"responses": {
|
|
3148
3251
|
"200": {
|
|
3149
|
-
"description": "Connections owned by exactly this
|
|
3252
|
+
"description": "Connections owned by exactly this organization, project, and environment.",
|
|
3150
3253
|
"headers": {
|
|
3151
3254
|
"WhooshBang-Diagnostic-Id": {
|
|
3152
3255
|
"$ref": "#/components/headers/DiagnosticId"
|
|
@@ -3201,13 +3304,13 @@
|
|
|
3201
3304
|
"post": {
|
|
3202
3305
|
"operationId": "createChannelConnection",
|
|
3203
3306
|
"summary": "Select a provider identity for this environment",
|
|
3204
|
-
"description": "Creates a connection in `pending`. An equivalent idempotent replay\nreturns the same connection; different input for the same key returns\n`idempotency_conflict`.\n\n`whooshbang_shared` names a disclosed WhooshBang-owned identity.\n`customer_byok` supplies the customer's own provider credential and\ncarries no identity field: `provider_identity_digest` is unique across\nevery tenant, so an endpoint that digested a client-supplied identity\nwould answer \"already claimed\" for a bot the caller does not own — an\noracle for whether any given bot is connected to WhooshBang by anyone.\nThe identity is derived server-side from a provider-validated `getMe`\non the submitted credential instead.\n\n`customer_managed` supplies no credential at all. Telegram creates a\nbrand new bot on the administrator's own account and hands WhooshBang\nits token server to server, so the token never reaches a browser, a\nclipboard, this request, or any response. The connection is returned\n`pending` with a `setup` carrying the link the administrator opens and\nthe moment it stops working; poll the connection, or read\n`setup.status`, to follow the attempt. Creating a bot is a person-only\naction, so a connection whose administrator never returns simply\nexpires — and a bot Telegram already created outlives it, because no\nprovider API can delete a bot.\n\nEverything that can go wrong in a managed setup after this call\nreturns is reported on `setup` rather than as a refusal here, because\nby then the connection exists and the failing party is a person this\nrequest has already answered. A lapsed link is `expired`; an attempt\nTelegram or WhooshBang could not complete is `failed` with a\n`failure_reason`. Both are recoverable through\n`restartChannelConnectionSetup` on the same connection.\n\nThe Problem vocabulary is closed, so each refusal reuses a published\ncode and is distinguished by `field_errors[].code`:\n\n- the provider answered and rejected the credential —\n `request_invalid` 400, `provider_credential_invalid` at `/credential`;\n- the identity already has a webhook and `confirm_webhook_takeover` was\n not sent — `request_invalid` 400, `webhook_takeover_required` at\n `/confirm_webhook_takeover`. This is a warning, not a prohibition:\n repeating the request with the confirmation connects the identity\n whoever owns the endpoint it currently delivers to;\n- the webhook it already has belongs to another WhooshBang connection —\n `request_invalid` 400, `whooshbang_connection_takeover_required` at\n `/confirm_webhook_takeover`. Separate from the code above because the\n consequence is separate: confirming this one **disables** the other\n connection, which would otherwise go on reporting itself healthy while\n receiving nothing;\n- the identity is already connected, by this
|
|
3307
|
+
"description": "Creates a connection in `pending`. An equivalent idempotent replay\nreturns the same connection; different input for the same key returns\n`idempotency_conflict`.\n\n`whooshbang_shared` names a disclosed WhooshBang-owned identity.\n`customer_byok` supplies the customer's own provider credential and\ncarries no identity field: `provider_identity_digest` is unique across\nevery tenant, so an endpoint that digested a client-supplied identity\nwould answer \"already claimed\" for a bot the caller does not own — an\noracle for whether any given bot is connected to WhooshBang by anyone.\nThe identity is derived server-side from a provider-validated `getMe`\non the submitted credential instead.\n\n`customer_managed` supplies no credential at all. Telegram creates a\nbrand new bot on the administrator's own Telegram account and hands WhooshBang\nits token server to server, so the token never reaches a browser, a\nclipboard, this request, or any response. The connection is returned\n`pending` with a `setup` carrying the link the administrator opens and\nthe moment it stops working; poll the connection, or read\n`setup.status`, to follow the attempt. Creating a bot is a person-only\naction, so a connection whose administrator never returns simply\nexpires — and a bot Telegram already created outlives it, because no\nprovider API can delete a bot.\n\nEverything that can go wrong in a managed setup after this call\nreturns is reported on `setup` rather than as a refusal here, because\nby then the connection exists and the failing party is a person this\nrequest has already answered. A lapsed link is `expired`; an attempt\nTelegram or WhooshBang could not complete is `failed` with a\n`failure_reason`. Both are recoverable through\n`restartChannelConnectionSetup` on the same connection.\n\nThe Problem vocabulary is closed, so each refusal reuses a published\ncode and is distinguished by `field_errors[].code`:\n\n- the provider answered and rejected the credential —\n `request_invalid` 400, `provider_credential_invalid` at `/credential`;\n- the identity already has a webhook and `confirm_webhook_takeover` was\n not sent — `request_invalid` 400, `webhook_takeover_required` at\n `/confirm_webhook_takeover`. This is a warning, not a prohibition:\n repeating the request with the confirmation connects the identity\n whoever owns the endpoint it currently delivers to;\n- the webhook it already has belongs to another WhooshBang connection —\n `request_invalid` 400, `whooshbang_connection_takeover_required` at\n `/confirm_webhook_takeover`. Separate from the code above because the\n consequence is separate: confirming this one **disables** the other\n connection, which would otherwise go on reporting itself healthy while\n receiving nothing;\n- the identity is already connected, by this organization or any other —\n `idempotency_conflict` 409, `provider_identity_claimed` at `/`, which\n reports only that the identity the submitted credential proves is in\n use and never that some other identity is;\n- the provider could not be reached and the outcome is genuinely\n unknown — `provider_outcome_unknown` 502, no automatic retry;\n- the provider rate-limited the call — `provider_retryable` 503 with\n `retry_at`.\n",
|
|
3205
3308
|
"tags": ["Channel connections"],
|
|
3206
3309
|
"security": [
|
|
3207
3310
|
{ "clerkSession": [] },
|
|
3208
3311
|
{ "bearerCredential": [] },
|
|
3209
3312
|
{ "bearerGrant": [] },
|
|
3210
|
-
{ "
|
|
3313
|
+
{ "bearerOrganizationCredential": [] }
|
|
3211
3314
|
],
|
|
3212
3315
|
"x-required-scopes": ["connections:write"],
|
|
3213
3316
|
"x-idempotency": {
|
|
@@ -3397,7 +3500,7 @@
|
|
|
3397
3500
|
{ "clerkSession": [] },
|
|
3398
3501
|
{ "bearerCredential": [] },
|
|
3399
3502
|
{ "bearerGrant": [] },
|
|
3400
|
-
{ "
|
|
3503
|
+
{ "bearerOrganizationCredential": [] }
|
|
3401
3504
|
],
|
|
3402
3505
|
"x-required-scopes": ["connections:read"],
|
|
3403
3506
|
"responses": {
|
|
@@ -3476,7 +3579,7 @@
|
|
|
3476
3579
|
{ "clerkSession": [] },
|
|
3477
3580
|
{ "bearerCredential": [] },
|
|
3478
3581
|
{ "bearerGrant": [] },
|
|
3479
|
-
{ "
|
|
3582
|
+
{ "bearerOrganizationCredential": [] }
|
|
3480
3583
|
],
|
|
3481
3584
|
"x-required-scopes": ["connections:write"],
|
|
3482
3585
|
"requestBody": {
|
|
@@ -3529,7 +3632,7 @@
|
|
|
3529
3632
|
{ "clerkSession": [] },
|
|
3530
3633
|
{ "bearerCredential": [] },
|
|
3531
3634
|
{ "bearerGrant": [] },
|
|
3532
|
-
{ "
|
|
3635
|
+
{ "bearerOrganizationCredential": [] }
|
|
3533
3636
|
],
|
|
3534
3637
|
"x-required-scopes": ["connections:write"],
|
|
3535
3638
|
"responses": {
|
|
@@ -3590,7 +3693,7 @@
|
|
|
3590
3693
|
{ "clerkSession": [] },
|
|
3591
3694
|
{ "bearerCredential": [] },
|
|
3592
3695
|
{ "bearerGrant": [] },
|
|
3593
|
-
{ "
|
|
3696
|
+
{ "bearerOrganizationCredential": [] }
|
|
3594
3697
|
],
|
|
3595
3698
|
"x-required-scopes": ["connections:write"],
|
|
3596
3699
|
"responses": {
|
|
@@ -3659,7 +3762,7 @@
|
|
|
3659
3762
|
{ "clerkSession": [] },
|
|
3660
3763
|
{ "bearerCredential": [] },
|
|
3661
3764
|
{ "bearerGrant": [] },
|
|
3662
|
-
{ "
|
|
3765
|
+
{ "bearerOrganizationCredential": [] }
|
|
3663
3766
|
],
|
|
3664
3767
|
"x-required-scopes": ["connections:write"],
|
|
3665
3768
|
"x-idempotency": {
|
|
@@ -3703,13 +3806,13 @@
|
|
|
3703
3806
|
"post": {
|
|
3704
3807
|
"operationId": "restartChannelConnectionSetup",
|
|
3705
3808
|
"summary": "Start a fresh setup on a connection that never finished one",
|
|
3706
|
-
"description": "Issues a new guided setup for a `customer_managed` connection whose\nsetup expired, failed, or was simply abandoned. Nothing was ever\nprovisioned under it, no identity was claimed, and no subscriber ever\nconsented to anything through it, so nothing is lost.\n\n**Telegram reuses the connection and answers `200`.** A fresh `setup`\nappears on the same resource.\n\n**Customer-owned Slack replaces the connection and answers `201`.** The\nabandoned connection is archived and a new one is returned, carrying a\nnew `app_setup` and a new creation link. The connection cannot be\nreused, because Slack bakes this deployment's request URLs into the app\nat the moment it is created and they are not ours to change afterwards:\na second setup on one connection would mean two Slack apps answering to\none address. **Read `id` on the response** — the connection you were\npolling is now archived. A Slack app the previous attempt already\ncreated is not withdrawn and cannot be; it is the customer's, and they\ndelete it in Slack when they are ready.\n\nEntering the three app-specific values again is not a restart, and does\nnot need one. `rotate-credential` replaces them on the connection that\nalready exists.\n\nRestart takes no body. The suggested identity recorded when the\nconnection was created is what the new attempt proposes again, so a\ncaller resuming a half-finished setup cannot accidentally rename a bot\nan administrator was already looking at. A different suggestion means\na different connection.\n\nRepeating the call is safe. A setup that is still live is returned as\nit stands rather than being replaced, so two dashboard tabs converge\non one session instead of racing to strand each other's link, and only\na session that can no longer be used is exchanged for a new one.\n\nA bot the previous attempt already created is not withdrawn and cannot\nbe: Telegram exposes no way to delete a bot. The administrator keeps it\nin their own account until they retire it in BotFather, and a restart\nwalks them through creating another rather than pretending the first\nnever happened.\n\nRefusals reuse the closed Problem vocabulary and differ by\n`field_errors[].code`:\n\n- the connection did not come from guided setup, so there is no setup\n to restart — `idempotency_conflict` 409, `setup_not_managed` at `/`;\n- the connection already finished setup, or is archived, so restarting\n would offer a second identity for something subscribers may already\n be bound to — `idempotency_conflict` 409,\n `invalid_connection_transition` at `/`;\n- the provider could not be reached, so whether a new session exists is\n genuinely unknown — `provider_outcome_unknown` 502; read the\n connection before calling again;\n- the provider rate-limited the call — `provider_retryable` 503 with\n `retry_at`.\n",
|
|
3809
|
+
"description": "Issues a new guided setup for a `customer_managed` connection whose\nsetup expired, failed, or was simply abandoned. Nothing was ever\nprovisioned under it, no identity was claimed, and no subscriber ever\nconsented to anything through it, so nothing is lost.\n\n**Telegram reuses the connection and answers `200`.** A fresh `setup`\nappears on the same resource.\n\n**Customer-owned Slack replaces the connection and answers `201`.** The\nabandoned connection is archived and a new one is returned, carrying a\nnew `app_setup` and a new creation link. The connection cannot be\nreused, because Slack bakes this deployment's request URLs into the app\nat the moment it is created and they are not ours to change afterwards:\na second setup on one connection would mean two Slack apps answering to\none address. **Read `id` on the response** — the connection you were\npolling is now archived. A Slack app the previous attempt already\ncreated is not withdrawn and cannot be; it is the customer's, and they\ndelete it in Slack when they are ready.\n\nEntering the three app-specific values again is not a restart, and does\nnot need one. `rotate-credential` replaces them on the connection that\nalready exists.\n\nRestart takes no body. The suggested identity recorded when the\nconnection was created is what the new attempt proposes again, so a\ncaller resuming a half-finished setup cannot accidentally rename a bot\nan administrator was already looking at. A different suggestion means\na different connection.\n\nRepeating the call is safe. A setup that is still live is returned as\nit stands rather than being replaced, so two dashboard tabs converge\non one session instead of racing to strand each other's link, and only\na session that can no longer be used is exchanged for a new one.\n\nA bot the previous attempt already created is not withdrawn and cannot\nbe: Telegram exposes no way to delete a bot. The administrator keeps it\nin their own Telegram account until they retire it in BotFather, and a restart\nwalks them through creating another rather than pretending the first\nnever happened.\n\nRefusals reuse the closed Problem vocabulary and differ by\n`field_errors[].code`:\n\n- the connection did not come from guided setup, so there is no setup\n to restart — `idempotency_conflict` 409, `setup_not_managed` at `/`;\n- the connection already finished setup, or is archived, so restarting\n would offer a second identity for something subscribers may already\n be bound to — `idempotency_conflict` 409,\n `invalid_connection_transition` at `/`;\n- the provider could not be reached, so whether a new session exists is\n genuinely unknown — `provider_outcome_unknown` 502; read the\n connection before calling again;\n- the provider rate-limited the call — `provider_retryable` 503 with\n `retry_at`.\n",
|
|
3707
3810
|
"tags": ["Channel connections"],
|
|
3708
3811
|
"security": [
|
|
3709
3812
|
{ "clerkSession": [] },
|
|
3710
3813
|
{ "bearerCredential": [] },
|
|
3711
3814
|
{ "bearerGrant": [] },
|
|
3712
|
-
{ "
|
|
3815
|
+
{ "bearerOrganizationCredential": [] }
|
|
3713
3816
|
],
|
|
3714
3817
|
"x-required-scopes": ["connections:write"],
|
|
3715
3818
|
"x-repeat-semantics": {
|
|
@@ -3834,7 +3937,7 @@
|
|
|
3834
3937
|
{ "clerkSession": [] },
|
|
3835
3938
|
{ "bearerCredential": [] },
|
|
3836
3939
|
{ "bearerGrant": [] },
|
|
3837
|
-
{ "
|
|
3940
|
+
{ "bearerOrganizationCredential": [] }
|
|
3838
3941
|
],
|
|
3839
3942
|
"x-required-scopes": ["connections:write"],
|
|
3840
3943
|
"requestBody": {
|
|
@@ -3946,7 +4049,7 @@
|
|
|
3946
4049
|
{ "clerkSession": [] },
|
|
3947
4050
|
{ "bearerCredential": [] },
|
|
3948
4051
|
{ "bearerGrant": [] },
|
|
3949
|
-
{ "
|
|
4052
|
+
{ "bearerOrganizationCredential": [] }
|
|
3950
4053
|
],
|
|
3951
4054
|
"x-required-scopes": ["connections:write"],
|
|
3952
4055
|
"responses": {
|
|
@@ -4013,7 +4116,7 @@
|
|
|
4013
4116
|
{ "clerkSession": [] },
|
|
4014
4117
|
{ "bearerCredential": [] },
|
|
4015
4118
|
{ "bearerGrant": [] },
|
|
4016
|
-
{ "
|
|
4119
|
+
{ "bearerOrganizationCredential": [] }
|
|
4017
4120
|
],
|
|
4018
4121
|
"x-required-scopes": ["connections:write"],
|
|
4019
4122
|
"responses": {
|
|
@@ -4074,13 +4177,13 @@
|
|
|
4074
4177
|
"get": {
|
|
4075
4178
|
"operationId": "getChannelConnectionAppManifest",
|
|
4076
4179
|
"summary": "Read the generated app configuration a customer-owned setup will create",
|
|
4077
|
-
"description": "Returns the exact configuration WhooshBang generated for this\ncustomer-owned Slack setup — the scopes it will ask for, the request\nURLs it will point at, the literal manifest document, and the same\nprefilled creation link the setup already carries.\n\nIt exists so the owner can read what they are about to approve, and a\nreviewer can check it, without opening Slack or decoding a URL. It\ncarries configuration only: no
|
|
4180
|
+
"description": "Returns the exact configuration WhooshBang generated for this\ncustomer-owned Slack setup — the scopes it will ask for, the request\nURLs it will point at, the literal manifest document, and the same\nprefilled creation link the setup already carries.\n\nIt exists so the owner can read what they are about to approve, and a\nreviewer can check it, without opening Slack or decoding a URL. It\ncarries configuration only: no organization, project, or environment, no\ncredential, and no provider-native identifier.\n\nOnly a `customer_managed` Slack connection has one. Every other\nprovider and mode answers `404`, because a manifest they do not have is\nnot a manifest that is empty.\n",
|
|
4078
4181
|
"tags": ["Channel connections"],
|
|
4079
4182
|
"security": [
|
|
4080
4183
|
{ "clerkSession": [] },
|
|
4081
4184
|
{ "bearerCredential": [] },
|
|
4082
4185
|
{ "bearerGrant": [] },
|
|
4083
|
-
{ "
|
|
4186
|
+
{ "bearerOrganizationCredential": [] }
|
|
4084
4187
|
],
|
|
4085
4188
|
"x-required-scopes": ["connections:read"],
|
|
4086
4189
|
"responses": {
|
|
@@ -4187,7 +4290,7 @@
|
|
|
4187
4290
|
{ "clerkSession": [] },
|
|
4188
4291
|
{ "bearerCredential": [] },
|
|
4189
4292
|
{ "bearerGrant": [] },
|
|
4190
|
-
{ "
|
|
4293
|
+
{ "bearerOrganizationCredential": [] }
|
|
4191
4294
|
],
|
|
4192
4295
|
"x-required-scopes": ["connections:read"],
|
|
4193
4296
|
"parameters": [
|
|
@@ -4268,7 +4371,7 @@
|
|
|
4268
4371
|
{ "clerkSession": [] },
|
|
4269
4372
|
{ "bearerCredential": [] },
|
|
4270
4373
|
{ "bearerGrant": [] },
|
|
4271
|
-
{ "
|
|
4374
|
+
{ "bearerOrganizationCredential": [] }
|
|
4272
4375
|
],
|
|
4273
4376
|
"x-required-scopes": ["connections:write"],
|
|
4274
4377
|
"x-idempotency": {
|
|
@@ -4364,7 +4467,7 @@
|
|
|
4364
4467
|
{ "clerkSession": [] },
|
|
4365
4468
|
{ "bearerCredential": [] },
|
|
4366
4469
|
{ "bearerGrant": [] },
|
|
4367
|
-
{ "
|
|
4470
|
+
{ "bearerOrganizationCredential": [] }
|
|
4368
4471
|
],
|
|
4369
4472
|
"x-required-scopes": ["connections:read"],
|
|
4370
4473
|
"responses": {
|
|
@@ -4425,7 +4528,7 @@
|
|
|
4425
4528
|
{ "clerkSession": [] },
|
|
4426
4529
|
{ "bearerCredential": [] },
|
|
4427
4530
|
{ "bearerGrant": [] },
|
|
4428
|
-
{ "
|
|
4531
|
+
{ "bearerOrganizationCredential": [] }
|
|
4429
4532
|
],
|
|
4430
4533
|
"x-required-scopes": ["connections:read"],
|
|
4431
4534
|
"parameters": [
|
|
@@ -4435,7 +4538,7 @@
|
|
|
4435
4538
|
],
|
|
4436
4539
|
"responses": {
|
|
4437
4540
|
"200": {
|
|
4438
|
-
"description": "Routes owned by exactly this
|
|
4541
|
+
"description": "Routes owned by exactly this organization, project, and environment.",
|
|
4439
4542
|
"headers": {
|
|
4440
4543
|
"WhooshBang-Diagnostic-Id": {
|
|
4441
4544
|
"$ref": "#/components/headers/DiagnosticId"
|
|
@@ -4484,7 +4587,7 @@
|
|
|
4484
4587
|
{ "clerkSession": [] },
|
|
4485
4588
|
{ "bearerCredential": [] },
|
|
4486
4589
|
{ "bearerGrant": [] },
|
|
4487
|
-
{ "
|
|
4590
|
+
{ "bearerOrganizationCredential": [] }
|
|
4488
4591
|
],
|
|
4489
4592
|
"x-required-scopes": ["connections:write"],
|
|
4490
4593
|
"requestBody": {
|
|
@@ -4566,7 +4669,7 @@
|
|
|
4566
4669
|
{ "clerkSession": [] },
|
|
4567
4670
|
{ "bearerCredential": [] },
|
|
4568
4671
|
{ "bearerGrant": [] },
|
|
4569
|
-
{ "
|
|
4672
|
+
{ "bearerOrganizationCredential": [] }
|
|
4570
4673
|
],
|
|
4571
4674
|
"x-required-scopes": ["connections:write"],
|
|
4572
4675
|
"responses": {
|
|
@@ -4624,7 +4727,7 @@
|
|
|
4624
4727
|
{ "bearerCredential": [] }
|
|
4625
4728
|
],
|
|
4626
4729
|
"x-required-scopes": ["projects:read"],
|
|
4627
|
-
"x-
|
|
4730
|
+
"x-organization-membership": "required",
|
|
4628
4731
|
"responses": {
|
|
4629
4732
|
"200": {
|
|
4630
4733
|
"description": "Current constrained project recipient experience.",
|
|
@@ -4668,7 +4771,7 @@
|
|
|
4668
4771
|
{ "bearerCredential": [] }
|
|
4669
4772
|
],
|
|
4670
4773
|
"x-required-scopes": ["projects:write"],
|
|
4671
|
-
"x-
|
|
4774
|
+
"x-organization-membership": "required",
|
|
4672
4775
|
"requestBody": {
|
|
4673
4776
|
"required": true,
|
|
4674
4777
|
"content": {
|
|
@@ -4725,7 +4828,7 @@
|
|
|
4725
4828
|
{ "bearerCredential": [] }
|
|
4726
4829
|
],
|
|
4727
4830
|
"x-required-scopes": ["projects:write"],
|
|
4728
|
-
"x-
|
|
4831
|
+
"x-organization-membership": "required",
|
|
4729
4832
|
"parameters": [
|
|
4730
4833
|
{
|
|
4731
4834
|
"name": "WhooshBang-Recipient-Experience-Version",
|
|
@@ -4779,10 +4882,10 @@
|
|
|
4779
4882
|
{ "clerkSession": [] },
|
|
4780
4883
|
{ "bearerGrant": [] },
|
|
4781
4884
|
{ "bearerCredential": [] },
|
|
4782
|
-
{ "
|
|
4885
|
+
{ "bearerOrganizationCredential": [] }
|
|
4783
4886
|
],
|
|
4784
4887
|
"x-required-scopes": ["projects:read"],
|
|
4785
|
-
"x-
|
|
4888
|
+
"x-organization-membership": "required",
|
|
4786
4889
|
"responses": {
|
|
4787
4890
|
"200": {
|
|
4788
4891
|
"description": "Current revisioned environment recipient experience.",
|
|
@@ -4828,10 +4931,10 @@
|
|
|
4828
4931
|
{ "clerkSession": [] },
|
|
4829
4932
|
{ "bearerGrant": [] },
|
|
4830
4933
|
{ "bearerCredential": [] },
|
|
4831
|
-
{ "
|
|
4934
|
+
{ "bearerOrganizationCredential": [] }
|
|
4832
4935
|
],
|
|
4833
4936
|
"x-required-scopes": ["projects:write"],
|
|
4834
|
-
"x-
|
|
4937
|
+
"x-organization-membership": "required",
|
|
4835
4938
|
"requestBody": {
|
|
4836
4939
|
"required": true,
|
|
4837
4940
|
"content": {
|
|
@@ -4880,7 +4983,7 @@
|
|
|
4880
4983
|
"post": {
|
|
4881
4984
|
"operationId": "createRecipientSession",
|
|
4882
4985
|
"summary": "Create one attenuated recipient browser session",
|
|
4883
|
-
"description": "The authenticated project credential supplies
|
|
4986
|
+
"description": "The authenticated project credential supplies organization, project, and\nenvironment. The request supplies only one subscriber, optional locale,\noptional registered return key, and bounded expiry. The response is the\nonly reveal of the browser capability and contains no resolved return\nURL, provider identity, group state, or application credential.\n",
|
|
4884
4987
|
"tags": ["Recipient experience"],
|
|
4885
4988
|
"security": [{ "bearerCredential": [] }],
|
|
4886
4989
|
"x-required-scopes": ["subscriptions:write"],
|
|
@@ -4983,7 +5086,7 @@
|
|
|
4983
5086
|
"delete": {
|
|
4984
5087
|
"operationId": "revokeRecipientSession",
|
|
4985
5088
|
"summary": "Revoke one recipient browser session",
|
|
4986
|
-
"description": "Immediately and terminally ends the session selected inside the\nauthenticated project environment. The browser capability stops\nworking, and any independently issued provider handoff that has not\nalready been consumed stops yielding an authorization link.\n\nRepeating the request is safe. An already revoked, absent, or\nout-of-scope session produces the same empty response, so this route\ncannot be used to enumerate session identifiers across environments or\
|
|
5089
|
+
"description": "Immediately and terminally ends the session selected inside the\nauthenticated project environment. The browser capability stops\nworking, and any independently issued provider handoff that has not\nalready been consumed stops yielding an authorization link.\n\nRepeating the request is safe. An already revoked, absent, or\nout-of-scope session produces the same empty response, so this route\ncannot be used to enumerate session identifiers across environments or\norganizations.\n",
|
|
4987
5090
|
"tags": ["Recipient experience"],
|
|
4988
5091
|
"security": [{ "bearerCredential": [] }],
|
|
4989
5092
|
"x-required-scopes": ["subscriptions:write"],
|
|
@@ -5332,7 +5435,7 @@
|
|
|
5332
5435
|
"value": {
|
|
5333
5436
|
"subscriber_id": "user_123",
|
|
5334
5437
|
"locale": "es",
|
|
5335
|
-
"groups": ["
|
|
5438
|
+
"groups": ["organization-updates", "trial-users"]
|
|
5336
5439
|
}
|
|
5337
5440
|
}
|
|
5338
5441
|
}
|
|
@@ -5471,7 +5574,7 @@
|
|
|
5471
5574
|
"value": {
|
|
5472
5575
|
"key": "trial-users",
|
|
5473
5576
|
"display_name": "Trial users",
|
|
5474
|
-
"description": "
|
|
5577
|
+
"description": "Organizations currently evaluating Acme."
|
|
5475
5578
|
}
|
|
5476
5579
|
}
|
|
5477
5580
|
}
|
|
@@ -5492,7 +5595,7 @@
|
|
|
5492
5595
|
"environment": "test",
|
|
5493
5596
|
"key": "trial-users",
|
|
5494
5597
|
"display_name": "Trial users",
|
|
5495
|
-
"description": "
|
|
5598
|
+
"description": "Organizations currently evaluating Acme.",
|
|
5496
5599
|
"status": "active",
|
|
5497
5600
|
"membership_revision": 1,
|
|
5498
5601
|
"row_version": 1,
|
|
@@ -6002,14 +6105,17 @@
|
|
|
6002
6105
|
"post": {
|
|
6003
6106
|
"operationId": "createSubscriptionLinkInEnvironment",
|
|
6004
6107
|
"summary": "Create a subscription link in a named project environment",
|
|
6005
|
-
"description": "The environment-scoped form of `createSubscriptionLink`, for a caller\nwhose authority selects an
|
|
6108
|
+
"description": "The environment-scoped form of `createSubscriptionLink`, for a caller\nwhose authority selects an organization rather than a project. Behavior,\nrequest, and response are identical; the path names the scope the\ncredential form takes from its bearer, and the service checks it\nagainst the granting person's membership before acting.\n",
|
|
6006
6109
|
"tags": ["Subscription links"],
|
|
6007
|
-
"security": [
|
|
6110
|
+
"security": [
|
|
6111
|
+
{ "bearerGrant": [] },
|
|
6112
|
+
{ "bearerOrganizationCredential": [] }
|
|
6113
|
+
],
|
|
6008
6114
|
"x-required-scopes": ["subscriptions:write"],
|
|
6009
6115
|
"x-idempotency": {
|
|
6010
6116
|
"required": true,
|
|
6011
6117
|
"retention_seconds": 604800,
|
|
6012
|
-
"scope": ["
|
|
6118
|
+
"scope": ["authenticated_organization", "operation_id", "key"],
|
|
6013
6119
|
"equivalence": "validated_request",
|
|
6014
6120
|
"replay_retention_extends": false
|
|
6015
6121
|
},
|
|
@@ -6086,7 +6192,10 @@
|
|
|
6086
6192
|
"summary": "Inspect a subscription link in a named project environment",
|
|
6087
6193
|
"description": "The environment-scoped form of `getSubscriptionLink`. A link outside the\nnamed environment is absent, exactly as it is for a credential.\n",
|
|
6088
6194
|
"tags": ["Subscription links"],
|
|
6089
|
-
"security": [
|
|
6195
|
+
"security": [
|
|
6196
|
+
{ "bearerGrant": [] },
|
|
6197
|
+
{ "bearerOrganizationCredential": [] }
|
|
6198
|
+
],
|
|
6090
6199
|
"x-required-scopes": ["subscriptions:read"],
|
|
6091
6200
|
"responses": {
|
|
6092
6201
|
"200": {
|
|
@@ -6154,14 +6263,17 @@
|
|
|
6154
6263
|
"post": {
|
|
6155
6264
|
"operationId": "createMessageInEnvironment",
|
|
6156
6265
|
"summary": "Create an asynchronous message in a named project environment",
|
|
6157
|
-
"description": "The environment-scoped form of `createMessage`. The path names the\
|
|
6266
|
+
"description": "The environment-scoped form of `createMessage`. The path names the\norganization, project, and environment the credential form takes from its\nbearer; test and live remain a property of the named environment and are\nnever selected by the request body.\n",
|
|
6158
6267
|
"tags": ["Messages"],
|
|
6159
|
-
"security": [
|
|
6268
|
+
"security": [
|
|
6269
|
+
{ "bearerGrant": [] },
|
|
6270
|
+
{ "bearerOrganizationCredential": [] }
|
|
6271
|
+
],
|
|
6160
6272
|
"x-required-scopes": ["messages:write"],
|
|
6161
6273
|
"x-idempotency": {
|
|
6162
6274
|
"required": true,
|
|
6163
6275
|
"retention_seconds": 604800,
|
|
6164
|
-
"scope": ["
|
|
6276
|
+
"scope": ["authenticated_organization", "operation_id", "key"],
|
|
6165
6277
|
"equivalence": "validated_request",
|
|
6166
6278
|
"replay_retention_extends": false
|
|
6167
6279
|
},
|
|
@@ -6245,7 +6357,10 @@
|
|
|
6245
6357
|
{ "$ref": "#/components/parameters/ResponseInspectionWait" }
|
|
6246
6358
|
],
|
|
6247
6359
|
"tags": ["Messages"],
|
|
6248
|
-
"security": [
|
|
6360
|
+
"security": [
|
|
6361
|
+
{ "bearerGrant": [] },
|
|
6362
|
+
{ "bearerOrganizationCredential": [] }
|
|
6363
|
+
],
|
|
6249
6364
|
"x-required-scopes": ["messages:read"],
|
|
6250
6365
|
"responses": {
|
|
6251
6366
|
"200": {
|
|
@@ -6316,7 +6431,10 @@
|
|
|
6316
6431
|
{ "$ref": "#/components/parameters/ResponseInspectionWait" }
|
|
6317
6432
|
],
|
|
6318
6433
|
"tags": ["Messages"],
|
|
6319
|
-
"security": [
|
|
6434
|
+
"security": [
|
|
6435
|
+
{ "bearerGrant": [] },
|
|
6436
|
+
{ "bearerOrganizationCredential": [] }
|
|
6437
|
+
],
|
|
6320
6438
|
"x-required-scopes": ["messages:read"],
|
|
6321
6439
|
"responses": {
|
|
6322
6440
|
"200": {
|
|
@@ -6364,12 +6482,15 @@
|
|
|
6364
6482
|
"summary": "Create a destination-bound machine client in a named project environment",
|
|
6365
6483
|
"description": "The environment-scoped form of `createMachineClient`. Scope remains the\nexact bound destination; the path only names where the client is created.\n",
|
|
6366
6484
|
"tags": ["Machine clients"],
|
|
6367
|
-
"security": [
|
|
6485
|
+
"security": [
|
|
6486
|
+
{ "bearerGrant": [] },
|
|
6487
|
+
{ "bearerOrganizationCredential": [] }
|
|
6488
|
+
],
|
|
6368
6489
|
"x-required-scopes": ["machine-clients:write"],
|
|
6369
6490
|
"x-idempotency": {
|
|
6370
6491
|
"required": true,
|
|
6371
6492
|
"retention_seconds": 604800,
|
|
6372
|
-
"scope": ["
|
|
6493
|
+
"scope": ["authenticated_organization", "operation_id", "key"],
|
|
6373
6494
|
"equivalence": "validated_request",
|
|
6374
6495
|
"replay_retention_extends": false
|
|
6375
6496
|
},
|
|
@@ -6442,7 +6563,10 @@
|
|
|
6442
6563
|
"summary": "Register a machine-credential digest in a named project environment",
|
|
6443
6564
|
"description": "The environment-scoped form of `registerMachineCredential`. Registers\nonly the credential ID and SHA-256 digest; the path only names where the\nowning machine client lives. Request and response shapes are that\noperation's exactly, including its published examples.\n",
|
|
6444
6565
|
"tags": ["Machine clients"],
|
|
6445
|
-
"security": [
|
|
6566
|
+
"security": [
|
|
6567
|
+
{ "bearerGrant": [] },
|
|
6568
|
+
{ "bearerOrganizationCredential": [] }
|
|
6569
|
+
],
|
|
6446
6570
|
"x-required-scopes": ["machine-clients:write"],
|
|
6447
6571
|
"x-idempotency": {
|
|
6448
6572
|
"required": true,
|
|
@@ -6508,7 +6632,10 @@
|
|
|
6508
6632
|
"summary": "Inspect provider-neutral capabilities for a named project environment",
|
|
6509
6633
|
"description": "The environment-scoped form of `getCapabilities`. The vocabulary is\nprovider-neutral and identical; the path names the environment whose\nactive degradation is reported.\n",
|
|
6510
6634
|
"tags": ["Capabilities"],
|
|
6511
|
-
"security": [
|
|
6635
|
+
"security": [
|
|
6636
|
+
{ "bearerGrant": [] },
|
|
6637
|
+
{ "bearerOrganizationCredential": [] }
|
|
6638
|
+
],
|
|
6512
6639
|
"x-required-scopes": ["capabilities:read"],
|
|
6513
6640
|
"responses": {
|
|
6514
6641
|
"200": {
|
|
@@ -6590,13 +6717,13 @@
|
|
|
6590
6717
|
"post": {
|
|
6591
6718
|
"operationId": "createSubscriberInEnvironment",
|
|
6592
6719
|
"summary": "Create a subscriber and initial memberships in a named project environment",
|
|
6593
|
-
"description": "The environment-scoped form of `createSubscriber`, for a caller whose\nauthority selects an
|
|
6720
|
+
"description": "The environment-scoped form of `createSubscriber`, for a caller whose\nauthority selects an organization rather than a project. Behavior, request,\nand response are identical; the path names the scope the credential\nform takes from its bearer, and the service checks it against the\npresenting session or grant before acting.\n",
|
|
6594
6721
|
"tags": ["Subscribers"],
|
|
6595
6722
|
"security": [
|
|
6596
6723
|
{ "clerkSession": [] },
|
|
6597
6724
|
{ "bearerCredential": [] },
|
|
6598
6725
|
{ "bearerGrant": [] },
|
|
6599
|
-
{ "
|
|
6726
|
+
{ "bearerOrganizationCredential": [] }
|
|
6600
6727
|
],
|
|
6601
6728
|
"x-required-scopes": ["subscriptions:write"],
|
|
6602
6729
|
"x-idempotency": {
|
|
@@ -6619,7 +6746,7 @@
|
|
|
6619
6746
|
"value": {
|
|
6620
6747
|
"subscriber_id": "user_123",
|
|
6621
6748
|
"locale": "es",
|
|
6622
|
-
"groups": ["
|
|
6749
|
+
"groups": ["organization-updates", "trial-users"]
|
|
6623
6750
|
}
|
|
6624
6751
|
}
|
|
6625
6752
|
}
|
|
@@ -6674,7 +6801,7 @@
|
|
|
6674
6801
|
{ "clerkSession": [] },
|
|
6675
6802
|
{ "bearerCredential": [] },
|
|
6676
6803
|
{ "bearerGrant": [] },
|
|
6677
|
-
{ "
|
|
6804
|
+
{ "bearerOrganizationCredential": [] }
|
|
6678
6805
|
],
|
|
6679
6806
|
"x-required-scopes": ["subscriptions:read"],
|
|
6680
6807
|
"responses": {
|
|
@@ -6692,6 +6819,97 @@
|
|
|
6692
6819
|
}
|
|
6693
6820
|
}
|
|
6694
6821
|
},
|
|
6822
|
+
"/v1/projects/{project_id}/subscribers/{subscriber_id}": {
|
|
6823
|
+
"parameters": [
|
|
6824
|
+
{ "$ref": "#/components/parameters/ProjectId" },
|
|
6825
|
+
{
|
|
6826
|
+
"name": "subscriber_id",
|
|
6827
|
+
"in": "path",
|
|
6828
|
+
"required": true,
|
|
6829
|
+
"schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
|
|
6830
|
+
}
|
|
6831
|
+
],
|
|
6832
|
+
"delete": {
|
|
6833
|
+
"operationId": "eraseSubscriber",
|
|
6834
|
+
"summary": "Erase one subscriber across the project",
|
|
6835
|
+
"description": "Erases the person represented by this customer-supplied subscriber id\nacross both project environments. Personal content, answers, identities,\nand identifiers are removed while non-identifying delivery and usage\nshells remain. Pending work and old capabilities cannot restore or send\ndata for the erased person.\n\nRepeating the operation is safe, including when the subscriber is already\nabsent. Project-environment credentials cannot call this project-wide\noperation. A provider action that has already begun returns\n`privacy_operation_in_progress` rather than claiming erasure won the race;\nretry after that operation finishes.\n",
|
|
6836
|
+
"tags": ["Subscribers"],
|
|
6837
|
+
"security": [
|
|
6838
|
+
{ "clerkSession": [] },
|
|
6839
|
+
{ "bearerGrant": [] },
|
|
6840
|
+
{ "bearerOrganizationCredential": [] }
|
|
6841
|
+
],
|
|
6842
|
+
"x-required-scopes": [
|
|
6843
|
+
"subscriptions:write",
|
|
6844
|
+
"messages:write",
|
|
6845
|
+
"machine-clients:write"
|
|
6846
|
+
],
|
|
6847
|
+
"x-organization-membership": "required",
|
|
6848
|
+
"x-repeat-semantics": {
|
|
6849
|
+
"same_target": "idempotent",
|
|
6850
|
+
"secret_returned": false
|
|
6851
|
+
},
|
|
6852
|
+
"responses": {
|
|
6853
|
+
"204": {
|
|
6854
|
+
"description": "The subscriber's personal data is erased or was already absent."
|
|
6855
|
+
},
|
|
6856
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
6857
|
+
"403": { "$ref": "#/components/responses/Forbidden" },
|
|
6858
|
+
"404": { "$ref": "#/components/responses/NotFound" },
|
|
6859
|
+
"409": { "$ref": "#/components/responses/Conflict" },
|
|
6860
|
+
"429": { "$ref": "#/components/responses/RateLimited" }
|
|
6861
|
+
}
|
|
6862
|
+
}
|
|
6863
|
+
},
|
|
6864
|
+
"/v1/projects/{project_id}/subscribers/{subscriber_id}/data-export": {
|
|
6865
|
+
"parameters": [
|
|
6866
|
+
{ "$ref": "#/components/parameters/ProjectId" },
|
|
6867
|
+
{
|
|
6868
|
+
"name": "subscriber_id",
|
|
6869
|
+
"in": "path",
|
|
6870
|
+
"required": true,
|
|
6871
|
+
"schema": { "$ref": "#/components/schemas/OpaqueIdentifier" }
|
|
6872
|
+
}
|
|
6873
|
+
],
|
|
6874
|
+
"get": {
|
|
6875
|
+
"operationId": "getSubscriberDataExport",
|
|
6876
|
+
"summary": "Export all customer-controlled data held for one subscriber",
|
|
6877
|
+
"description": "Returns one complete, machine-readable artifact across every environment\nin the project. `provided_by_subscriber` is the Article 20 portable subset;\nthe three provenance sections together provide the Article 15 access copy.\nWhooshBang-controller audit and service log data is identified as excluded\nand requires a separate recipient request. Project-environment credentials\ncannot call this project-wide operation.\n",
|
|
6878
|
+
"tags": ["Subscribers"],
|
|
6879
|
+
"security": [
|
|
6880
|
+
{ "clerkSession": [] },
|
|
6881
|
+
{ "bearerGrant": [] },
|
|
6882
|
+
{ "bearerOrganizationCredential": [] }
|
|
6883
|
+
],
|
|
6884
|
+
"x-required-scopes": [
|
|
6885
|
+
"subscriptions:read",
|
|
6886
|
+
"messages:read",
|
|
6887
|
+
"machine-clients:read"
|
|
6888
|
+
],
|
|
6889
|
+
"x-organization-membership": "required",
|
|
6890
|
+
"responses": {
|
|
6891
|
+
"200": {
|
|
6892
|
+
"description": "Complete project-wide customer-controller subscriber data export.",
|
|
6893
|
+
"headers": {
|
|
6894
|
+
"Content-Disposition": {
|
|
6895
|
+
"schema": { "type": "string" },
|
|
6896
|
+
"description": "Fixed safe attachment filename."
|
|
6897
|
+
}
|
|
6898
|
+
},
|
|
6899
|
+
"content": {
|
|
6900
|
+
"application/json": {
|
|
6901
|
+
"schema": {
|
|
6902
|
+
"$ref": "#/components/schemas/SubscriberDataExport"
|
|
6903
|
+
}
|
|
6904
|
+
}
|
|
6905
|
+
}
|
|
6906
|
+
},
|
|
6907
|
+
"401": { "$ref": "#/components/responses/Unauthorized" },
|
|
6908
|
+
"403": { "$ref": "#/components/responses/Forbidden" },
|
|
6909
|
+
"404": { "$ref": "#/components/responses/NotFound" }
|
|
6910
|
+
}
|
|
6911
|
+
}
|
|
6912
|
+
},
|
|
6695
6913
|
"/v1/projects/{project_id}/environments/{environment_id}/recipient-groups": {
|
|
6696
6914
|
"parameters": [
|
|
6697
6915
|
{ "$ref": "#/components/parameters/ProjectId" },
|
|
@@ -6706,7 +6924,7 @@
|
|
|
6706
6924
|
{ "clerkSession": [] },
|
|
6707
6925
|
{ "bearerCredential": [] },
|
|
6708
6926
|
{ "bearerGrant": [] },
|
|
6709
|
-
{ "
|
|
6927
|
+
{ "bearerOrganizationCredential": [] }
|
|
6710
6928
|
],
|
|
6711
6929
|
"x-required-scopes": ["subscriptions:read"],
|
|
6712
6930
|
"parameters": [
|
|
@@ -6759,7 +6977,7 @@
|
|
|
6759
6977
|
{ "clerkSession": [] },
|
|
6760
6978
|
{ "bearerCredential": [] },
|
|
6761
6979
|
{ "bearerGrant": [] },
|
|
6762
|
-
{ "
|
|
6980
|
+
{ "bearerOrganizationCredential": [] }
|
|
6763
6981
|
],
|
|
6764
6982
|
"x-required-scopes": ["subscriptions:write"],
|
|
6765
6983
|
"x-idempotency": {
|
|
@@ -6782,7 +7000,7 @@
|
|
|
6782
7000
|
"value": {
|
|
6783
7001
|
"key": "trial-users",
|
|
6784
7002
|
"display_name": "Trial users",
|
|
6785
|
-
"description": "
|
|
7003
|
+
"description": "Organizations currently evaluating Acme."
|
|
6786
7004
|
}
|
|
6787
7005
|
}
|
|
6788
7006
|
}
|
|
@@ -6803,7 +7021,7 @@
|
|
|
6803
7021
|
"environment": "test",
|
|
6804
7022
|
"key": "trial-users",
|
|
6805
7023
|
"display_name": "Trial users",
|
|
6806
|
-
"description": "
|
|
7024
|
+
"description": "Organizations currently evaluating Acme.",
|
|
6807
7025
|
"status": "active",
|
|
6808
7026
|
"membership_revision": 1,
|
|
6809
7027
|
"row_version": 1,
|
|
@@ -6848,7 +7066,7 @@
|
|
|
6848
7066
|
{ "clerkSession": [] },
|
|
6849
7067
|
{ "bearerCredential": [] },
|
|
6850
7068
|
{ "bearerGrant": [] },
|
|
6851
|
-
{ "
|
|
7069
|
+
{ "bearerOrganizationCredential": [] }
|
|
6852
7070
|
],
|
|
6853
7071
|
"x-required-scopes": ["subscriptions:read"],
|
|
6854
7072
|
"responses": {
|
|
@@ -6874,7 +7092,7 @@
|
|
|
6874
7092
|
{ "clerkSession": [] },
|
|
6875
7093
|
{ "bearerCredential": [] },
|
|
6876
7094
|
{ "bearerGrant": [] },
|
|
6877
|
-
{ "
|
|
7095
|
+
{ "bearerOrganizationCredential": [] }
|
|
6878
7096
|
],
|
|
6879
7097
|
"x-required-scopes": ["subscriptions:write"],
|
|
6880
7098
|
"requestBody": {
|
|
@@ -6912,7 +7130,7 @@
|
|
|
6912
7130
|
{ "clerkSession": [] },
|
|
6913
7131
|
{ "bearerCredential": [] },
|
|
6914
7132
|
{ "bearerGrant": [] },
|
|
6915
|
-
{ "
|
|
7133
|
+
{ "bearerOrganizationCredential": [] }
|
|
6916
7134
|
],
|
|
6917
7135
|
"x-required-scopes": ["subscriptions:write"],
|
|
6918
7136
|
"responses": {
|
|
@@ -6955,7 +7173,7 @@
|
|
|
6955
7173
|
{ "clerkSession": [] },
|
|
6956
7174
|
{ "bearerCredential": [] },
|
|
6957
7175
|
{ "bearerGrant": [] },
|
|
6958
|
-
{ "
|
|
7176
|
+
{ "bearerOrganizationCredential": [] }
|
|
6959
7177
|
],
|
|
6960
7178
|
"x-required-scopes": ["subscriptions:read"],
|
|
6961
7179
|
"parameters": [
|
|
@@ -7056,7 +7274,7 @@
|
|
|
7056
7274
|
{ "clerkSession": [] },
|
|
7057
7275
|
{ "bearerCredential": [] },
|
|
7058
7276
|
{ "bearerGrant": [] },
|
|
7059
|
-
{ "
|
|
7277
|
+
{ "bearerOrganizationCredential": [] }
|
|
7060
7278
|
],
|
|
7061
7279
|
"x-required-scopes": ["subscriptions:write"],
|
|
7062
7280
|
"responses": {
|
|
@@ -7100,7 +7318,7 @@
|
|
|
7100
7318
|
{ "clerkSession": [] },
|
|
7101
7319
|
{ "bearerCredential": [] },
|
|
7102
7320
|
{ "bearerGrant": [] },
|
|
7103
|
-
{ "
|
|
7321
|
+
{ "bearerOrganizationCredential": [] }
|
|
7104
7322
|
],
|
|
7105
7323
|
"x-required-scopes": ["subscriptions:write"],
|
|
7106
7324
|
"responses": {
|
|
@@ -7139,7 +7357,7 @@
|
|
|
7139
7357
|
{ "clerkSession": [] },
|
|
7140
7358
|
{ "bearerCredential": [] },
|
|
7141
7359
|
{ "bearerGrant": [] },
|
|
7142
|
-
{ "
|
|
7360
|
+
{ "bearerOrganizationCredential": [] }
|
|
7143
7361
|
],
|
|
7144
7362
|
"x-required-scopes": ["messages:write"],
|
|
7145
7363
|
"x-idempotency": {
|
|
@@ -7238,7 +7456,7 @@
|
|
|
7238
7456
|
{ "clerkSession": [] },
|
|
7239
7457
|
{ "bearerCredential": [] },
|
|
7240
7458
|
{ "bearerGrant": [] },
|
|
7241
|
-
{ "
|
|
7459
|
+
{ "bearerOrganizationCredential": [] }
|
|
7242
7460
|
],
|
|
7243
7461
|
"x-required-scopes": ["messages:read"],
|
|
7244
7462
|
"responses": {
|
|
@@ -7291,25 +7509,25 @@
|
|
|
7291
7509
|
"type": "http",
|
|
7292
7510
|
"scheme": "bearer",
|
|
7293
7511
|
"bearerFormat": "Clerk session JWT",
|
|
7294
|
-
"description": "A verified human session whose active Clerk organization selects exactly\none WhooshBang
|
|
7512
|
+
"description": "A verified human session whose active Clerk organization selects exactly\none WhooshBang organization. Every administration operation rechecks the\nprojected organization membership; session identity never selects a project\nor environment from request data.\n"
|
|
7295
7513
|
},
|
|
7296
7514
|
"bearerGrant": {
|
|
7297
7515
|
"type": "http",
|
|
7298
7516
|
"scheme": "bearer",
|
|
7299
7517
|
"bearerFormat": "OAuth 2.0 access token",
|
|
7300
|
-
"description": "An access token issued by the WhooshBang authorization server for one\nconsenting
|
|
7518
|
+
"description": "An access token issued by the WhooshBang authorization server for one\nconsenting organization member. It selects exactly one organization and carries\nthe scopes that member consented to, and never a project: an operation\nnames its project and environment in the path, and the service checks\nboth against the granting person's membership before acting. A project\ncredential can name no project but its own; an organization credential names\none per call the same way this does.\n"
|
|
7301
7519
|
},
|
|
7302
|
-
"
|
|
7520
|
+
"bearerOrganizationCredential": {
|
|
7303
7521
|
"type": "http",
|
|
7304
7522
|
"scheme": "bearer",
|
|
7305
|
-
"bearerFormat": "
|
|
7306
|
-
"description": "Selects exactly one
|
|
7523
|
+
"bearerFormat": "wb_oc1.ocred_<16-byte-base64url>.<32-byte-base64url-secret>",
|
|
7524
|
+
"description": "Selects exactly one organization and nothing below it. It names no project\nand no environment, so it authenticates only operations whose path does,\nand its authority there is the intersection of its scopes with the\nproject-credential vocabulary — never wider than a project credential\nwould have been for the same project environment. A path naming a\nproject outside its organization is refused with `credential_organization_mismatch`\nrather than a bare scope failure. `organization:read` is the one scope it can\nhold that a project credential cannot, and it authorizes only the\norganization's project directory: listing the organization's projects and reading\none, which is the organization-wide question a project credential cannot ask\nand the reason a `--project <slug>` selector can work at all. It is\nrequired *in addition to* each of those operations' own\n`x-required-scopes`, never instead of them.\nCredentials cannot be read after creation.\n"
|
|
7307
7525
|
},
|
|
7308
7526
|
"bearerCredential": {
|
|
7309
7527
|
"type": "http",
|
|
7310
7528
|
"scheme": "bearer",
|
|
7311
7529
|
"bearerFormat": "wb_pc1.pcred_<16-byte-base64url>.<32-byte-base64url-secret>",
|
|
7312
|
-
"description": "Selects exactly one
|
|
7530
|
+
"description": "Selects exactly one organization, project, and `test` or `live` environment.\nCredentials cannot be read after creation. Except for explicitly\nsynthetic creation/rotation reveal fixtures, complete bearer values\nmust never appear in fixtures, errors, logs, metrics, or inspection\nsurfaces.\n"
|
|
7313
7531
|
},
|
|
7314
7532
|
"machineCredential": {
|
|
7315
7533
|
"type": "http",
|
|
@@ -7321,7 +7539,7 @@
|
|
|
7321
7539
|
"type": "apiKey",
|
|
7322
7540
|
"in": "header",
|
|
7323
7541
|
"name": "WhooshBang-Recipient-Capability",
|
|
7324
|
-
"description": "A creation-only, short-lived capability bound server-side to one exact\
|
|
7542
|
+
"description": "A creation-only, short-lived capability bound server-side to one exact\norganization, project, environment, subscriber, configuration revision,\npresenting origin, and registered return destination. It is accepted\nonly on the `/v1/recipient-session` browser surface and never as bearer\nauthority on an ordinary application route.\n"
|
|
7325
7543
|
}
|
|
7326
7544
|
},
|
|
7327
7545
|
"parameters": {
|
|
@@ -7360,12 +7578,12 @@
|
|
|
7360
7578
|
"description": "Canonical opaque project credential identity; never a readable secret.",
|
|
7361
7579
|
"schema": { "$ref": "#/components/schemas/ApiCredentialId" }
|
|
7362
7580
|
},
|
|
7363
|
-
"
|
|
7364
|
-
"name": "
|
|
7581
|
+
"OrganizationCredentialId": {
|
|
7582
|
+
"name": "organization_credential_id",
|
|
7365
7583
|
"in": "path",
|
|
7366
7584
|
"required": true,
|
|
7367
|
-
"description": "Canonical opaque
|
|
7368
|
-
"schema": { "$ref": "#/components/schemas/
|
|
7585
|
+
"description": "Canonical opaque organization credential identity; never a readable secret.",
|
|
7586
|
+
"schema": { "$ref": "#/components/schemas/OrganizationCredentialId" }
|
|
7369
7587
|
},
|
|
7370
7588
|
"ApiCredentialAfterCursor": {
|
|
7371
7589
|
"name": "after",
|
|
@@ -7767,7 +7985,7 @@
|
|
|
7767
7985
|
"additionalProperties": false
|
|
7768
7986
|
},
|
|
7769
7987
|
"CreateChannelConnectionRequest": {
|
|
7770
|
-
"description": "Selects the provider identity this environment will send through, discriminated on `mode`, and naming the provider it is for. The two customer-owned modes differ only in where the bot comes from: `customer_byok` connects one the customer already has, and `customer_managed` has Telegram create a new one on the administrator's own account. Neither supersedes the other, because a bot that already exists can never be adopted into managed mode — the manager that may act for a bot is fixed when the bot is created.",
|
|
7988
|
+
"description": "Selects the provider identity this environment will send through, discriminated on `mode`, and naming the provider it is for. The two customer-owned modes differ only in where the bot comes from: `customer_byok` connects one the customer already has, and `customer_managed` has Telegram create a new one on the administrator's own Telegram account. Neither supersedes the other, because a bot that already exists can never be adopted into managed mode — the manager that may act for a bot is fixed when the bot is created.",
|
|
7771
7989
|
"oneOf": [
|
|
7772
7990
|
{
|
|
7773
7991
|
"type": "object",
|
|
@@ -8145,7 +8363,7 @@
|
|
|
8145
8363
|
},
|
|
8146
8364
|
"CustomerOwnedSlackAppManifest": {
|
|
8147
8365
|
"type": "object",
|
|
8148
|
-
"description": "The exact configuration a customer-owned Slack app is created from, as data rather than as a URL-encoded blob.\n\nIt exists so the owner can read what they are about to approve, and so a reviewer can check it, without opening Slack. It carries configuration only: no
|
|
8366
|
+
"description": "The exact configuration a customer-owned Slack app is created from, as data rather than as a URL-encoded blob.\n\nIt exists so the owner can read what they are about to approve, and so a reviewer can check it, without opening Slack. It carries configuration only: no organization, project, or environment, no credential, and no provider-native identifier. The opaque handle inside the request URLs selects candidate setup state and authorizes nothing — a request still has to carry Slack's signature over the untouched body before anything inside it is believed.",
|
|
8149
8367
|
"required": [
|
|
8150
8368
|
"creation_url",
|
|
8151
8369
|
"app_name",
|
|
@@ -8303,7 +8521,7 @@
|
|
|
8303
8521
|
"pattern": "^[!-~]+$",
|
|
8304
8522
|
"description": "Visible ASCII, scoped by authenticated environment, operation ID, and key, and retained for seven days from first acceptance."
|
|
8305
8523
|
},
|
|
8306
|
-
"
|
|
8524
|
+
"OrganizationProjection": {
|
|
8307
8525
|
"type": "object",
|
|
8308
8526
|
"description": "The current Clerk organization projected as a WhooshBang tenant. Clerk organization and user identifiers are not public fields.",
|
|
8309
8527
|
"required": [
|
|
@@ -8320,7 +8538,7 @@
|
|
|
8320
8538
|
"name": { "type": "string", "minLength": 1, "maxLength": 100 },
|
|
8321
8539
|
"status": { "type": "string", "enum": ["active", "suspended"] },
|
|
8322
8540
|
"membership": {
|
|
8323
|
-
"$ref": "#/components/schemas/
|
|
8541
|
+
"$ref": "#/components/schemas/OrganizationMembershipSummary"
|
|
8324
8542
|
},
|
|
8325
8543
|
"created_at": { "$ref": "#/components/schemas/Timestamp" },
|
|
8326
8544
|
"updated_at": { "$ref": "#/components/schemas/Timestamp" },
|
|
@@ -8328,9 +8546,23 @@
|
|
|
8328
8546
|
},
|
|
8329
8547
|
"additionalProperties": false
|
|
8330
8548
|
},
|
|
8549
|
+
"UpdateProjectRequest": {
|
|
8550
|
+
"type": "object",
|
|
8551
|
+
"description": "Sets the project privacy policy. Moving from standard to minimal erases stored identifying profile data; moving to private also erases recipient language. Increasing collection does not restore erased data.",
|
|
8552
|
+
"required": ["privacy_mode"],
|
|
8553
|
+
"properties": {
|
|
8554
|
+
"privacy_mode": { "$ref": "#/components/schemas/PrivacyMode" }
|
|
8555
|
+
},
|
|
8556
|
+
"additionalProperties": false
|
|
8557
|
+
},
|
|
8558
|
+
"PrivacyMode": {
|
|
8559
|
+
"type": "string",
|
|
8560
|
+
"enum": ["minimal", "standard", "private"],
|
|
8561
|
+
"description": "Project profile collection policy. minimal (the default for new and existing projects) keeps recipient language only; standard permits messenger profile data; private retains delivery routing and the customer-supplied subscriber identifier, with no profile data. Lowering collection erases existing fields the new mode disallows."
|
|
8562
|
+
},
|
|
8331
8563
|
"CreateProjectRequest": {
|
|
8332
8564
|
"type": "object",
|
|
8333
|
-
"description": "Creates one project inside the
|
|
8565
|
+
"description": "Creates one project inside the organization selected by the authenticated human session.",
|
|
8334
8566
|
"required": ["name", "slug"],
|
|
8335
8567
|
"properties": {
|
|
8336
8568
|
"name": { "type": "string", "minLength": 1, "maxLength": 100 },
|
|
@@ -8344,6 +8576,10 @@
|
|
|
8344
8576
|
"$ref": "#/components/schemas/RecipientLanguage",
|
|
8345
8577
|
"default": "en",
|
|
8346
8578
|
"description": "The application fallback locale for recipient-owned surfaces when no session, subscriber, or supported provider locale is available."
|
|
8579
|
+
},
|
|
8580
|
+
"privacy_mode": {
|
|
8581
|
+
"$ref": "#/components/schemas/PrivacyMode",
|
|
8582
|
+
"default": "minimal"
|
|
8347
8583
|
}
|
|
8348
8584
|
},
|
|
8349
8585
|
"additionalProperties": false
|
|
@@ -8384,10 +8620,10 @@
|
|
|
8384
8620
|
},
|
|
8385
8621
|
"Project": {
|
|
8386
8622
|
"type": "object",
|
|
8387
|
-
"description": "An
|
|
8623
|
+
"description": "An organization-scoped application project with its complete test/live bootstrap.",
|
|
8388
8624
|
"required": [
|
|
8389
8625
|
"id",
|
|
8390
|
-
"
|
|
8626
|
+
"organization_id",
|
|
8391
8627
|
"name",
|
|
8392
8628
|
"slug",
|
|
8393
8629
|
"status",
|
|
@@ -8395,11 +8631,14 @@
|
|
|
8395
8631
|
"environments",
|
|
8396
8632
|
"created_at",
|
|
8397
8633
|
"updated_at",
|
|
8398
|
-
"diagnostic_id"
|
|
8634
|
+
"diagnostic_id",
|
|
8635
|
+
"privacy_mode"
|
|
8399
8636
|
],
|
|
8400
8637
|
"properties": {
|
|
8401
8638
|
"id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
|
|
8402
|
-
"
|
|
8639
|
+
"organization_id": {
|
|
8640
|
+
"$ref": "#/components/schemas/OpaqueIdentifier"
|
|
8641
|
+
},
|
|
8403
8642
|
"name": { "type": "string", "minLength": 1, "maxLength": 100 },
|
|
8404
8643
|
"slug": {
|
|
8405
8644
|
"type": "string",
|
|
@@ -8420,13 +8659,14 @@
|
|
|
8420
8659
|
},
|
|
8421
8660
|
"created_at": { "$ref": "#/components/schemas/Timestamp" },
|
|
8422
8661
|
"updated_at": { "$ref": "#/components/schemas/Timestamp" },
|
|
8423
|
-
"diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" }
|
|
8662
|
+
"diagnostic_id": { "$ref": "#/components/schemas/DiagnosticId" },
|
|
8663
|
+
"privacy_mode": { "$ref": "#/components/schemas/PrivacyMode" }
|
|
8424
8664
|
},
|
|
8425
8665
|
"additionalProperties": false
|
|
8426
8666
|
},
|
|
8427
8667
|
"ProjectCollection": {
|
|
8428
8668
|
"type": "object",
|
|
8429
|
-
"description": "A stable page of projects inside the authenticated
|
|
8669
|
+
"description": "A stable page of projects inside the authenticated organization.",
|
|
8430
8670
|
"required": ["items"],
|
|
8431
8671
|
"properties": {
|
|
8432
8672
|
"items": {
|
|
@@ -8638,17 +8878,19 @@
|
|
|
8638
8878
|
},
|
|
8639
8879
|
"additionalProperties": false
|
|
8640
8880
|
},
|
|
8641
|
-
"
|
|
8881
|
+
"CreateOrganizationCredentialRequest": {
|
|
8642
8882
|
"type": "object",
|
|
8643
|
-
"description": "Creates one credential against the whole
|
|
8883
|
+
"description": "Creates one credential against the whole organization rather than one project environment.",
|
|
8644
8884
|
"required": ["label", "scopes"],
|
|
8645
8885
|
"properties": {
|
|
8646
8886
|
"label": { "type": "string", "minLength": 1, "maxLength": 100 },
|
|
8647
|
-
"scopes": {
|
|
8887
|
+
"scopes": {
|
|
8888
|
+
"$ref": "#/components/schemas/OrganizationCredentialScopeSet"
|
|
8889
|
+
}
|
|
8648
8890
|
},
|
|
8649
8891
|
"additionalProperties": false
|
|
8650
8892
|
},
|
|
8651
|
-
"
|
|
8893
|
+
"RotateOrganizationCredentialRequest": {
|
|
8652
8894
|
"type": "object",
|
|
8653
8895
|
"description": "Creates a replacement with the same label and scopes and schedules terminal revocation of the replaced credential after the declared overlap.",
|
|
8654
8896
|
"required": ["overlap_seconds"],
|
|
@@ -8661,14 +8903,14 @@
|
|
|
8661
8903
|
},
|
|
8662
8904
|
"additionalProperties": false
|
|
8663
8905
|
},
|
|
8664
|
-
"
|
|
8906
|
+
"OrganizationCredentialId": {
|
|
8665
8907
|
"type": "string",
|
|
8666
|
-
"pattern": "^
|
|
8667
|
-
"description": "
|
|
8908
|
+
"pattern": "^ocred_[A-Za-z0-9_-]{21}[AQgw]$",
|
|
8909
|
+
"description": "ocred_ followed by the canonical unpadded base64url encoding of exactly 16 random bytes."
|
|
8668
8910
|
},
|
|
8669
|
-
"
|
|
8911
|
+
"OrganizationCredential": {
|
|
8670
8912
|
"type": "object",
|
|
8671
|
-
"description": "Safe
|
|
8913
|
+
"description": "Safe organization-scoped API credential metadata. It carries no project or environment, because it names neither: a request does, in its path. It never contains a bearer secret, digest, Clerk identifier, or digest-key reference.",
|
|
8672
8914
|
"required": [
|
|
8673
8915
|
"id",
|
|
8674
8916
|
"prefix",
|
|
@@ -8679,11 +8921,13 @@
|
|
|
8679
8921
|
"status"
|
|
8680
8922
|
],
|
|
8681
8923
|
"properties": {
|
|
8682
|
-
"id": { "$ref": "#/components/schemas/
|
|
8683
|
-
"prefix": {
|
|
8924
|
+
"id": { "$ref": "#/components/schemas/OrganizationCredentialId" },
|
|
8925
|
+
"prefix": {
|
|
8926
|
+
"$ref": "#/components/schemas/OrganizationCredentialPrefix"
|
|
8927
|
+
},
|
|
8684
8928
|
"label": { "type": "string", "minLength": 1, "maxLength": 100 },
|
|
8685
8929
|
"scopes": {
|
|
8686
|
-
"$ref": "#/components/schemas/
|
|
8930
|
+
"$ref": "#/components/schemas/OrganizationCredentialScopeSet"
|
|
8687
8931
|
},
|
|
8688
8932
|
"created_by": {
|
|
8689
8933
|
"$ref": "#/components/schemas/OpaqueIdentifier",
|
|
@@ -8716,15 +8960,15 @@
|
|
|
8716
8960
|
],
|
|
8717
8961
|
"additionalProperties": false
|
|
8718
8962
|
},
|
|
8719
|
-
"
|
|
8963
|
+
"OrganizationCredentialCollection": {
|
|
8720
8964
|
"type": "object",
|
|
8721
|
-
"description": "A stable page of safe
|
|
8965
|
+
"description": "A stable page of safe organization-credential metadata for one organization.",
|
|
8722
8966
|
"required": ["items"],
|
|
8723
8967
|
"properties": {
|
|
8724
8968
|
"items": {
|
|
8725
8969
|
"type": "array",
|
|
8726
8970
|
"maxItems": 100,
|
|
8727
|
-
"items": { "$ref": "#/components/schemas/
|
|
8971
|
+
"items": { "$ref": "#/components/schemas/OrganizationCredential" }
|
|
8728
8972
|
},
|
|
8729
8973
|
"next_cursor": {
|
|
8730
8974
|
"type": "string",
|
|
@@ -8738,26 +8982,30 @@
|
|
|
8738
8982
|
},
|
|
8739
8983
|
"additionalProperties": false
|
|
8740
8984
|
},
|
|
8741
|
-
"
|
|
8985
|
+
"OrganizationCredentialSecretReveal": {
|
|
8742
8986
|
"type": "object",
|
|
8743
8987
|
"description": "The creation-only response. The secret is emitted in this response exactly once and is never available from list, rotate-target, revoke, or later read responses.",
|
|
8744
8988
|
"required": ["credential", "secret"],
|
|
8745
8989
|
"properties": {
|
|
8746
|
-
"credential": {
|
|
8747
|
-
|
|
8990
|
+
"credential": {
|
|
8991
|
+
"$ref": "#/components/schemas/OrganizationCredential"
|
|
8992
|
+
},
|
|
8993
|
+
"secret": {
|
|
8994
|
+
"$ref": "#/components/schemas/OrganizationCredentialSecret"
|
|
8995
|
+
}
|
|
8748
8996
|
},
|
|
8749
8997
|
"additionalProperties": false
|
|
8750
8998
|
},
|
|
8751
|
-
"
|
|
8999
|
+
"OrganizationCredentialRotation": {
|
|
8752
9000
|
"type": "object",
|
|
8753
9001
|
"description": "A creation-only replacement secret plus safe metadata for the credential it replaces.",
|
|
8754
9002
|
"required": ["credential", "replaced_credential"],
|
|
8755
9003
|
"properties": {
|
|
8756
9004
|
"credential": {
|
|
8757
|
-
"$ref": "#/components/schemas/
|
|
9005
|
+
"$ref": "#/components/schemas/OrganizationCredentialSecretReveal"
|
|
8758
9006
|
},
|
|
8759
9007
|
"replaced_credential": {
|
|
8760
|
-
"$ref": "#/components/schemas/
|
|
9008
|
+
"$ref": "#/components/schemas/OrganizationCredential"
|
|
8761
9009
|
}
|
|
8762
9010
|
},
|
|
8763
9011
|
"additionalProperties": false
|
|
@@ -9284,7 +9532,7 @@
|
|
|
9284
9532
|
},
|
|
9285
9533
|
"delivery_target": {
|
|
9286
9534
|
"$ref": "#/components/schemas/MessageDeliveryTarget",
|
|
9287
|
-
"description": "Optional routing override. Omit for notifier-default connection delivery
|
|
9535
|
+
"description": "Optional routing override. Simulator delivery and the reserved test: subscriber prefix are test-environment-only; live requests are refused with 400 request_invalid. Omit for notifier-default connection delivery or the reserved test-environment simulator default."
|
|
9288
9536
|
},
|
|
9289
9537
|
"connection_id": {
|
|
9290
9538
|
"allOf": [{ "$ref": "#/components/schemas/OpaqueIdentifier" }],
|
|
@@ -9824,6 +10072,18 @@
|
|
|
9824
10072
|
"retryable": { "const": false }
|
|
9825
10073
|
}
|
|
9826
10074
|
},
|
|
10075
|
+
{
|
|
10076
|
+
"type": "object",
|
|
10077
|
+
"properties": {
|
|
10078
|
+
"type": {
|
|
10079
|
+
"const": "https://whooshbang.flowxo.com/problems/privacy_operation_in_progress"
|
|
10080
|
+
},
|
|
10081
|
+
"title": { "const": "Privacy operation in progress" },
|
|
10082
|
+
"status": { "const": 409 },
|
|
10083
|
+
"code": { "const": "privacy_operation_in_progress" },
|
|
10084
|
+
"retryable": { "const": true }
|
|
10085
|
+
}
|
|
10086
|
+
},
|
|
9827
10087
|
{
|
|
9828
10088
|
"type": "object",
|
|
9829
10089
|
"properties": {
|
|
@@ -10008,11 +10268,11 @@
|
|
|
10008
10268
|
"type": "object",
|
|
10009
10269
|
"properties": {
|
|
10010
10270
|
"type": {
|
|
10011
|
-
"const": "https://whooshbang.flowxo.com/problems/
|
|
10271
|
+
"const": "https://whooshbang.flowxo.com/problems/credential_organization_mismatch"
|
|
10012
10272
|
},
|
|
10013
|
-
"title": { "const": "Credential
|
|
10273
|
+
"title": { "const": "Credential organization mismatch" },
|
|
10014
10274
|
"status": { "const": 403 },
|
|
10015
|
-
"code": { "const": "
|
|
10275
|
+
"code": { "const": "credential_organization_mismatch" },
|
|
10016
10276
|
"retryable": { "const": false }
|
|
10017
10277
|
}
|
|
10018
10278
|
},
|
|
@@ -10734,7 +10994,7 @@
|
|
|
10734
10994
|
},
|
|
10735
10995
|
"RecipientSession": {
|
|
10736
10996
|
"type": "object",
|
|
10737
|
-
"description": "A browser-safe projection for the exact subscriber selected when the session was created.
|
|
10997
|
+
"description": "A browser-safe projection for the exact subscriber selected when the session was created. Organization, project, environment, subscriber, origin, resolved return URL, provider identity, credentials, and group state are structurally absent.",
|
|
10738
10998
|
"required": [
|
|
10739
10999
|
"id",
|
|
10740
11000
|
"capability_prefix",
|
|
@@ -10962,6 +11222,92 @@
|
|
|
10962
11222
|
},
|
|
10963
11223
|
"additionalProperties": false
|
|
10964
11224
|
},
|
|
11225
|
+
"SubscriberDataExport": {
|
|
11226
|
+
"type": "object",
|
|
11227
|
+
"description": "A complete customer-controller access artifact for one subscriber across every environment in one project. provided_by_subscriber is the Article 20 portable subset; all three record groups together are the Article 15 access copy. WhooshBang-controller records are named but never mixed into the customer export.",
|
|
11228
|
+
"required": [
|
|
11229
|
+
"format",
|
|
11230
|
+
"generated_at",
|
|
11231
|
+
"controller_scope",
|
|
11232
|
+
"project_id",
|
|
11233
|
+
"environment_ids",
|
|
11234
|
+
"subscriber_id",
|
|
11235
|
+
"provided_by_subscriber",
|
|
11236
|
+
"provided_by_customer",
|
|
11237
|
+
"derived_by_service",
|
|
11238
|
+
"excluded_controller_data"
|
|
11239
|
+
],
|
|
11240
|
+
"properties": {
|
|
11241
|
+
"format": {
|
|
11242
|
+
"type": "string",
|
|
11243
|
+
"const": "whooshbang.subscriber-data-export.v1"
|
|
11244
|
+
},
|
|
11245
|
+
"generated_at": { "$ref": "#/components/schemas/Timestamp" },
|
|
11246
|
+
"controller_scope": { "type": "string", "const": "customer" },
|
|
11247
|
+
"project_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
|
|
11248
|
+
"environment_ids": {
|
|
11249
|
+
"type": "array",
|
|
11250
|
+
"minItems": 1,
|
|
11251
|
+
"uniqueItems": true,
|
|
11252
|
+
"items": { "$ref": "#/components/schemas/OpaqueIdentifier" }
|
|
11253
|
+
},
|
|
11254
|
+
"subscriber_id": { "$ref": "#/components/schemas/OpaqueIdentifier" },
|
|
11255
|
+
"provided_by_subscriber": {
|
|
11256
|
+
"type": "array",
|
|
11257
|
+
"items": {
|
|
11258
|
+
"$ref": "#/components/schemas/SubscriberDataExportRecord"
|
|
11259
|
+
}
|
|
11260
|
+
},
|
|
11261
|
+
"provided_by_customer": {
|
|
11262
|
+
"type": "array",
|
|
11263
|
+
"items": {
|
|
11264
|
+
"$ref": "#/components/schemas/SubscriberDataExportRecord"
|
|
11265
|
+
}
|
|
11266
|
+
},
|
|
11267
|
+
"derived_by_service": {
|
|
11268
|
+
"type": "array",
|
|
11269
|
+
"items": {
|
|
11270
|
+
"$ref": "#/components/schemas/SubscriberDataExportRecord"
|
|
11271
|
+
}
|
|
11272
|
+
},
|
|
11273
|
+
"excluded_controller_data": {
|
|
11274
|
+
"type": "array",
|
|
11275
|
+
"minItems": 2,
|
|
11276
|
+
"maxItems": 2,
|
|
11277
|
+
"uniqueItems": true,
|
|
11278
|
+
"items": {
|
|
11279
|
+
"$ref": "#/components/schemas/SubscriberDataExportExcludedControllerData"
|
|
11280
|
+
}
|
|
11281
|
+
}
|
|
11282
|
+
},
|
|
11283
|
+
"additionalProperties": false
|
|
11284
|
+
},
|
|
11285
|
+
"CloseOrganizationRequest": {
|
|
11286
|
+
"type": "object",
|
|
11287
|
+
"description": "Exact, explicit confirmation that the current organization administrator intends to close the whole organization.",
|
|
11288
|
+
"required": ["confirmation"],
|
|
11289
|
+
"properties": {
|
|
11290
|
+
"confirmation": { "type": "string", "const": "close-organization" }
|
|
11291
|
+
},
|
|
11292
|
+
"additionalProperties": false
|
|
11293
|
+
},
|
|
11294
|
+
"OrganizationClosureResult": {
|
|
11295
|
+
"type": "object",
|
|
11296
|
+
"description": "Terminal organization-closure result. Repeating closure returns the same closed_at and any provider-owned resources that still require manual retirement.",
|
|
11297
|
+
"required": ["status", "closed_at", "provider_actions_required"],
|
|
11298
|
+
"properties": {
|
|
11299
|
+
"status": { "type": "string", "const": "closed" },
|
|
11300
|
+
"closed_at": { "$ref": "#/components/schemas/Timestamp" },
|
|
11301
|
+
"provider_actions_required": {
|
|
11302
|
+
"type": "array",
|
|
11303
|
+
"uniqueItems": true,
|
|
11304
|
+
"items": {
|
|
11305
|
+
"$ref": "#/components/schemas/OrganizationClosureProviderAction"
|
|
11306
|
+
}
|
|
11307
|
+
}
|
|
11308
|
+
},
|
|
11309
|
+
"additionalProperties": false
|
|
11310
|
+
},
|
|
10965
11311
|
"CreateRecipientGroupRequest": {
|
|
10966
11312
|
"type": "object",
|
|
10967
11313
|
"description": "Creates one static, developer-managed recipient group.",
|
|
@@ -11191,16 +11537,16 @@
|
|
|
11191
11537
|
},
|
|
11192
11538
|
"additionalProperties": false
|
|
11193
11539
|
},
|
|
11194
|
-
"
|
|
11540
|
+
"OrganizationRole": {
|
|
11195
11541
|
"type": "string",
|
|
11196
11542
|
"enum": ["admin", "member"],
|
|
11197
11543
|
"description": "The stable WhooshBang authorization role projected from the current Clerk organization membership."
|
|
11198
11544
|
},
|
|
11199
|
-
"
|
|
11545
|
+
"OrganizationMembershipSummary": {
|
|
11200
11546
|
"type": "object",
|
|
11201
11547
|
"required": ["role"],
|
|
11202
11548
|
"properties": {
|
|
11203
|
-
"role": { "$ref": "#/components/schemas/
|
|
11549
|
+
"role": { "$ref": "#/components/schemas/OrganizationRole" }
|
|
11204
11550
|
},
|
|
11205
11551
|
"additionalProperties": false
|
|
11206
11552
|
},
|
|
@@ -11219,6 +11565,7 @@
|
|
|
11219
11565
|
"environment_mismatch",
|
|
11220
11566
|
"idempotency_key_required",
|
|
11221
11567
|
"idempotency_conflict",
|
|
11568
|
+
"privacy_operation_in_progress",
|
|
11222
11569
|
"project_slug_conflict",
|
|
11223
11570
|
"request_invalid",
|
|
11224
11571
|
"replay_unavailable",
|
|
@@ -11236,7 +11583,7 @@
|
|
|
11236
11583
|
"resource_not_found",
|
|
11237
11584
|
"resource_expired",
|
|
11238
11585
|
"cancellation_too_late",
|
|
11239
|
-
"
|
|
11586
|
+
"credential_organization_mismatch",
|
|
11240
11587
|
"endpoint_rotation_conflict",
|
|
11241
11588
|
"rate_limited",
|
|
11242
11589
|
"provider_retryable",
|
|
@@ -11355,15 +11702,29 @@
|
|
|
11355
11702
|
}
|
|
11356
11703
|
]
|
|
11357
11704
|
},
|
|
11358
|
-
"
|
|
11705
|
+
"OrganizationClosureProviderAction": {
|
|
11706
|
+
"type": "object",
|
|
11707
|
+
"description": "One provider-owned resource the customer must retire outside WhooshBang after organization closure. It contains safe identifiers only, never provider credentials.",
|
|
11708
|
+
"required": ["provider", "action", "connection_id"],
|
|
11709
|
+
"properties": {
|
|
11710
|
+
"provider": { "type": "string", "enum": ["telegram", "slack"] },
|
|
11711
|
+
"action": {
|
|
11712
|
+
"type": "string",
|
|
11713
|
+
"enum": ["revoke_bot_token", "delete_provider_application"]
|
|
11714
|
+
},
|
|
11715
|
+
"connection_id": { "$ref": "#/components/schemas/OpaqueIdentifier" }
|
|
11716
|
+
},
|
|
11717
|
+
"additionalProperties": false
|
|
11718
|
+
},
|
|
11719
|
+
"OrganizationCredentialPrefix": {
|
|
11359
11720
|
"type": "string",
|
|
11360
|
-
"pattern": "^
|
|
11361
|
-
"description": "A safe display prefix containing the
|
|
11721
|
+
"pattern": "^wb_oc1\\.ocred_[A-Za-z0-9_-]{8}$",
|
|
11722
|
+
"description": "A safe display prefix containing the organization-credential format marker and first eight base64url identity characters, never secret bytes."
|
|
11362
11723
|
},
|
|
11363
|
-
"
|
|
11724
|
+
"OrganizationCredentialScope": {
|
|
11364
11725
|
"type": "string",
|
|
11365
11726
|
"enum": [
|
|
11366
|
-
"
|
|
11727
|
+
"organization:read",
|
|
11367
11728
|
"projects:write",
|
|
11368
11729
|
"projects:read",
|
|
11369
11730
|
"messages:write",
|
|
@@ -11376,14 +11737,14 @@
|
|
|
11376
11737
|
"connections:write",
|
|
11377
11738
|
"connections:read"
|
|
11378
11739
|
],
|
|
11379
|
-
"description": "One
|
|
11740
|
+
"description": "One organization-credential capability. `organization:read` is the organization's project directory — listing the organization's projects and reading one — and is the only scope here a project credential can never carry; it authorizes nothing below the organization. Every other name is the project-credential vocabulary unchanged, and is exercised only on the environment-scoped routes, where the project and environment come from the path and the credential's authority is the intersection of these scopes with the project-credential vocabulary. An organization credential is therefore never wider than a project credential would have been for the same project environment."
|
|
11380
11741
|
},
|
|
11381
|
-
"
|
|
11742
|
+
"OrganizationCredentialScopeSet": {
|
|
11382
11743
|
"type": "array",
|
|
11383
11744
|
"minItems": 1,
|
|
11384
11745
|
"maxItems": 12,
|
|
11385
11746
|
"uniqueItems": true,
|
|
11386
|
-
"items": { "$ref": "#/components/schemas/
|
|
11747
|
+
"items": { "$ref": "#/components/schemas/OrganizationCredentialScope" }
|
|
11387
11748
|
},
|
|
11388
11749
|
"ListPageSize": {
|
|
11389
11750
|
"type": "integer",
|
|
@@ -11396,9 +11757,9 @@
|
|
|
11396
11757
|
"minimum": 0,
|
|
11397
11758
|
"description": "How many records the list holds in total, not only on this page. Counted while the page was read, so a write landing between the count and the page can leave it a record or two out of step with `items`. That is noise on an inspection surface; it never changes which records a page addresses."
|
|
11398
11759
|
},
|
|
11399
|
-
"
|
|
11760
|
+
"OrganizationCredentialSecret": {
|
|
11400
11761
|
"type": "string",
|
|
11401
|
-
"pattern": "^
|
|
11762
|
+
"pattern": "^wb_oc1\\.ocred_[A-Za-z0-9_-]{21}[AQgw]\\.[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$",
|
|
11402
11763
|
"description": "The exact one-time runtime bearer syntax. The final segment is canonical unpadded base64url for exactly 32 random secret bytes."
|
|
11403
11764
|
},
|
|
11404
11765
|
"Environment": {
|
|
@@ -11432,7 +11793,7 @@
|
|
|
11432
11793
|
"connections:write",
|
|
11433
11794
|
"connections:read"
|
|
11434
11795
|
],
|
|
11435
|
-
"description": "One project-credential capability. Environment authority always comes from the credential record, never a scope or request field. `projects:write` configures the credential's own project and environment; it never creates a project, which remains an
|
|
11796
|
+
"description": "One project-credential capability. Environment authority always comes from the credential record, never a scope or request field. `projects:write` configures the credential's own project and environment; it never creates a project, which remains an organization authority. The project-wide singletons — brand, default locale, logo and recipient copy — are what a live recipient sees, so writing them requires a live credential; a test credential may read them and may write its own environment's policy."
|
|
11436
11797
|
},
|
|
11437
11798
|
"ApiCredentialScopeSet": {
|
|
11438
11799
|
"type": "array",
|
|
@@ -12060,7 +12421,7 @@
|
|
|
12060
12421
|
"failed",
|
|
12061
12422
|
"expired"
|
|
12062
12423
|
],
|
|
12063
|
-
"description": "How far a guided setup has reached, which is the only thing a caller can act on while a connection is still `pending`. `awaiting_handoff` waits for the administrator to open the link on the Telegram account that will own the bot; `awaiting_creation` means that account is bound and the bot does not exist yet; `provisioning` means the bot exists and WhooshBang is installing delivery on it. `failed` and `expired` end the attempt without ending the connection — another attempt can be started on the same `pending` connection — and neither withdraws a bot Telegram has already created, because no provider API can delete one."
|
|
12424
|
+
"description": "How far a guided setup has reached, which is the only thing a caller can act on while a connection is still `pending`. `awaiting_handoff` waits for the administrator to open the link on the Telegram account that will own the bot; `awaiting_creation` means that Telegram account is bound and the bot does not exist yet; `provisioning` means the bot exists and WhooshBang is installing delivery on it. `failed` and `expired` end the attempt without ending the connection — another attempt can be started on the same `pending` connection — and neither withdraws a bot Telegram has already created, because no provider API can delete one."
|
|
12064
12425
|
},
|
|
12065
12426
|
"SuggestedBotUsername": {
|
|
12066
12427
|
"type": "string",
|
|
@@ -12087,7 +12448,7 @@
|
|
|
12087
12448
|
"format": "uri",
|
|
12088
12449
|
"pattern": "^https://[^\\s]+$",
|
|
12089
12450
|
"maxLength": 2048,
|
|
12090
|
-
"description": "The link the administrator opens to put their own Telegram account behind this setup; for Telegram it is `https://t.me/<manager>?start=<payload>`. It is a capability for exactly one setup session and nothing else: it names no
|
|
12451
|
+
"description": "The link the administrator opens to put their own Telegram account behind this setup; for Telegram it is `https://t.me/<manager>?start=<payload>`. It is a capability for exactly one setup session and nothing else: it names no organization, no project, and no environment, it stops working at `expires_at`, and only the first Telegram account to open it is bound. It is not credential material, so displaying it costs nothing beyond letting whoever sees it first become the owner of the bot this setup creates. After `expired` or `failed` it binds nothing, and restarting the setup issues a new one rather than reviving this."
|
|
12091
12452
|
},
|
|
12092
12453
|
"expires_at": {
|
|
12093
12454
|
"$ref": "#/components/schemas/Timestamp",
|
|
@@ -12101,7 +12462,7 @@
|
|
|
12101
12462
|
"type": "string",
|
|
12102
12463
|
"minLength": 1,
|
|
12103
12464
|
"maxLength": 200,
|
|
12104
|
-
"description": "Why this attempt ended, in terms the administrator can act on. Absent when there is nothing both safe and useful to say: an attempt refused because that Telegram account already holds a live setup says only that, because naming the
|
|
12465
|
+
"description": "Why this attempt ended, in terms the administrator can act on. Absent when there is nothing both safe and useful to say: an attempt refused because that Telegram account already holds a live setup says only that, because naming the organization, project, or environment holding the other one would disclose another customer."
|
|
12105
12466
|
}
|
|
12106
12467
|
},
|
|
12107
12468
|
"additionalProperties": false
|
|
@@ -12389,7 +12750,7 @@
|
|
|
12389
12750
|
"format": "uri",
|
|
12390
12751
|
"pattern": "^https://api\\.slack\\.com/apps\\?[^\\s]+$",
|
|
12391
12752
|
"maxLength": 8192,
|
|
12392
|
-
"description": "Slack's own app-creation flow, opened with this app's manifest already filled in, so the owner reviews and presses Create rather than writing or pasting YAML. The URL carries configuration only: it names no
|
|
12753
|
+
"description": "Slack's own app-creation flow, opened with this app's manifest already filled in, so the owner reviews and presses Create rather than writing or pasting YAML. The URL carries configuration only: it names no organization, project, or environment and contains no credential. The opaque handle it does carry selects candidate setup state and authorizes nothing."
|
|
12393
12754
|
},
|
|
12394
12755
|
"expires_at": {
|
|
12395
12756
|
"$ref": "#/components/schemas/Timestamp",
|
|
@@ -12783,7 +13144,7 @@
|
|
|
12783
13144
|
"provider-capabilities-v1.schema": {
|
|
12784
13145
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
12785
13146
|
"$id": "https://whooshbang.flowxo.com/schemas/provider-capabilities-v1.schema.json",
|
|
12786
|
-
"x-contract-version": "1.0.0-rc.
|
|
13147
|
+
"x-contract-version": "1.0.0-rc.23",
|
|
12787
13148
|
"title": "ProviderCapabilitiesV1",
|
|
12788
13149
|
"description": "Provider-neutral, renderer-facing delivery and interaction capabilities with explicit degradation.",
|
|
12789
13150
|
"type": "object",
|
|
@@ -12986,6 +13347,38 @@
|
|
|
12986
13347
|
}
|
|
12987
13348
|
},
|
|
12988
13349
|
"additionalProperties": false
|
|
13350
|
+
},
|
|
13351
|
+
"SubscriberDataExportRecord": {
|
|
13352
|
+
"type": "object",
|
|
13353
|
+
"description": "One semantic record held about the subscriber. The source names the durable store or recovered semantic value; data contains plaintext business fields and excludes custody metadata and secrets.",
|
|
13354
|
+
"required": ["source", "data"],
|
|
13355
|
+
"properties": {
|
|
13356
|
+
"source": {
|
|
13357
|
+
"type": "string",
|
|
13358
|
+
"minLength": 1,
|
|
13359
|
+
"maxLength": 96,
|
|
13360
|
+
"pattern": "^[a-z][a-z0-9_.-]*$"
|
|
13361
|
+
},
|
|
13362
|
+
"data": { "type": "object", "additionalProperties": true }
|
|
13363
|
+
},
|
|
13364
|
+
"additionalProperties": false
|
|
13365
|
+
},
|
|
13366
|
+
"SubscriberDataExportExcludedControllerData": {
|
|
13367
|
+
"type": "object",
|
|
13368
|
+
"description": "A category deliberately outside the customer-controller artifact because WhooshBang is controller for it.",
|
|
13369
|
+
"required": ["category", "controller", "access"],
|
|
13370
|
+
"properties": {
|
|
13371
|
+
"category": {
|
|
13372
|
+
"type": "string",
|
|
13373
|
+
"enum": ["consent_lifecycle_audit", "service_logs"]
|
|
13374
|
+
},
|
|
13375
|
+
"controller": { "type": "string", "const": "whooshbang" },
|
|
13376
|
+
"access": {
|
|
13377
|
+
"type": "string",
|
|
13378
|
+
"const": "separate_recipient_request_required"
|
|
13379
|
+
}
|
|
13380
|
+
},
|
|
13381
|
+
"additionalProperties": false
|
|
12989
13382
|
}
|
|
12990
13383
|
},
|
|
12991
13384
|
"responses": {
|
|
@@ -13145,7 +13538,7 @@
|
|
|
13145
13538
|
}
|
|
13146
13539
|
},
|
|
13147
13540
|
"Conflict": {
|
|
13148
|
-
"description": "An idempotency key, project slug, credential identity, existing\nacknowledgement, or resource state conflicts with the authorized\
|
|
13541
|
+
"description": "An idempotency key, project slug, credential identity, existing\nacknowledgement, or resource state conflicts with the authorized\norganization or request.\n",
|
|
13149
13542
|
"headers": {
|
|
13150
13543
|
"WhooshBang-Diagnostic-Id": {
|
|
13151
13544
|
"$ref": "#/components/headers/DiagnosticId"
|
|
@@ -13171,7 +13564,7 @@
|
|
|
13171
13564
|
"type": "https://whooshbang.flowxo.com/problems/project_slug_conflict",
|
|
13172
13565
|
"title": "Project slug conflict",
|
|
13173
13566
|
"status": 409,
|
|
13174
|
-
"detail": "That project slug is already used in this
|
|
13567
|
+
"detail": "That project slug is already used in this organization.",
|
|
13175
13568
|
"code": "project_slug_conflict",
|
|
13176
13569
|
"diagnostic_id": "diag_project_slug_conflict_001",
|
|
13177
13570
|
"retryable": false,
|
|
@@ -13435,5 +13828,5 @@
|
|
|
13435
13828
|
}
|
|
13436
13829
|
}
|
|
13437
13830
|
},
|
|
13438
|
-
"x-contract-version": "1.0.0-rc.
|
|
13831
|
+
"x-contract-version": "1.0.0-rc.23"
|
|
13439
13832
|
}
|