@whooshbang/contracts 2.0.0-rc.7 → 2.0.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 (97) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/README.md +4 -5
  3. package/contract-manifest.json +33 -32
  4. package/dist/generated/artifact-index.d.ts +34 -34
  5. package/dist/generated/artifact-index.js +33 -32
  6. package/dist/generated/artifact-index.js.map +1 -1
  7. package/dist/generated/validators-standalone.d.ts +488 -437
  8. package/dist/generated/validators-standalone.js +40130 -29709
  9. package/dist/generated/validators-standalone.js.map +1 -1
  10. package/dist/generated/validators.d.ts +5 -1
  11. package/dist/generated/validators.js +9 -2
  12. package/dist/generated/validators.js.map +1 -1
  13. package/dist/generated/whooshbang-event-v1.d.ts +34 -18
  14. package/dist/generated/whooshbang-v1.d.ts +220 -45
  15. package/dist/index.d.ts +2 -2
  16. package/dist/index.js +1 -1
  17. package/dist/index.js.map +1 -1
  18. package/fixtures/core-v1/fixture-index.json +7 -1
  19. package/fixtures/core-v1/requests/assert-email-service.json +10 -0
  20. package/fixtures/core-v1/scenarios/api-credential-invalid-indistinguishable.json +1 -1
  21. package/fixtures/core-v1/scenarios/api-credential-one-time-reveal.json +1 -1
  22. package/fixtures/core-v1/scenarios/api-credential-revocation-replay.json +1 -1
  23. package/fixtures/core-v1/scenarios/api-credential-rotation-overlap.json +1 -1
  24. package/fixtures/core-v1/scenarios/cancellation-too-late.json +1 -1
  25. package/fixtures/core-v1/scenarios/cross-organization-project.json +1 -1
  26. package/fixtures/core-v1/scenarios/cross-project-resource.json +1 -1
  27. package/fixtures/core-v1/scenarios/environment-mismatch.json +1 -1
  28. package/fixtures/core-v1/scenarios/idempotency-conflict.json +1 -1
  29. package/fixtures/core-v1/scenarios/idempotency-equivalent-replay.json +1 -1
  30. package/fixtures/core-v1/scenarios/malformed-bearer.json +1 -1
  31. package/fixtures/core-v1/scenarios/metadata-overrun.json +1 -1
  32. package/fixtures/core-v1/scenarios/missing-scope.json +1 -1
  33. package/fixtures/core-v1/scenarios/project-create-equivalent-replay.json +1 -1
  34. package/fixtures/core-v1/scenarios/project-slug-conflict.json +1 -1
  35. package/fixtures/core-v1/scenarios/provider-outcome-unknown.json +1 -1
  36. package/fixtures/core-v1/scenarios/subscription-activation-replay.json +1 -1
  37. package/fixtures/core-v1/scenarios/subscription-authorization-capability-opacity.json +1 -1
  38. package/fixtures/core-v1/scenarios/subscription-cross-connection-callback-rejected.json +1 -1
  39. package/fixtures/core-v1/scenarios/subscription-expired-replay.json +1 -1
  40. package/fixtures/core-v1/scenarios/subscription-selected-connection-replay.json +1 -1
  41. package/fixtures/core-v1/success/subscription-change.json +1 -1
  42. package/fixtures/interaction-machine-v1/scenarios/ack-conflict.json +1 -1
  43. package/fixtures/interaction-machine-v1/scenarios/ack-cross-machine.json +1 -1
  44. package/fixtures/interaction-machine-v1/scenarios/ack-out-of-order.json +1 -1
  45. package/fixtures/interaction-machine-v1/scenarios/ack-replay.json +1 -1
  46. package/fixtures/interaction-machine-v1/scenarios/ambiguous-free-text.json +1 -1
  47. package/fixtures/interaction-machine-v1/scenarios/callback-token-opacity.json +1 -1
  48. package/fixtures/interaction-machine-v1/scenarios/credential-registration-conflict.json +1 -1
  49. package/fixtures/interaction-machine-v1/scenarios/credential-registration-replay.json +1 -1
  50. package/fixtures/interaction-machine-v1/scenarios/credential-revocation-replay.json +1 -1
  51. package/fixtures/interaction-machine-v1/scenarios/credential-rotation.json +1 -1
  52. package/fixtures/interaction-machine-v1/scenarios/first-credential-activates.json +1 -1
  53. package/fixtures/interaction-machine-v1/scenarios/interaction-duplicate.json +1 -1
  54. package/fixtures/interaction-machine-v1/scenarios/interaction-expired.json +1 -1
  55. package/fixtures/interaction-machine-v1/scenarios/interaction-mismatch.json +1 -1
  56. package/fixtures/interaction-machine-v1/scenarios/interaction-retired.json +1 -1
  57. package/fixtures/interaction-machine-v1/scenarios/interaction-stale.json +1 -1
  58. package/fixtures/interaction-machine-v1/scenarios/machine-admin-denied.json +1 -1
  59. package/fixtures/interaction-machine-v1/scenarios/machine-bound-message-create.json +1 -1
  60. package/fixtures/interaction-machine-v1/scenarios/machine-cancel-denied.json +1 -1
  61. package/fixtures/interaction-machine-v1/scenarios/machine-crash-before-ack.json +1 -1
  62. package/fixtures/interaction-machine-v1/scenarios/machine-notifier-mismatch.json +1 -1
  63. package/fixtures/interaction-machine-v1/scenarios/machine-other-message-read.json +1 -1
  64. package/fixtures/interaction-machine-v1/scenarios/machine-owned-message-read.json +1 -1
  65. package/fixtures/interaction-machine-v1/scenarios/machine-subscriber-mismatch.json +1 -1
  66. package/fixtures/interaction-machine-v1/scenarios/poll-uncommitted-cursor-rejected.json +1 -1
  67. package/fixtures/interaction-machine-v1/scenarios/project-credential-machine-endpoint-denied.json +1 -1
  68. package/fixtures/interaction-machine-v1/scenarios/quarantine-integrity-rejected.json +1 -1
  69. package/fixtures/interaction-machine-v1/scenarios/quarantine-signature-rejected.json +1 -1
  70. package/fixtures/interaction-machine-v1/scenarios/quarantine-valid.json +1 -1
  71. package/fixtures/interaction-machine-v1/scenarios/revoked-machine-credential.json +1 -1
  72. package/fixtures/recipient-experience-v1/scenarios/membership-broadcast-snapshot.json +1 -1
  73. package/fixtures/recipient-experience-v1/scenarios/preferred-binding-resolution.json +1 -1
  74. package/fixtures/recipient-experience-v1/scenarios/recipient-session-security.json +1 -1
  75. package/fixtures/recipient-experience-v1/scenarios/subscriber-initial-groups-transaction.json +1 -1
  76. package/openapi/generated/whooshbang-v1.bundle.json +630 -48
  77. package/openapi/whooshbang-v1.yaml +230 -5
  78. package/package.json +2 -3
  79. package/schemas/core-scenario.schema.json +1 -1
  80. package/schemas/events/agent-binding-degraded-v1.schema.json +1 -1
  81. package/schemas/events/interaction-expired-v1.schema.json +1 -1
  82. package/schemas/events/interaction-received-v1.schema.json +1 -1
  83. package/schemas/events/message-delivered-v1.schema.json +1 -1
  84. package/schemas/events/message-expired-v1.schema.json +1 -1
  85. package/schemas/events/message-failed-v1.schema.json +1 -1
  86. package/schemas/events/message-provider-accepted-v1.schema.json +1 -1
  87. package/schemas/events/subscription-activated-v1.schema.json +1 -1
  88. package/schemas/events/subscription-revoked-v1.schema.json +1 -1
  89. package/schemas/events/whooshbang-event-v1.schema.json +145 -65
  90. package/schemas/fixture-index.schema.json +1 -1
  91. package/schemas/interaction-machine-scenario.schema.json +1 -1
  92. package/schemas/interaction-v1.schema.json +1 -1
  93. package/schemas/machine-v1.schema.json +1 -1
  94. package/schemas/provider-capabilities-v1.schema.json +1 -1
  95. package/schemas/webhooks/webhook-delivery-case-v1.schema.json +1 -1
  96. package/schemas/webhooks/webhook-signing-vector-v1.schema.json +1 -1
  97. package/schemas/whooshbang-v1.schema.json +552 -53
