@whooshbang/contracts 2.4.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +21 -21
  3. package/contract-manifest.json +35 -32
  4. package/dist/generated/artifact-index.d.ts +34 -34
  5. package/dist/generated/artifact-index.js +35 -32
  6. package/dist/generated/artifact-index.js.map +1 -1
  7. package/dist/generated/interaction-v1.d.ts +77 -4
  8. package/dist/generated/validators-standalone.d.ts +522 -483
  9. package/dist/generated/validators-standalone.js +12972 -6118
  10. package/dist/generated/validators-standalone.js.map +1 -1
  11. package/dist/generated/validators.d.ts +5 -2
  12. package/dist/generated/validators.js +4 -1
  13. package/dist/generated/validators.js.map +1 -1
  14. package/dist/generated/whooshbang-v1.d.ts +634 -116
  15. package/dist/index.d.ts +5 -2
  16. package/dist/index.js +2 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/input-defaults.d.ts +7 -0
  19. package/dist/input-defaults.js +59 -0
  20. package/dist/input-defaults.js.map +1 -0
  21. package/dist/interaction-expiry.js +2 -1
  22. package/dist/interaction-expiry.js.map +1 -1
  23. package/fixtures/core-v1/fixture-index.json +24 -1
  24. package/fixtures/core-v1/problems/idempotency-key-required.json +2 -2
  25. package/fixtures/core-v1/requests/redeem-billing-promotion.json +3 -0
  26. package/fixtures/core-v1/scenarios/api-credential-invalid-indistinguishable.json +1 -1
  27. package/fixtures/core-v1/scenarios/api-credential-one-time-reveal.json +1 -1
  28. package/fixtures/core-v1/scenarios/api-credential-revocation-replay.json +1 -1
  29. package/fixtures/core-v1/scenarios/api-credential-rotation-overlap.json +1 -1
  30. package/fixtures/core-v1/scenarios/cancellation-too-late.json +1 -1
  31. package/fixtures/core-v1/scenarios/cross-organization-project.json +1 -1
  32. package/fixtures/core-v1/scenarios/cross-project-resource.json +1 -1
  33. package/fixtures/core-v1/scenarios/environment-mismatch.json +1 -1
  34. package/fixtures/core-v1/scenarios/idempotency-conflict.json +1 -1
  35. package/fixtures/core-v1/scenarios/idempotency-equivalent-replay.json +1 -1
  36. package/fixtures/core-v1/scenarios/malformed-bearer.json +1 -1
  37. package/fixtures/core-v1/scenarios/metadata-overrun.json +1 -1
  38. package/fixtures/core-v1/scenarios/missing-scope.json +1 -1
  39. package/fixtures/core-v1/scenarios/project-create-equivalent-replay.json +1 -1
  40. package/fixtures/core-v1/scenarios/project-slug-conflict.json +1 -1
  41. package/fixtures/core-v1/scenarios/provider-outcome-unknown.json +1 -1
  42. package/fixtures/core-v1/scenarios/subscription-activation-replay.json +1 -1
  43. package/fixtures/core-v1/scenarios/subscription-authorization-capability-opacity.json +1 -1
  44. package/fixtures/core-v1/scenarios/subscription-cross-connection-callback-rejected.json +1 -1
  45. package/fixtures/core-v1/scenarios/subscription-expired-replay.json +1 -1
  46. package/fixtures/core-v1/scenarios/subscription-selected-connection-replay.json +1 -1
  47. package/fixtures/core-v1/success/billing-promotion.json +14 -0
  48. package/fixtures/core-v1/success/billing-promotions.json +64 -0
  49. package/fixtures/core-v1/success/credit-purchase.json +2 -0
  50. package/fixtures/core-v1/success/subscription-change.json +7 -0
  51. package/fixtures/interaction-machine-v1/scenarios/ack-conflict.json +1 -1
  52. package/fixtures/interaction-machine-v1/scenarios/ack-cross-machine.json +1 -1
  53. package/fixtures/interaction-machine-v1/scenarios/ack-out-of-order.json +1 -1
  54. package/fixtures/interaction-machine-v1/scenarios/ack-replay.json +1 -1
  55. package/fixtures/interaction-machine-v1/scenarios/ambiguous-free-text.json +1 -1
  56. package/fixtures/interaction-machine-v1/scenarios/callback-token-opacity.json +1 -1
  57. package/fixtures/interaction-machine-v1/scenarios/credential-registration-conflict.json +1 -1
  58. package/fixtures/interaction-machine-v1/scenarios/credential-registration-replay.json +1 -1
  59. package/fixtures/interaction-machine-v1/scenarios/credential-revocation-replay.json +1 -1
  60. package/fixtures/interaction-machine-v1/scenarios/credential-rotation.json +1 -1
  61. package/fixtures/interaction-machine-v1/scenarios/first-credential-activates.json +1 -1
  62. package/fixtures/interaction-machine-v1/scenarios/interaction-duplicate.json +1 -1
  63. package/fixtures/interaction-machine-v1/scenarios/interaction-expired.json +1 -1
  64. package/fixtures/interaction-machine-v1/scenarios/interaction-mismatch.json +1 -1
  65. package/fixtures/interaction-machine-v1/scenarios/interaction-retired.json +1 -1
  66. package/fixtures/interaction-machine-v1/scenarios/interaction-stale.json +1 -1
  67. package/fixtures/interaction-machine-v1/scenarios/machine-admin-denied.json +1 -1
  68. package/fixtures/interaction-machine-v1/scenarios/machine-bound-message-create.json +1 -1
  69. package/fixtures/interaction-machine-v1/scenarios/machine-cancel-denied.json +1 -1
  70. package/fixtures/interaction-machine-v1/scenarios/machine-crash-before-ack.json +1 -1
  71. package/fixtures/interaction-machine-v1/scenarios/machine-notifier-mismatch.json +1 -1
  72. package/fixtures/interaction-machine-v1/scenarios/machine-other-message-read.json +1 -1
  73. package/fixtures/interaction-machine-v1/scenarios/machine-owned-message-read.json +1 -1
  74. package/fixtures/interaction-machine-v1/scenarios/machine-subscriber-mismatch.json +1 -1
  75. package/fixtures/interaction-machine-v1/scenarios/poll-uncommitted-cursor-rejected.json +1 -1
  76. package/fixtures/interaction-machine-v1/scenarios/project-credential-machine-endpoint-denied.json +1 -1
  77. package/fixtures/interaction-machine-v1/scenarios/quarantine-integrity-rejected.json +1 -1
  78. package/fixtures/interaction-machine-v1/scenarios/quarantine-signature-rejected.json +1 -1
  79. package/fixtures/interaction-machine-v1/scenarios/quarantine-valid.json +1 -1
  80. package/fixtures/interaction-machine-v1/scenarios/revoked-machine-credential.json +1 -1
  81. package/fixtures/recipient-experience-v1/scenarios/membership-broadcast-snapshot.json +1 -1
  82. package/fixtures/recipient-experience-v1/scenarios/preferred-binding-resolution.json +1 -1
  83. package/fixtures/recipient-experience-v1/scenarios/recipient-session-security.json +1 -1
  84. package/fixtures/recipient-experience-v1/scenarios/subscriber-initial-groups-transaction.json +1 -1
  85. package/openapi/generated/whooshbang-v1.bundle.json +1338 -254
  86. package/openapi/whooshbang-v1.yaml +547 -73
  87. package/package.json +1 -1
  88. package/schemas/core-scenario.schema.json +1 -1
  89. package/schemas/events/agent-binding-degraded-v1.schema.json +1 -1
  90. package/schemas/events/interaction-expired-v1.schema.json +1 -1
  91. package/schemas/events/interaction-received-v1.schema.json +1 -1
  92. package/schemas/events/message-delivered-v1.schema.json +1 -1
  93. package/schemas/events/message-expired-v1.schema.json +1 -1
  94. package/schemas/events/message-failed-v1.schema.json +1 -1
  95. package/schemas/events/message-provider-accepted-v1.schema.json +1 -1
  96. package/schemas/events/subscription-activated-v1.schema.json +1 -1
  97. package/schemas/events/subscription-revoked-v1.schema.json +1 -1
  98. package/schemas/events/whooshbang-event-v1.schema.json +1 -1
  99. package/schemas/fixture-index.schema.json +1 -1
  100. package/schemas/interaction-machine-scenario.schema.json +1 -1
  101. package/schemas/interaction-v1.schema.json +192 -5
  102. package/schemas/machine-v1.schema.json +1 -1
  103. package/schemas/provider-capabilities-v1.schema.json +1 -1
  104. package/schemas/webhooks/webhook-delivery-case-v1.schema.json +1 -1
  105. package/schemas/webhooks/webhook-signing-vector-v1.schema.json +1 -1
  106. package/schemas/whooshbang-v1.schema.json +769 -63