@@ -1,13 +1,25 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://whooshbang.flowxo.com/schemas/whooshbang-v1.schema.json",
4
- "x-contract-version": "2.0.0-rc.7",
4
+ "x-contract-version": "2.0.0",
5
5
  "title": "WhooshBangV1ContractDocument",
6
6
  "description": "Public request, resource, summary, and Problem Details models for the WhooshBang V1 REST API.",
7
7
  "anyOf": [
8
8
  {
9
9
  "$ref": "#/$defs/OrganizationProjection"
10
10
  },
11
+ {
12
+ "$ref": "#/$defs/Teammate"
13
+ },
14
+ {
15
+ "$ref": "#/$defs/TeammateCollection"
16
+ },
17
+ {
18
+ "$ref": "#/$defs/TeammateAccessRequest"
19
+ },
20
+ {
21
+ "$ref": "#/$defs/InviteTeammateRequest"
22
+ },
11
23
  {
12
24
  "$ref": "#/$defs/CloseOrganizationRequest"
13
25
  },
@@ -469,8 +481,8 @@
469
481
  },
470
482
  "OrganizationRole": {
471
483
  "type": "string",
472
- "enum": ["admin", "member"],
473
- "description": "The stable WhooshBang authorization role projected from the current Clerk organization membership."
484
+ "enum": ["admin", "member", "messenger"],
485
+ "description": "The person's WhooshBang role in the organization. `admin` does everything, including billing, API keys and teammates. `member` runs the projects they were given: channels, subscribers, messages and project settings. `messenger` sends messages and reads replies in the projects they were given. Clients must tolerate roles added later."
474
486
  },