@@ -1,10 +1,10 @@
1
1
  openapi: 3.1.1
2
2
  jsonSchemaDialect: https://json-schema.org/draft/2020-12/schema
3
3
  # whooshbang:public-origin production api https://api.whooshbang.com
4
- x-contract-version: 2.4.0
4
+ x-contract-version: 2.6.0
5
5
  info:
6
6
  title: WhooshBang API
7
- version: 2.4.0
7
+ version: 2.6.0
8
8
  description: |
9
9
  The V1 contract for human organization/project administration, project-scoped
10
10
  subscription links, and asynchronous text messages. A Clerk session selects
@@ -435,6 +435,93 @@ paths:
435
435
  $ref: "#/components/responses/Conflict"
436
436
  "429":
437
437
  $ref: "#/components/responses/RateLimited"
438
+ /v1/billing/promotions:
439
+ get:
440
+ operationId: getBillingPromotions
441
+ summary: Read the organization's promotions
442
+ description: |
443
+ Organization administrators can read every promotion the organization holds: rewards WhooshBang gave it
444
+ and promotion codes it redeemed, with what remains and when each ends. Promotional value has no cash
445
+ value, is never refunded and cannot move to another organization.
446
+ tags: [Organization]
447
+ security:
448
+ - clerkSession: []
449
+ - bearerGrant: []
450
+ x-required-scopes: [billing:read]
451
+ x-organization-membership: required
452
+ responses:
453
+ "200":
454
+ description: The organization's promotions, newest first.
455
+ headers:
456
+ WhooshBang-Diagnostic-Id:
457
+ $ref: "#/components/headers/DiagnosticId"
458
+ content:
459
+ application/json:
460
+ schema:
461
+ $ref: "#/components/schemas/BillingPromotions"
462
+ "401":
463
+ $ref: "#/components/responses/Unauthorized"
464
+ "403":
465
+ $ref: "#/components/responses/Forbidden"
466
+ "404":
467
+ $ref: "#/components/responses/NotFound"
468
+ "429":
469
+ $ref: "#/components/responses/RateLimited"
470
+ /v1/billing/promotions/redeem:
471
+ post:
472
+ operationId: redeemBillingPromotion
473
+ summary: Redeem a promotion code
474
+ description: |
475
+ Organization administrators can redeem a promotion code for their own organization. Nothing is charged.
476
+ Every code that cannot be redeemed (mistyped, ended, fully used, not offered to this organization, or not
477
+ combinable with a promotion it already holds) receives the same `resource_not_found` answer. Repeated
478
+ refusals are rate limited per organization; wait for `Retry-After`. Reuse the same idempotency key after
479
+ an uncertain response: it can never redeem twice.
480
+ tags: [Organization]
481
+ security:
482
+ - clerkSession: []
483
+ - bearerGrant: []
484
+ x-required-scopes: [billing:write]
485
+ x-organization-membership: required
486
+ parameters:
487
+ - $ref: "#/components/parameters/IdempotencyKey"
488
+ requestBody:
489
+ required: true
490
+ content:
491
+ application/json:
492
+ schema:
493
+ $ref: "#/components/schemas/RedeemBillingPromotionRequest"
494
+ responses:
495
+ "200":
496
+ description: The same promotion, replayed for a repeated idempotency key.
497
+ headers:
498
+ WhooshBang-Diagnostic-Id:
499
+ $ref: "#/components/headers/DiagnosticId"
500
+ content:
501
+ application/json:
502
+ schema:
503
+ $ref: "#/components/schemas/BillingPromotion"
504
+ "201":
505
+ description: The promotion the code gave the organization.
506
+ headers:
507
+ WhooshBang-Diagnostic-Id:
508
+ $ref: "#/components/headers/DiagnosticId"
509
+ content:
510
+ application/json:
511
+ schema:
512
+ $ref: "#/components/schemas/BillingPromotion"
513
+ "400":
514
+ $ref: "#/components/responses/BadRequest"
515
+ "401":
516
+ $ref: "#/components/responses/Unauthorized"
517
+ "403":
518
+ $ref: "#/components/responses/Forbidden"
519
+ "404":
520
+ $ref: "#/components/responses/NotFound"
521
+ "409":
522
+ $ref: "#/components/responses/Conflict"
523
+ "429":
524
+ $ref: "#/components/responses/RateLimited"
438
525
  /v1/billing/auto-top-up:
439
526
  get:
440
527
  operationId: getAutoTopUpSettings
@@ -2043,7 +2130,7 @@ paths:
2043
2130
  - projects:write
2044
2131
  x-organization-membership: required
2045
2132
  x-idempotency:
2046
- required: true
2133
+ required: false
2047
2134
  retention_seconds: 604800
2048
2135
  scope:
2049
2136
  - authenticated_organization
@@ -2529,7 +2616,7 @@ paths:
2529
2616
  x-required-scopes:
2530
2617
  - subscriptions:write
2531
2618
  x-idempotency:
2532
- required: true
2619
+ required: false
2533
2620
  retention_seconds: 604800
2534
2621
  scope:
2535
2622
  - authenticated_environment
@@ -2624,7 +2711,7 @@ paths:
2624
2711
  x-required-scopes:
2625
2712
  - subscriptions:write
2626
2713
  x-idempotency:
2627
- required: true
2714
+ required: false
2628
2715
  retention_seconds: 604800
2629
2716
  scope:
2630
2717
  - authenticated_environment
@@ -2685,7 +2772,7 @@ paths:
2685
2772
  x-required-scopes:
2686
2773
  - messages:write
2687
2774
  x-idempotency:
2688
- required: true
2775
+ required: false
2689
2776
  retention_seconds: 604800
2690
2777
  scope:
2691
2778
  - authenticated_environment
@@ -2812,7 +2899,7 @@ paths:
2812
2899
  - bound_notifier
2813
2900
  - bound_subscriber
2814
2901
  x-idempotency:
2815
- required: true
2902
+ required: false
2816
2903
  retention_seconds: 604800
2817
2904
  scope:
2818
2905
  - authenticated_environment
@@ -3002,7 +3089,7 @@ paths:
3002
3089
  x-required-scopes:
3003
3090
  - messages:write
3004
3091
  x-idempotency:
3005
- required: true
3092
+ required: false
3006
3093
  retention_seconds: 604800
3007
3094
  scope:
3008
3095
  - authenticated_environment
@@ -3061,7 +3148,7 @@ paths:
3061
3148
  x-required-scopes:
3062
3149
  - machine-clients:write
3063
3150
  x-idempotency:
3064
- required: true
3151
+ required: false
3065
3152
  retention_seconds: 604800
3066
3153
  scope:
3067
3154
  - authenticated_environment
@@ -3158,7 +3245,7 @@ paths:
3158
3245
  x-required-scopes:
3159
3246
  - machine-clients:write
3160
3247
  x-idempotency:
3161
- required: true
3248
+ required: false
3162
3249
  retention_seconds: 604800
3163
3250
  scope:
3164
3251
  - authenticated_environment
@@ -3231,7 +3318,7 @@ paths:
3231
3318
  x-required-scopes:
3232
3319
  - machine-clients:write
3233
3320
  x-idempotency:
3234
- required: true
3321
+ required: false
3235
3322
  retention_seconds: 604800
3236
3323
  scope:
3237
3324
  - authenticated_environment
@@ -3282,7 +3369,7 @@ paths:
3282
3369
  x-required-scopes:
3283
3370
  - machine-clients:write
3284
3371
  x-idempotency:
3285
- required: true
3372
+ required: false
3286
3373
  retention_seconds: 604800
3287
3374
  scope:
3288
3375
  - authenticated_environment
@@ -3384,7 +3471,7 @@ paths:
3384
3471
  x-required-scopes:
3385
3472
  - machine-events:ack
3386
3473
  x-idempotency:
3387
- required: true
3474
+ required: false
3388
3475
  retention_seconds: 604800
3389
3476
  scope:
3390
3477
  - authenticated_environment
@@ -3475,7 +3562,7 @@ paths:
3475
3562
  $ref: "#/components/responses/NotFound"
3476
3563
  post:
3477
3564
  operationId: createCustomerEndpoint
3478
- summary: Create an inactive customer endpoint and reveal its signing secret once
3565
+ summary: Create an active customer endpoint and reveal its signing secret once
3479
3566
  description: |
3480
3567
  Validates the final normalized public HTTPS destination before storing it.
3481
3568
  The initial response includes the new signing secret. An equivalent
@@ -3491,7 +3578,7 @@ paths:
3491
3578
  x-required-scopes:
3492
3579
  - messages:write
3493
3580
  x-idempotency:
3494
- required: true
3581
+ required: false
3495
3582
  retention_seconds: 604800
3496
3583
  scope:
3497
3584
  - authenticated_environment
@@ -3516,7 +3603,7 @@ paths:
3516
3603
  externalValue: ../fixtures/core-v1/requests/create-customer-endpoint.json
3517
3604
  responses:
3518
3605
  "201":
3519
- description: Newly created unverified endpoint and its one-time signing secret.
3606
+ description: Newly active endpoint, recorded signed ping result, and its one-time signing secret.
3520
3607
  headers:
3521
3608
  WhooshBang-Diagnostic-Id:
3522
3609
  $ref: "#/components/headers/DiagnosticId"
@@ -3585,7 +3672,7 @@ paths:
3585
3672
  - $ref: "#/components/parameters/CustomerEndpointId"
3586
3673
  post:
3587
3674
  operationId: verifyCustomerEndpoint