475
487
  "OrganizationMembershipSummary": {
476
488
  "type": "object",
@@ -482,6 +494,217 @@
482
494
  },
483
495
  "additionalProperties": false
484
496
  },
497
+ "TeammateStatus": {
498
+ "type": "string",
499
+ "enum": ["active", "invited"],
500
+ "description": "`active` has joined. `invited` has an invitation they have not accepted."
501
+ },
502
+ "TeammateProjectAccess": {
503
+ "type": "object",
504
+ "description": "Which projects the teammate can see. An admin sees every project, including ones created later.",
505
+ "required": ["all", "project_ids"],
506
+ "properties": {
507
+ "all": {
508
+ "type": "boolean"
509
+ },
510
+ "project_ids": {
511
+ "type": "array",
512
+ "maxItems": 1000,
513
+ "uniqueItems": true,
514
+ "items": {
515
+ "$ref": "#/$defs/OpaqueIdentifier"
516
+ },
517
+ "description": "The projects given to this teammate. Empty when `all` is true."
518
+ }
519
+ },
520
+ "additionalProperties": false
521
+ },
522
+ "Teammate": {
523
+ "type": "object",
524
+ "description": "One person in the organization, or one invitation to it. Identity-provider identifiers are not public fields.",
525
+ "required": [
526
+ "id",
527
+ "status",
528
+ "role",
529
+ "name",
530
+ "email",
531
+ "projects",
532
+ "is_current_user",
533
+ "created_at"
534
+ ],
535
+ "properties": {
536
+ "id": {
537
+ "$ref": "#/$defs/OpaqueIdentifier"
538
+ },
539
+ "status": {
540
+ "$ref": "#/$defs/TeammateStatus"
541
+ },
542
+ "role": {
543
+ "$ref": "#/$defs/OrganizationRole"
544
+ },
545
+ "name": {
546
+ "anyOf": [
547
+ {
548
+ "type": "null"
549
+ },
550
+ {
551
+ "type": "string",
552
+ "minLength": 1,
553
+ "maxLength": 200
554
+ }
555
+ ],
556
+ "description": "The person's name, when they have given one. Null for an invitation."
557
+ },
558
+ "email": {
559
+ "anyOf": [
560
+ {
561
+ "type": "null"
562
+ },
563
+ {
564
+ "type": "string",
565
+ "minLength": 1,
566
+ "maxLength": 320
567
+ }
568
+ ],
569
+ "description": "The address the person signs in with, or the address invited."
570
+ },
571
+ "projects": {
572
+ "$ref": "#/$defs/TeammateProjectAccess"
573
+ },
574
+ "is_current_user": {
575
+ "type": "boolean",
576
+ "description": "Whether this is the person making the request."
577
+ },
578
+ "created_at": {
579
+ "$ref": "#/$defs/Timestamp",
580
+ "description": "When they joined, or when the invitation was sent."
581
+ },
582
+ "expires_at": {
583
+ "$ref": "#/$defs/Timestamp",
584
+ "description": "When an invitation stops working. Absent for an active teammate."
585
+ }
586
+ },
587
+ "additionalProperties": false
588
+ },
589
+ "TeammateCollection": {
590
+ "type": "object",
591
+ "description": "Everybody in the organization and every open invitation, people first.",
592
+ "required": ["items", "total"],
593
+ "properties": {
594
+ "items": {
595
+ "type": "array",
596
+ "maxItems": 100,
597
+ "items": {
598
+ "$ref": "#/$defs/Teammate"
599
+ }
600
+ },
601
+ "next_cursor": {
602
+ "type": "string",
603
+ "minLength": 1,
604
+ "maxLength": 256,
605
+ "pattern": "^[A-Za-z0-9_-]+$"
606
+ },
607
+ "page": {
608
+ "$ref": "#/$defs/ListPageNumber"
609
+ },
610
+ "page_size": {
611
+ "$ref": "#/$defs/ListPageSize"
612
+ },
613
+ "total": {
614
+ "$ref": "#/$defs/ListTotal"
615
+ }
616
+ },
617
+ "additionalProperties": false
618
+ },
619
+ "TeammateAccessRequest": {
620
+ "type": "object",
621
+ "description": "A role and, except for an admin, at least one project. An admin sees every project and takes no list.",
622
+ "required": ["role"],
623
+ "properties": {
624
+ "role": {
625
+ "$ref": "#/$defs/OrganizationRole"
626
+ },
627
+ "project_ids": {
628
+ "type": "array",
629
+ "maxItems": 1000,
630
+ "uniqueItems": true,
631
+ "items": {
632
+ "$ref": "#/$defs/OpaqueIdentifier"
633
+ }
634
+ }
635
+ },
636
+ "if": {
637
+ "properties": {
638
+ "role": {
639
+ "const": "admin"
640
+ }
641
+ }
642
+ },
643
+ "then": {
644
+ "properties": {
645
+ "project_ids": {
646
+ "type": "array",
647
+ "maxItems": 0
648
+ }
649
+ }
650
+ },
651
+ "else": {
652
+ "required": ["project_ids"],
653
+ "properties": {
654
+ "project_ids": {
655
+ "type": "array",
656
+ "minItems": 1
657
+ }
658
+ }
659
+ },
660
+ "additionalProperties": false
661
+ },
662
+ "InviteTeammateRequest": {
663
+ "type": "object",
664
+ "description": "Invites one person by email with their role and projects in one step.",
665
+ "required": ["email", "role"],
666
+ "properties": {
667
+ "email": {
668
+ "$ref": "#/$defs/EmailAddress"
669
+ },
670
+ "role": {
671
+ "$ref": "#/$defs/OrganizationRole"
672
+ },
673
+ "project_ids": {
674
+ "type": "array",
675
+ "maxItems": 1000,
676
+ "uniqueItems": true,
677
+ "items": {
678
+ "$ref": "#/$defs/OpaqueIdentifier"
679
+ }
680
+ }
681
+ },
682
+ "if": {
683
+ "properties": {
684
+ "role": {
685
+ "const": "admin"
686
+ }
687
+ }
688
+ },
689
+ "then": {
690
+ "properties": {
691
+ "project_ids": {
692
+ "type": "array",
693
+ "maxItems": 0
694
+ }
695
+ }
696
+ },
697
+ "else": {
698
+ "required": ["project_ids"],
699
+ "properties": {
700
+ "project_ids": {
701
+ "type": "array",
702
+ "minItems": 1
703
+ }
704
+ }
705
+ },
706
+ "additionalProperties": false
707
+ },
485
708
  "OrganizationProjection": {
486
709
  "type": "object",
487
710
  "description": "The current Clerk organization projected as a WhooshBang tenant. Clerk organization and user identifiers are not public fields.",
@@ -2316,6 +2539,185 @@
2316
2539
  },
2317
2540
  "additionalProperties": false,
2318
2541
  "description": "Address-free asserted consent captured on a message. The snapshot survives binding deletion; it never claims recipient verification."
2542
+ },
2543
+ {
2544
+ "type": "object",
2545
+ "required": [
2546
+ "id",
2547
+ "project_id",
2548
+ "environment",
2549
+ "subscriber_id",
2550
+ "notifier_id",
2551
+ "channel",
2552
+ "connection_id",
2553
+ "status",
2554
+ "address",
2555
+ "basis",
2556
+ "service"
2557
+ ],
2558
+ "properties": {
2559
+ "id": {
2560
+ "$ref": "#/$defs/OpaqueIdentifier"
2561
+ },
2562
+ "project_id": {
2563
+ "$ref": "#/$defs/OpaqueIdentifier"
2564
+ },
2565
+ "environment": {
2566
+ "$ref": "#/$defs/Environment"
2567
+ },
2568
+ "subscriber_id": {
2569
+ "$ref": "#/$defs/OpaqueIdentifier"
2570
+ },
2571
+ "notifier_id": {
2572
+ "$ref": "#/$defs/OpaqueIdentifier"
2573
+ },
2574
+ "channel": {
2575
+ "const": "email"
2576
+ },
2577
+ "connection_id": {
2578
+ "$ref": "#/$defs/OpaqueIdentifier"
2579
+ },
2580
+ "status": {
2581
+ "enum": ["active", "paused", "revoked"]
2582
+ },
2583
+ "address": {
2584
+ "$ref": "#/$defs/EmailAddress",
2585
+ "description": "The application-verified email destination enrolled for service notices."
2586
+ },
2587
+ "basis": {
2588
+ "const": "service"
2589
+ },
2590
+ "service": {
2591
+ "type": "object",
2592
+ "required": [
2593
+ "relationship_started_at",
2594
+ "source",
2595
+ "asserted_at",
2596
+ "asserted_by",
2597
+ "domain_id"
2598
+ ],
2599
+ "properties": {
2600
+ "source": {
2601
+ "type": "string",
2602
+ "minLength": 1,
2603
+ "maxLength": 100,
2604
+ "pattern": "^[^\u0000-\u001f-Ÿ

]+$"
2605
+ },
2606
+ "asserted_at": {
2607
+ "$ref": "#/$defs/Timestamp"
2608
+ },
2609
+ "asserted_by": {
2610
+ "type": "object",
2611
+ "required": ["kind", "id"],
2612
+ "properties": {
2613
+ "kind": {
2614
+ "enum": ["credential", "grant", "session"]
2615
+ },
2616
+ "id": {
2617
+ "$ref": "#/$defs/OpaqueIdentifier"
2618
+ }
2619
+ },
2620
+ "additionalProperties": false
2621
+ },
2622
+ "domain_id": {
2623
+ "$ref": "#/$defs/OpaqueIdentifier"
2624
+ },
2625
+ "relationship_started_at": {
2626
+ "$ref": "#/$defs/Timestamp"
2627
+ }
2628
+ },
2629
+ "additionalProperties": false
2630
+ }
2631
+ },
2632
+ "additionalProperties": false,
2633
+ "description": "Service relationship evidence. No consent claim. Address-free snapshots survive binding deletion."
2634
+ },
2635
+ {
2636
+ "type": "object",
2637
+ "required": [
2638
+ "id",
2639
+ "project_id",
2640
+ "environment",
2641
+ "subscriber_id",
2642
+ "notifier_id",
2643
+ "channel",
2644
+ "connection_id",
2645
+ "status",
2646
+ "basis",
2647
+ "service"
2648
+ ],
2649
+ "properties": {
2650
+ "id": {
2651
+ "$ref": "#/$defs/OpaqueIdentifier"
2652
+ },
2653
+ "project_id": {
2654
+ "$ref": "#/$defs/OpaqueIdentifier"
2655
+ },
2656
+ "environment": {
2657
+ "$ref": "#/$defs/Environment"
2658
+ },
2659
+ "subscriber_id": {
2660
+ "$ref": "#/$defs/OpaqueIdentifier"
2661
+ },
2662
+ "notifier_id": {
2663
+ "$ref": "#/$defs/OpaqueIdentifier"
2664
+ },
2665
+ "channel": {
2666
+ "const": "email"
2667
+ },
2668
+ "connection_id": {
2669
+ "$ref": "#/$defs/OpaqueIdentifier"
2670
+ },
2671
+ "status": {
2672
+ "enum": ["active", "paused", "revoked"]
2673
+ },
2674
+ "basis": {
2675
+ "const": "service"
2676
+ },
2677
+ "service": {
2678
+ "type": "object",
2679
+ "required": [
2680
+ "relationship_started_at",
2681
+ "source",
2682
+ "asserted_at",
2683
+ "asserted_by",
2684
+ "domain_id"
2685
+ ],
2686
+ "properties": {
2687
+ "source": {
2688
+ "type": "string",
2689
+ "minLength": 1,
2690
+ "maxLength": 100,
2691
+ "pattern": "^[^\u0000-\u001f-Ÿ

]+$"
2692
+ },
2693
+ "asserted_at": {
2694
+ "$ref": "#/$defs/Timestamp"
2695
+ },
2696
+ "asserted_by": {
2697
+ "type": "object",
2698
+ "required": ["kind", "id"],
2699
+ "properties": {
2700
+ "kind": {
2701
+ "enum": ["credential", "grant", "session"]
2702
+ },
2703
+ "id": {
2704
+ "$ref": "#/$defs/OpaqueIdentifier"
2705
+ }
2706
+ },
2707
+ "additionalProperties": false
2708
+ },
2709
+ "domain_id": {
2710
+ "$ref": "#/$defs/OpaqueIdentifier"
2711
+ },
2712
+ "relationship_started_at": {
2713
+ "$ref": "#/$defs/Timestamp"
2714
+ }
2715
+ },
2716
+ "additionalProperties": false
2717
+ }
2718
+ },
2719
+ "additionalProperties": false,
2720
+ "description": "Service relationship evidence. No consent claim. Address-free snapshots survive binding deletion."
2319
2721
  }