3588
- summary: Send a signed challenge and activate the endpoint only after a signed echo
3675
+ summary: Send a signed test ping and record whether the receiver returns 2xx
3589
3676
  tags:
3590
3677
  - Customer endpoints
3591
3678
  security:
@@ -3630,7 +3717,7 @@ paths:
3630
3717
  x-required-scopes:
3631
3718
  - messages:write
3632
3719
  x-idempotency:
3633
- required: true
3720
+ required: false
3634
3721
  retention_seconds: 604800
3635
3722
  scope:
3636
3723
  - authenticated_environment
@@ -3908,7 +3995,7 @@ paths:
3908
3995
  x-required-scopes:
3909
3996
  - connections:write
3910
3997
  x-idempotency:
3911
- required: true
3998
+ required: false
3912
3999
  retention_seconds: 604800
3913
4000
  scope:
3914
4001
  - authenticated_environment
@@ -4225,7 +4312,7 @@ paths:
4225
4312
  x-required-scopes:
4226
4313
  - connections:write
4227
4314
  x-idempotency:
4228
- required: true
4315
+ required: false
4229
4316
  retention_seconds: 604800
4230
4317
  scope:
4231
4318
  - authenticated_environment
@@ -4787,7 +4874,7 @@ paths:
4787
4874
  x-required-scopes:
4788
4875
  - connections:write
4789
4876
  x-idempotency:
4790
- required: true
4877
+ required: false
4791
4878
  retention_seconds: 604800
4792
4879
  scope:
4793
4880
  - authenticated_environment
@@ -5429,7 +5516,7 @@ paths:
5429
5516
  x-required-scopes:
5430
5517
  - subscriptions:write
5431
5518
  x-idempotency:
5432
- required: true
5519
+ required: false
5433
5520
  retention_seconds: 604800
5434
5521
  scope:
5435
5522
  - authenticated_project_environment
@@ -5735,7 +5822,7 @@ paths:
5735
5822
  x-required-scopes:
5736
5823
  - subscriptions:write
5737
5824
  x-idempotency:
5738
- required: true
5825
+ required: false
5739
5826
  retention_seconds: 604800
5740
5827
  scope:
5741
5828
  - authenticated_project_environment
@@ -5840,7 +5927,7 @@ paths:
5840
5927
  environment asked about. Combines with every other filter, so `q`
5841
5928
  searches within the group.
5842
5929
  schema:
5843
- $ref: "../schemas/whooshbang-v1.schema.json#/$defs/DeveloperKey"
5930
+ $ref: "../schemas/whooshbang-v1.schema.json#/$defs/GroupKey"
5844
5931
  - name: created_after
5845
5932
  in: query
5846
5933
  required: false
@@ -5895,7 +5982,7 @@ paths:
5895
5982
  x-required-scopes:
5896
5983
  - subscriptions:write
5897
5984
  x-idempotency:
5898
- required: true
5985
+ required: false
5899
5986
  retention_seconds: 604800
5900
5987
  scope:
5901
5988
  - authenticated_project_environment
@@ -6056,7 +6143,7 @@ paths:
6056
6143
  x-required-scopes:
6057
6144
  - subscriptions:write
6058
6145
  x-idempotency:
6059
- required: true
6146
+ required: false
6060
6147
  retention_seconds: 604800
6061
6148
  scope:
6062
6149
  - authenticated_project_environment
@@ -6099,10 +6186,7 @@ paths:
6099
6186
  in: path
6100
6187
  required: true
6101
6188
  schema:
6102
- type: string
6103
- minLength: 1
6104
- maxLength: 63
6105
- pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$"
6189
+ $ref: "../schemas/whooshbang-v1.schema.json#/$defs/GroupKey"
6106
6190
  get:
6107
6191
  operationId: getSubscriberGroup
6108
6192
  summary: Read one static subscriber group
@@ -6194,10 +6278,7 @@ paths:
6194
6278
  in: path
6195
6279
  required: true
6196
6280
  schema:
6197
- type: string
6198
- minLength: 1
6199
- maxLength: 63
6200
- pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$"
6281
+ $ref: "../schemas/whooshbang-v1.schema.json#/$defs/GroupKey"
6201
6282
  get:
6202
6283
  operationId: listSubscriberGroupMembers
6203
6284
  summary: List active membership generations with bounded pagination
@@ -6248,10 +6329,7 @@ paths:
6248
6329
  in: path
6249
6330
  required: true
6250
6331
  schema:
6251
- type: string
6252
- minLength: 1
6253
- maxLength: 63
6254
- pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$"
6332
+ $ref: "../schemas/whooshbang-v1.schema.json#/$defs/GroupKey"
6255
6333
  - name: subscriber_id
6256
6334
  in: path
6257
6335
  required: true
@@ -6310,10 +6388,7 @@ paths:
6310
6388
  in: path
6311
6389
  required: true
6312
6390
  schema:
6313
- type: string
6314
- minLength: 1
6315
- maxLength: 63
6316
- pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$"
6391
+ $ref: "../schemas/whooshbang-v1.schema.json#/$defs/GroupKey"
6317
6392
  post:
6318
6393
  operationId: createGroupBroadcast
6319
6394
  summary: Accept one durable broadcast at the group's current membership revision
@@ -6329,7 +6404,7 @@ paths:
6329
6404
  x-required-scopes:
6330
6405
  - messages:write
6331
6406
  x-idempotency:
6332
- required: true
6407
+ required: false
6333
6408
  retention_seconds: 604800
6334
6409
  scope:
6335
6410
  - authenticated_project_environment
@@ -6451,7 +6526,7 @@ paths:
6451
6526
  x-required-scopes:
6452
6527
  - subscriptions:write
6453
6528
  x-idempotency:
6454
- required: true
6529
+ required: false
6455
6530
  retention_seconds: 604800
6456
6531
  scope:
6457
6532
  - authenticated_organization
@@ -6633,7 +6708,7 @@ paths:
6633
6708
  x-required-scopes:
6634
6709
  - messages:write
6635
6710
  x-idempotency:
6636
- required: true
6711
+ required: false
6637
6712
  retention_seconds: 604800
6638
6713
  scope:
6639
6714
  - authenticated_organization