2320
2722
  ]
2321
2723
  },
@@ -3925,6 +4327,11 @@
3925
4327
  },
3926
4328
  "interaction": {
3927
4329
  "$ref": "interaction-v1.schema.json#/$defs/InteractionRequest"
4330
+ },
4331
+ "purpose": {
4332
+ "enum": ["service", "marketing"],
4333
+ "default": "service",
4334
+ "description": "Omitted means service. Marketing refuses service-only bindings before charging and at every delayed dispatch."
3928
4335
  }
3929
4336
  },
3930
4337
  "additionalProperties": false
@@ -4962,6 +5369,11 @@
4962
5369
  },
4963
5370
  "interaction": {
4964
5371
  "$ref": "interaction-v1.schema.json#/$defs/InteractionRequest"
5372
+ },
5373
+ "purpose": {
5374
+ "enum": ["service", "marketing"],
5375
+ "default": "service",
5376
+ "description": "Omitted means service. Marketing refuses service-only bindings before charging and at every delayed dispatch."
4965
5377
  }
4966
5378
  },
4967
5379
  "allOf": [
@@ -5186,6 +5598,11 @@
5186
5598
  "outcome_guidance": {
5187
5599
  "type": "string",
5188
5600
  "const": "Delivery may have been accepted by the provider. No automatic retry is scheduled; create a new message explicitly if another attempt is appropriate."
5601
+ },
5602
+ "purpose": {
5603
+ "enum": ["service", "marketing"],
5604
+ "default": "service",
5605
+ "description": "Omitted means service. Marketing refuses service-only bindings before charging and at every delayed dispatch."
5189
5606
  }
5190
5607
  },
5191
5608
  "allOf": [
@@ -5475,7 +5892,10 @@
5475
5892
  "type": "object",
5476
5893
  "properties": {
5477
5894
  "code": {
5478
- "const": "provider_terminal"
5895
+ "enum": [
5896
+ "provider_terminal",
5897
+ "not_consented_for_marketing"
5898
+ ]
5479
5899
  },
5480
5900
  "retryable": {
5481
5901
  "const": false
@@ -5582,7 +6002,8 @@
5582
6002
  "provider_retryable",
5583
6003
  "provider_terminal",
5584
6004
  "provider_outcome_unknown",
5585
- "internal_error"
6005
+ "internal_error",
6006
+ "not_consented_for_marketing"
5586
6007
  ]
5587
6008
  },
5588
6009
  "ProblemFieldError": {
@@ -6542,6 +6963,26 @@
6542
6963
  "const": true
6543
6964
  }
6544
6965
  }
6966
+ },
6967
+ {
6968
+ "type": "object",
6969
+ "properties": {
6970
+ "type": {
6971
+ "const": "https://whooshbang.flowxo.com/problems/not_consented_for_marketing"
6972
+ },
6973
+ "title": {
6974
+ "const": "Marketing consent required"
6975
+ },
6976
+ "status": {
6977
+ "const": 422
6978
+ },
6979
+ "code": {
6980
+ "const": "not_consented_for_marketing"
6981
+ },
6982
+ "retryable": {
6983
+ "const": false
6984
+ }
6985
+ }
6545
6986
  }
6546
6987
  ],
6547
6988
  "additionalProperties": false
@@ -6552,9 +6993,11 @@
6552
6993
  "projects:write",
6553
6994
  "projects:read",
6554
6995
  "billing:write",
6555
- "billing:read"
6996
+ "billing:read",
6997
+ "teammates:write",
6998
+ "teammates:read"
6556
6999
  ],
6557
- "description": "An organization-level capability carried by a human session or an OAuth grant. Billing scopes grant financial access separately from project configuration. Project and organization API credentials cannot administer billing."
7000
+ "description": "An organization-level capability carried by a human session or an OAuth grant. Teammate scopes reach the organization's people: who is in it, their roles and their projects. Billing scopes grant financial access separately from project configuration. Project and organization API credentials cannot administer billing."
6558
7001
  },