@@ -6683,18 +6758,25 @@ paths:
6683
6758
  - $ref: "#/components/parameters/MessageId"
6684
6759
  get:
6685
6760
  operationId: getMessageInEnvironment
6761
+ x-notification-scopes: [notifications:self, notifications:team]
6686
6762
  summary: Inspect a message in a named project environment
6687
6763
  description: |
6688
6764
  The environment-scoped form of `getMessage`, including the same bounded
6689
6765
  long poll. Inspection acknowledges, consumes, retries, and replays
6690
6766
  nothing.
6767
+ Notification grants can read only current operator recipients in their
6768
+ audience: self means the signed-in person; team includes current
6769
+ teammates with access to this project. Customer subscribers and retired
6770
+ memberships are hidden with 404, including during a held poll.
6691
6771
  parameters:
6692
6772
  - $ref: "#/components/parameters/ResponseInspectionWait"
6693
6773
  tags:
6694
6774
  - Messages
6695
6775
  security:
6696
6776
  - clerkSession: []
6697
- - bearerGrant: []
6777
+ - bearerGrant: [messages:read]
6778
+ - bearerGrant: [notifications:self]
6779
+ - bearerGrant: [notifications:team]
6698
6780
  - bearerOrganizationCredential: []
6699
6781
  x-required-scopes:
6700
6782
  - messages:read
@@ -6728,16 +6810,23 @@ paths:
6728
6810
  - $ref: "#/components/parameters/InteractionId"
6729
6811
  get:
6730
6812
  operationId: getInteractionInEnvironment
6813
+ x-notification-scopes: [notifications:self, notifications:team]
6731
6814
  summary: Inspect an interaction response in a named project environment
6732
6815
  description: |
6733
6816
  The environment-scoped form of `getInteraction`, including the same
6734
6817
  bounded long poll and the same retained-answer semantics.
6818
+ Notification grants can read only current operator recipients in their
6819
+ audience: self means the signed-in person; team includes current
6820
+ teammates with access to this project. Customer subscribers and retired
6821
+ memberships are hidden with 404, including during a held poll.
6735
6822
  parameters:
6736
6823
  - $ref: "#/components/parameters/ResponseInspectionWait"
6737
6824
  tags:
6738
6825
  - Messages
6739
6826
  security:
6740
- - bearerGrant: []
6827
+ - bearerGrant: [messages:read]
6828
+ - bearerGrant: [notifications:self]
6829
+ - bearerGrant: [notifications:team]
6741
6830
  - bearerOrganizationCredential: []
6742
6831
  x-required-scopes:
6743
6832
  - messages:read
@@ -6883,7 +6972,7 @@ paths:
6883
6972
  x-required-scopes:
6884
6973
  - machine-clients:write
6885
6974
  x-idempotency:
6886
- required: true
6975
+ required: false
6887
6976
  retention_seconds: 604800
6888
6977
  scope:
6889
6978
  - authenticated_organization
@@ -6947,7 +7036,7 @@ paths:
6947
7036
  x-required-scopes:
6948
7037
  - machine-clients:write
6949
7038
  x-idempotency:
6950
- required: true
7039
+ required: false
6951
7040
  retention_seconds: 604800
6952
7041
  scope:
6953
7042
  - authenticated_environment
@@ -7057,7 +7146,7 @@ paths:
7057
7146
  x-required-scopes:
7058
7147
  - subscriptions:write
7059
7148
  x-idempotency:
7060
- required: true
7149
+ required: false
7061
7150
  retention_seconds: 604800
7062
7151
  scope:
7063
7152
  - authenticated_project_environment
@@ -7165,7 +7254,7 @@ paths:
7165
7254
  environment asked about. Combines with every other filter, so `q`
7166
7255
  searches within the group.
7167
7256
  schema:
7168
- $ref: "../schemas/whooshbang-v1.schema.json#/$defs/DeveloperKey"
7257
+ $ref: "../schemas/whooshbang-v1.schema.json#/$defs/GroupKey"
7169
7258
  - name: created_after
7170
7259
  in: query
7171
7260
  required: false
@@ -7225,7 +7314,7 @@ paths:
7225
7314
  x-required-scopes:
7226
7315
  - subscriptions:write
7227
7316
  x-idempotency:
7228
- required: true
7317
+ required: false
7229
7318
  retention_seconds: 604800
7230
7319
  scope:
7231
7320
  - authenticated_project_environment
@@ -7508,7 +7597,7 @@ paths:
7508
7597
  x-required-scopes:
7509
7598
  - subscriptions:write
7510
7599
  x-idempotency:
7511
- required: true
7600
+ required: false
7512
7601
  retention_seconds: 604800
7513
7602
  scope:
7514
7603
  - authenticated_project_environment
@@ -7553,10 +7642,7 @@ paths:
7553
7642
  in: path
7554
7643
  required: true
7555
7644
  schema:
7556
- type: string
7557
- minLength: 1
7558
- maxLength: 63
7559
- pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$"
7645
+ $ref: "../schemas/whooshbang-v1.schema.json#/$defs/GroupKey"
7560
7646
  get:
7561
7647
  operationId: getSubscriberGroupInEnvironment
7562
7648
  summary: Read one static subscriber group in a named project environment
@@ -7669,10 +7755,7 @@ paths:
7669
7755
  in: path
7670
7756
  required: true
7671
7757
  schema:
7672
- type: string
7673
- minLength: 1
7674
- maxLength: 63
7675
- pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$"
7758
+ $ref: "../schemas/whooshbang-v1.schema.json#/$defs/GroupKey"
7676
7759
  get:
7677
7760
  operationId: listSubscriberGroupMembersInEnvironment
7678
7761
  summary: List active membership generations in a named project environment
@@ -7732,10 +7815,7 @@ paths:
7732
7815
  in: path
7733
7816
  required: true
7734
7817
  schema:
7735
- type: string
7736
- minLength: 1
7737
- maxLength: 63
7738
- pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$"
7818
+ $ref: "../schemas/whooshbang-v1.schema.json#/$defs/GroupKey"
7739
7819
  - name: subscriber_id
7740
7820
  in: path
7741
7821
  required: true
@@ -7810,10 +7890,7 @@ paths:
7810
7890
  in: path