6559
7002
  "OAuthScope": {
6560
7003
  "description": "A scope an OAuth grant may carry. Project-level scopes are the credential vocabulary unchanged; organization-level scopes exist only here and on a human session.",
@@ -9113,49 +9556,100 @@
9113
9556
  "additionalProperties": false
9114
9557
  },
9115
9558
  "AssertEmailConsentRequest": {
9116
- "type": "object",
9117
- "description": "Atomically create or resolve one subscriber and assert existing consent for an exact customer-owned email connection and domain. No verification message is sent. Revocation, suppression, recipient pause, holds and unhealthy authority take precedence. An omitted source is recorded as customer.",
9118
- "required": [
9119
- "subscriber_id",
9120
- "notifier_id",
9121
- "connection_id",
9122
- "domain_id",
9123
- "address",
9124
- "consented",
9125
- "consented_at"
9126
- ],
9127
- "properties": {
9128
- "subscriber_id": {
9129
- "$ref": "#/$defs/OpaqueIdentifier"
9130
- },
9131
- "notifier_id": {
9132
- "$ref": "#/$defs/OpaqueIdentifier"
9133
- },
9134
- "connection_id": {
9135
- "$ref": "#/$defs/OpaqueIdentifier"
9136
- },
9137
- "domain_id": {
9138
- "$ref": "#/$defs/OpaqueIdentifier"
9139
- },
9140
- "address": {
9141
- "$ref": "#/$defs/EmailAddress"
9142
- },
9143
- "consented": {
9144
- "const": true
9145
- },
9146
- "consented_at": {
9147
- "$ref": "#/$defs/Timestamp",
9148
- "description": "When the application obtained consent; must not be in the future."
9559
+ "description": "Assert prior consent or enroll an application-verified user for service email on an exact customer-owned connection. Revocation and sending restrictions always win.",
9560
+ "oneOf": [
9561
+ {
9562
+ "type": "object",
9563
+ "description": "Atomically create or resolve one subscriber and assert existing consent for an exact customer-owned email connection and domain. No verification message is sent. Revocation, suppression, recipient pause, holds and unhealthy authority take precedence. An omitted source is recorded as customer.",
9564
+ "required": [
9565
+ "subscriber_id",
9566
+ "notifier_id",
9567
+ "connection_id",
9568
+ "domain_id",
9569
+ "address",
9570
+ "consented",
9571
+ "consented_at"
9572
+ ],
9573
+ "properties": {
9574
+ "subscriber_id": {
9575
+ "$ref": "#/$defs/OpaqueIdentifier"
9576
+ },
9577
+ "notifier_id": {
9578
+ "$ref": "#/$defs/OpaqueIdentifier"
9579
+ },
9580
+ "connection_id": {
9581
+ "$ref": "#/$defs/OpaqueIdentifier"
9582
+ },
9583
+ "domain_id": {
9584
+ "$ref": "#/$defs/OpaqueIdentifier"
9585
+ },
9586
+ "address": {
9587
+ "$ref": "#/$defs/EmailAddress"
9588
+ },
9589
+ "consented": {
9590
+ "const": true
9591
+ },
9592
+ "consented_at": {
9593
+ "$ref": "#/$defs/Timestamp",
9594
+ "description": "When the application obtained consent; must not be in the future."
9595
+ },
9596
+ "source": {
9597
+ "type": "string",
9598
+ "minLength": 1,
9599
+ "maxLength": 100,
9600
+ "pattern": "^[^\u0000-\u001f-Ÿ

]+$",
9601
+ "description": "A bounded customer description of where consent was collected. The authenticated asserting actor is recorded by the service, never accepted from this object."
9602
+ }
9603
+ },
9604
+ "additionalProperties": false
9149
9605
  },
9150
- "source": {
9151
- "type": "string",
9152
- "minLength": 1,
9153
- "maxLength": 100,
9154
- "pattern": "^[^\u0000-\u001f-Ÿ

]+$",
9155
- "description": "A bounded customer description of where consent was collected. The authenticated asserting actor is recorded by the service, never accepted from this object."
9606
+ {
9607
+ "type": "object",
9608
+ "description": "Enroll an application-verified user for service email. This is relationship evidence, never consent or WhooshBang mailbox verification. An existing prior-consent binding with the same subscriber, address, notifier, connection and domain is reused with its original evidence and status.",
9609
+ "required": [
9610
+ "subscriber_id": "^[^\u0000-\u001f-Ÿ

]+$",
9611
+ "notifier_id",
9612
+ "connection_id",
9613
+ "domain_id",
9614
+ "address",
9615
+ "basis",
9616
+ "source",
9617
+ "relationship_started_at"
9618
+ ],
9619
+ "properties": {
9620
+ "subscriber_id": {
9621
+ "$ref": "#/$defs/OpaqueIdentifier"
9622
+ },
9623
+ "notifier_id": {
9624
+ "$ref": "#/$defs/OpaqueIdentifier"
9625
+ },
9626
+ "connection_id": {
9627
+ "$ref": "#/$defs/OpaqueIdentifier"
9628
+ },
9629
+ "domain_id": {
9630
+ "$ref": "#/$defs/OpaqueIdentifier"
9631
+ },
9632
+ "address": {
9633
+ "$ref": "#/$defs/EmailAddress"
9634
+ },
9635
+ "source": {
9636
+ "type": "string",
9637
+ "minLength": 1,
9638
+ "maxLength": 100,
9639
+ "pattern": "^[^\u0000-\u001f-Ÿ

]+$",
9640
+ "description": "A bounded customer description of the service relationship. The authenticated asserting actor is recorded by the service, never accepted from this object."
9641
+ },
9642
+ "basis": {
9643
+ "const": "service"
9644
+ },
9645
+ "relationship_started_at": {
9646
+ "$ref": "#/$defs/Timestamp",
9647
+ "description": "When the verified user relationship began; must not be in the future."
9648
+ }
9649
+ },
9650
+ "additionalProperties": false
9156
9651
  }
9157
- },
9158
- "additionalProperties": false
9652
+ ]
9159
9653
  },
9160
9654
  "SubscriberChannelSettings": {
9161
9655
  "type": "object",
@@ -10648,6 +11142,10 @@
10648
11142
  }
10649
11143
  ],
10650
11144
  "description": "A recurring charge the default card did not pay. Paid access continues until the paid boundary; another attempt follows at next_attempt_at, or none when null. Update the card to settle it."
11145
+ },
11146
+ "recurring_selection": {
11147
+ "$ref": "#/$defs/SubscriptionSelection",
11148
+ "description": "Selection that will renew; paid project capacity can also include dropped extras until their original expiry. Optional for compatibility with older servers."
10651
11149
  }
10652
11150
  },
10653
11151
  "additionalProperties": false
@@ -10694,7 +11192,7 @@
10694
11192
  "project_capacity": {
10695
11193
  "type": "integer",
10696
11194
  "minimum": 1,
10697
- "maximum": 10025
11195
+ "maximum": 2147483647
10698
11196
  },
10699
11197
  "requested_project_ids": {
10700
11198
  "type": "array",
@@ -10702,7 +11200,7 @@
10702
11200
  "$ref": "#/$defs/OpaqueIdentifier"
10703
11201
  },
10704
11202
  "uniqueItems": true,
10705
- "maxItems": 10025
11203
+ "maxItems": 2147483647
10706
11204
  },
10707
11205
  "active_project_ids": {
10708
11206
  "type": "array",
@@ -10710,11 +11208,11 @@
10710
11208
  "$ref": "#/$defs/OpaqueIdentifier"
10711
11209
  },
10712
11210
  "uniqueItems": true,
10713
- "maxItems": 10025
11211
+ "maxItems": 2147483647
10714
11212
  }
10715
11213
  },
10716
11214
  "additionalProperties": false,
10717
- "description": "Reusable account project slots. After a downgrade the oldest requested projects retain active slots. Unassigned projects retain data, accepted delivery and answers; new live sends require an active slot."
11215
+ "description": "Reusable account project slots. After a downgrade the oldest requested projects retain active slots. Unassigned projects retain data, accepted delivery and answers; new live sends require an active slot. Paid capacity includes all unexpired project purchases, so retained dropped extras can exceed the maximum renewing selection."
10718
11216
  },
10719
11217
  "AssignBillingProjectSlotsRequest": {
10720
11218
  "type": "object",
@@ -10930,7 +11428,8 @@
10930
11428
  {
10931
11429
  "type": "null"
10932
11430
  }
10933
- ]
11431
+ ],
11432
+ "description": "Compatibility field: new upgrades return 0.000000; starts and boundary changes return null. Historical quotes can retain their recorded unused-time credit. No new automatic unused-time refunds or offsets."
10934
11433
  },
10935
11434
  "effective_at": {
10936
11435
  "anyOf": [