7811
7891
  required: true
7812
7892
  schema:
7813
- type: string
7814
- minLength: 1
7815
- maxLength: 63
7816
- pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$"
7893
+ $ref: "../schemas/whooshbang-v1.schema.json#/$defs/GroupKey"
7817
7894
  post:
7818
7895
  operationId: createGroupBroadcastInEnvironment
7819
7896
  summary: Accept one durable broadcast in a named project environment
@@ -7832,7 +7909,7 @@ paths:
7832
7909
  x-required-scopes:
7833
7910
  - messages:write
7834
7911
  x-idempotency:
7835
- required: true
7912
+ required: false
7836
7913
  retention_seconds: 604800
7837
7914
  scope:
7838
7915
  - authenticated_project_environment
@@ -8247,7 +8324,7 @@ paths:
8247
8324
  - bearerOrganizationCredential: []
8248
8325
  x-required-scopes: [machine-clients:write]
8249
8326
  x-idempotency:
8250
- required: true
8327
+ required: false
8251
8328
  retention_seconds: 604800
8252
8329
  scope: [authenticated_environment, operation_id, key]
8253
8330
  equivalence: validated_request_after_documented_defaults
@@ -8315,6 +8392,395 @@ paths:
8315
8392
  $ref: "#/components/responses/Conflict"
8316
8393
  "429":
8317
8394
  $ref: "#/components/responses/RateLimited"
8395
+ /v1/operator-messages:
8396
+ post:
8397
+ operationId: sendOperatorMessageWithCredential
8398
+ summary: sendOperatorMessage
8399
+ description: >-
8400
+ Message a current teammate by name or operator ID. Personal callers may omit recipient or use
8401
+ me. Shared credentials must name a recipient. Runtime machine credentials report
8402
+ recipient_required for omitted or me; named operator sends are forbidden because runtime
8403
+ authority remains subscriber-bound.
8404
+ tags:
8405
+ - Operators
8406
+ security:
8407
+ - bearerCredential: []
8408
+ x-required-scopes:
8409
+ - messages:write
8410
+ parameters:
8411
+ - $ref: "#/components/parameters/IdempotencyKey"
8412
+ requestBody:
8413
+ required: true
8414
+ content:
8415
+ application/json:
8416
+ schema:
8417
+ $ref: "#/components/schemas/CreateOperatorMessageRequest"
8418
+ responses:
8419
+ "200":
8420
+ description: Authorized result.
8421
+ content:
8422
+ application/json:
8423
+ schema:
8424
+ $ref: "#/components/schemas/OperatorMessageResult"
8425
+ "401":
8426
+ $ref: "#/components/responses/Unauthorized"
8427
+ "403":
8428
+ $ref: "#/components/responses/Forbidden"
8429
+ /v1/operators/broadcasts:
8430
+ post:
8431
+ operationId: broadcastOperatorsWithCredential
8432
+ summary: broadcastOperators
8433
+ description: >-
8434
+ Membership-derived operator messaging. Only the authenticated human can manage personal
8435
+ preferences.
8436
+ tags:
8437
+ - Operators
8438
+ security:
8439
+ - bearerCredential: []
8440
+ x-required-scopes:
8441
+ - messages:write
8442
+ parameters:
8443
+ - $ref: "#/components/parameters/IdempotencyKey"
8444
+ requestBody:
8445
+ required: true
8446
+ content:
8447
+ application/json:
8448
+ schema:
8449
+ $ref: "#/components/schemas/CreateGroupBroadcastRequest"
8450
+ responses:
8451
+ "200":
8452
+ description: Authorized result.
8453
+ content:
8454
+ application/json:
8455
+ schema:
8456
+ $ref: "#/components/schemas/OperatorBroadcast"
8457
+ "401":
8458
+ $ref: "#/components/responses/Unauthorized"
8459
+ "403":
8460
+ $ref: "#/components/responses/Forbidden"
8461
+ /v1/operators/broadcasts/{broadcast_id}:
8462
+ get:
8463
+ operationId: getOperatorBroadcastWithCredential
8464
+ summary: getOperatorBroadcast
8465
+ description: >-
8466
+ Membership-derived operator messaging. Only the authenticated human can manage personal
8467
+ preferences.
8468
+ tags:
8469
+ - Operators
8470
+ security:
8471
+ - bearerCredential: []
8472
+ x-required-scopes:
8473
+ - messages:read
8474
+ parameters:
8475
+ - name: broadcast_id
8476
+ in: path
8477
+ required: true
8478
+ schema:
8479
+ type: string
8480
+ responses:
8481
+ "200":
8482
+ description: Authorized result.
8483
+ content:
8484
+ application/json:
8485
+ schema:
8486
+ $ref: "#/components/schemas/OperatorBroadcast"
8487
+ "401":
8488
+ $ref: "#/components/responses/Unauthorized"
8489
+ "403":
8490
+ $ref: "#/components/responses/Forbidden"
8491
+ /v1/customer-endpoints:
8492
+ get:
8493
+ operationId: listCustomerEndpointsWithCredential
8494
+ summary: List safe customer-endpoint health metadata
8495
+ tags:
8496
+ - Customer endpoints
8497
+ security:
8498
+ - bearerCredential: []
8499
+ x-required-scopes:
8500
+ - messages:read
8501
+ parameters:
8502
+ - $ref: "#/components/parameters/ListAfterCursor"
8503
+ - $ref: "#/components/parameters/ListPageLimit"
8504
+ - $ref: "#/components/parameters/PageNumber"
8505
+ responses:
8506
+ "200":
8507
+ description: Safe endpoint lifecycle and health metadata without URLs or protected content.
8508
+ headers:
8509
+ WhooshBang-Diagnostic-Id:
8510
+ $ref: "#/components/headers/DiagnosticId"
8511
+ content:
8512
+ application/json:
8513
+ schema:
8514
+ $ref: "#/components/schemas/CustomerEndpointCollection"
8515
+ examples:
8516
+ endpoints:
8517
+ externalValue: ../fixtures/core-v1/success/customer-endpoint-collection.json
8518
+ "401":
8519
+ $ref: "#/components/responses/Unauthorized"
8520
+ "403":
8521
+ $ref: "#/components/responses/Forbidden"
8522
+ "404":
8523
+ $ref: "#/components/responses/NotFound"
8524
+ post:
8525
+ operationId: createCustomerEndpointWithCredential
8526
+ summary: Create an active customer endpoint and reveal its signing secret once
8527
+ description: >-
8528
+ Creates an active endpoint and sends a signed diagnostic ping. A 2xx acknowledges the ping; no
8529
+ echo handshake is required. SSRF destination validation applies.
8530
+ tags:
8531
+ - Customer endpoints
8532
+ security:
8533
+ - bearerCredential: []
8534
+ x-required-scopes:
8535
+ - messages:write
8536
+ x-idempotency:
8537
+ required: false
8538
+ retention_seconds: 604800
8539
+ scope:
8540
+ - authenticated_environment
8541
+ - operation_id
8542
+ - key
8543
+ equivalence: final_normalized_url_and_validated_request
8544
+ replay_retention_extends: false
8545
+ x-secret-reveal:
8546
+ responses: 1
8547
+ replayable: false
8548
+ later_reads: metadata_only
8549
+ parameters:
8550
+ - $ref: "#/components/parameters/IdempotencyKey"
8551
+ requestBody:
8552
+ required: true
8553
+ content:
8554
+ application/json:
8555
+ schema:
8556
+ $ref: "#/components/schemas/CreateCustomerEndpointRequest"
8557
+ examples:
8558
+ createEndpoint:
8559
+ externalValue: ../fixtures/core-v1/requests/create-customer-endpoint.json
8560
+ responses:
8561
+ "200":
8562
+ description: Equivalent replay returning safe endpoint metadata without the secret.
8563
+ content:
8564
+ application/json:
8565
+ schema:
8566
+ $ref: "#/components/schemas/CustomerEndpointMutationResult"
8567
+ examples:
8568
+ replayed:
8569
+ externalValue: ../fixtures/core-v1/success/customer-endpoint-create-replayed.json
8570
+ "201":
8571
+ description: Newly active endpoint, recorded signed ping result, and its one-time signing secret.
8572
+ headers:
8573
+ WhooshBang-Diagnostic-Id:
8574
+ $ref: "#/components/headers/DiagnosticId"
8575
+ content:
8576
+ application/json:
8577
+ schema:
8578
+ $ref: "#/components/schemas/CustomerEndpointMutationResult"
8579
+ examples:
8580
+ created:
8581
+ externalValue: ../fixtures/core-v1/success/customer-endpoint-created.json
8582
+ "400":
8583
+ $ref: "#/components/responses/BadRequest"
8584
+ "401":
8585
+ $ref: "#/components/responses/Unauthorized"
8586
+ "403":
8587
+ $ref: "#/components/responses/Forbidden"
8588
+ "404":
8589
+ $ref: "#/components/responses/NotFound"
8590
+ "409":
8591
+ $ref: "#/components/responses/Conflict"
8592
+ "503":
8593
+ $ref: "#/components/responses/ProviderRetryable"
8594
+ /v1/customer-endpoints/{endpoint_id}:
8595
+ parameters:
8596
+ - $ref: "#/components/parameters/CustomerEndpointId"
8597
+ get:
8598
+ operationId: getCustomerEndpointWithCredential
8599
+ summary: Read safe lifecycle and health metadata for one endpoint
8600
+ tags:
8601
+ - Customer endpoints
8602
+ security:
8603
+ - bearerCredential: []
8604
+ x-required-scopes:
8605
+ - messages:read
8606
+ responses:
8607
+ "200":
8608
+ description: Safe endpoint metadata.
8609
+ content:
8610
+ application/json:
8611
+ schema:
8612
+ $ref: "#/components/schemas/CustomerEndpoint"
8613
+ "401":
8614
+ $ref: "#/components/responses/Unauthorized"
8615
+ "403":
8616
+ $ref: "#/components/responses/Forbidden"
8617
+ "404":
8618
+ $ref: "#/components/responses/NotFound"
8619
+ /v1/customer-endpoints/{endpoint_id}/verify:
8620
+ parameters:
8621
+ - $ref: "#/components/parameters/CustomerEndpointId"
8622
+ post:
8623
+ operationId: verifyCustomerEndpointWithCredential
8624
+ summary: Send a signed test ping and record whether the receiver returns 2xx
8625
+ tags:
8626
+ - Customer endpoints
8627
+ security:
8628
+ - bearerCredential: []
8629
+ x-required-scopes:
8630
+ - messages:write
8631
+ responses:
8632
+ "200":
8633
+ description: Verified active endpoint metadata.
8634
+ content:
8635
+ application/json:
8636
+ schema:
8637
+ $ref: "#/components/schemas/CustomerEndpoint"
8638
+ "401":
8639
+ $ref: "#/components/responses/Unauthorized"
8640
+ "403":
8641
+ $ref: "#/components/responses/Forbidden"
8642
+ "404":
8643
+ $ref: "#/components/responses/NotFound"
8644
+ "502":
8645
+ $ref: "#/components/responses/ProviderTerminal"
8646
+ "503":
8647
+ $ref: "#/components/responses/ProviderRetryable"
8648
+ /v1/customer-endpoints/{endpoint_id}/rotate:
8649
+ parameters:
8650
+ - $ref: "#/components/parameters/CustomerEndpointId"
8651
+ post:
8652
+ operationId: rotateCustomerEndpointWithCredential
8653
+ summary: Create a new signing version with bounded old/new overlap
8654
+ tags:
8655
+ - Customer endpoints
8656
+ security:
8657
+ - bearerCredential: []
8658
+ x-required-scopes:
8659
+ - messages:write
8660
+ x-idempotency:
8661
+ required: false
8662
+ retention_seconds: 604800
8663
+ scope:
8664
+ - authenticated_environment
8665
+ - operation_id
8666
+ - key
8667
+ equivalence: endpoint_and_validated_request
8668
+ replay_retention_extends: false
8669
+ x-secret-reveal:
8670
+ responses: 1
8671
+ replayable: false
8672
+ later_reads: metadata_only
8673
+ parameters:
8674
+ - $ref: "#/components/parameters/IdempotencyKey"
8675
+ requestBody:
8676
+ required: true
8677
+ content:
8678
+ application/json:
8679
+ schema:
8680
+ $ref: "#/components/schemas/RotateCustomerEndpointRequest"
8681
+ examples:
8682
+ rotate:
8683
+ externalValue: ../fixtures/core-v1/requests/rotate-customer-endpoint.json
8684
+ responses:
8685
+ "200":
8686
+ description: Equivalent replay without another secret reveal.
8687
+ content:
8688
+ application/json:
8689
+ schema:
8690
+ $ref: "#/components/schemas/CustomerEndpointMutationResult"
8691
+ "201":
8692
+ description: Rotated endpoint and one-time new secret.
8693
+ content:
8694
+ application/json:
8695
+ schema:
8696
+ $ref: "#/components/schemas/CustomerEndpointMutationResult"
8697
+ examples:
8698
+ rotated:
8699
+ externalValue: ../fixtures/core-v1/success/customer-endpoint-rotated.json
8700
+ "400":
8701
+ $ref: "#/components/responses/BadRequest"
8702
+ "401":
8703
+ $ref: "#/components/responses/Unauthorized"
8704
+ "403":
8705
+ $ref: "#/components/responses/Forbidden"
8706
+ "404":
8707
+ $ref: "#/components/responses/NotFound"
8708
+ "409":
8709
+ $ref: "#/components/responses/EndpointRotationConflict"
8710
+ /v1/customer-endpoints/{endpoint_id}/{action}:
8711
+ parameters:
8712
+ - $ref: "#/components/parameters/CustomerEndpointId"
8713
+ - name: action
8714
+ in: path
8715
+ required: true
8716
+ schema:
8717
+ type: string
8718
+ enum:
8719
+ - pause
8720
+ - resume
8721
+ - disable
8722
+ post:
8723
+ operationId: transitionCustomerEndpointWithCredential
8724
+ summary: Pause, resume, or terminally disable an endpoint
8725
+ tags:
8726
+ - Customer endpoints
8727
+ security:
8728
+ - bearerCredential: []
8729
+ x-required-scopes:
8730
+ - messages:write
8731
+ x-repeat-semantics:
8732
+ same_target: idempotent
8733
+ secret_returned: false
8734
+ responses:
8735
+ "200":
8736
+ description: Updated safe endpoint metadata.
8737
+ content:
8738
+ application/json:
8739
+ schema:
8740
+ $ref: "#/components/schemas/CustomerEndpoint"
8741
+ "400":
8742
+ $ref: "#/components/responses/BadRequest"
8743
+ "401":
8744
+ $ref: "#/components/responses/Unauthorized"
8745
+ "403":
8746
+ $ref: "#/components/responses/Forbidden"
8747
+ "404":
8748
+ $ref: "#/components/responses/NotFound"
8749
+ description: >-
8750
+ Creates an active endpoint and sends a signed diagnostic ping. A 2xx acknowledges the ping; no
8751
+ echo handshake is required. SSRF destination validation applies.
8752
+ /v1/customer-endpoints/{endpoint_id}/attempts:
8753
+ parameters:
8754
+ - $ref: "#/components/parameters/CustomerEndpointId"
8755
+ get:
8756
+ operationId: listCustomerEndpointAttemptsWithCredential
8757
+ summary: Inspect protected content-free delivery diagnostics
8758
+ tags:
8759
+ - Customer endpoints
8760
+ security:
8761
+ - bearerCredential: []
8762
+ x-required-scopes:
8763
+ - messages:read
8764
+ parameters:
8765
+ - $ref: "#/components/parameters/ListAfterCursor"
8766
+ - $ref: "#/components/parameters/ListPageLimit"
8767
+ - $ref: "#/components/parameters/PageNumber"
8768
+ responses:
8769
+ "200":
8770
+ description: Safe status, timing, and failure categories only.
8771
+ content:
8772
+ application/json:
8773
+ schema:
8774
+ $ref: "#/components/schemas/CustomerEndpointAttemptCollection"
8775
+ examples:
8776
+ attempts:
8777
+ externalValue: ../fixtures/core-v1/success/customer-endpoint-attempts.json
8778
+ "401":
8779
+ $ref: "#/components/responses/Unauthorized"
8780
+ "403":
8781
+ $ref: "#/components/responses/Forbidden"
8782
+ "404":
8783
+ $ref: "#/components/responses/NotFound"
8318
8784
  components:
8319
8785
  securitySchemes:
8320
8786
  clerkSession:
@@ -8390,9 +8856,11 @@ components:
8390
8856
  IdempotencyKey:
8391
8857
  name: Idempotency-Key
8392
8858
  in: header
8393
- required: true
8859
+ required: false
8394
8860
  description: |
8395
- Visible ASCII key retained for seven days from first acceptance.
8861
+ Optional visible ASCII key retained for seven days from first acceptance.
8862
+ A retry with the same key returns the original result and never acts twice.
8863
+ Without a key each request is new.
8396
8864
  Equivalent replay returns the original status and logical resource;
8397
8865
  materially different validated input returns `idempotency_conflict`.
8398
8866
  schema:
@@ -8754,6 +9222,12 @@ components:
8754
9222
  $ref: "../schemas/whooshbang-v1.schema.json#/$defs/BillingProjectSlots"
8755
9223
  AssignBillingProjectSlotsRequest:
8756
9224
  $ref: "../schemas/whooshbang-v1.schema.json#/$defs/AssignBillingProjectSlotsRequest"
9225
+ BillingPromotions:
9226
+ $ref: "../schemas/whooshbang-v1.schema.json#/$defs/BillingPromotions"
9227
+ BillingPromotion:
9228
+ $ref: "../schemas/whooshbang-v1.schema.json#/$defs/BillingPromotion"
9229
+ RedeemBillingPromotionRequest:
9230
+ $ref: "../schemas/whooshbang-v1.schema.json#/$defs/RedeemBillingPromotionRequest"
8757
9231
  BillingEntitlements:
8758
9232
  $ref: "../schemas/whooshbang-v1.schema.json#/$defs/BillingEntitlements"
8759
9233
  SubscriptionSelection: