@cookiemunch/sdk 0.5.1 → 0.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.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { CONSENT_COOKIE_NAME, ConsentCategory, ConsentSource, ReadConsentOptions, ServerConsent, getConsent, isAllowed, parseConsentValue, readConsent } from './consent.js';
1
+ export { CONSENT_COOKIE_NAME, ConsentCategory, ConsentSource, ConsentTokenClaims, DEFAULT_JWKS_URL, JsonWebKeySet, KeySetOptions, ReadConsentOptions, ReadSignedConsentOptions, ServerConsent, SignableDecision, VerifyTokenOptions, consentSignaturePayload, getConsent, isAllowed, parseConsentValue, readConsent, verifyDecisionSignature, verifyToken } from './consent.js';
2
2
 
3
3
  /**
4
4
  * Request/response shapes for the Cookie Munch Developer API (/v1). These mirror the
@@ -93,25 +93,72 @@ interface SiteUpdateResult {
93
93
  }
94
94
  /** One row of GET /v1/integration-health. `ok: null` = the check could not run (see `detail`). */
95
95
  interface HealthRow {
96
+ /** The suite shape's name for `check` (always equal). */
97
+ id: string;
96
98
  check: string;
99
+ /** The generic check this row is an instance of (`forumulate.webhook` → `webhook.delivery`); otherwise `check`. */
100
+ kind: string;
101
+ /** The vendor a vendor-specific instance is about. */
102
+ vendor?: string;
97
103
  ok: boolean | null;
98
104
  severity: 'error' | 'warning' | 'info';
99
105
  subject: string;
100
106
  fixHint?: string;
107
+ /** The same as fixHint (suite shape). */
108
+ fix?: string;
109
+ /** Where the check and its fix are explained. */
110
+ docs: string;
101
111
  detail?: string;
112
+ /** Network checks: the hop that failed (or, on success, the last one reached). */
113
+ hop?: 'dns' | 'tls' | 'http' | 'challenge' | 'auth';
114
+ status?: number;
115
+ elapsedMs?: number;
116
+ /** Failed network checks: a stable code (ENOTFOUND, timeout, challenge, http_503, …). */
117
+ error?: string;
118
+ /** A waiver covers this failing row; `ok` is then null. */
119
+ waived?: {
120
+ reason: string;
121
+ by: string;
122
+ until: number | null;
123
+ };
102
124
  lastCheckedAt: number;
103
125
  }
104
126
  interface IntegrationHealthReport {
105
127
  cbid: string;
106
128
  checkedAt: number;
129
+ generatedAt: string;
107
130
  ok: boolean;
108
131
  counts: {
109
132
  error: number;
110
133
  warning: number;
111
134
  notChecked: number;
135
+ waived: number;
112
136
  };
113
137
  checks: HealthRow[];
114
138
  }
139
+ /** PUT /v1/integration-health/waivers. */
140
+ interface HealthWaiverInput {
141
+ /** Optional when the organisation has one site. */
142
+ cbid?: string;
143
+ /** A row's `check` or `kind`. */
144
+ check: string;
145
+ /** A row's `subject`; omitted: every subject of the check (`*`). */
146
+ subject?: string;
147
+ /** Why this is deliberate (1–500 characters). */
148
+ reason: string;
149
+ /** ISO date or epoch ms, future, within a year; omitted or null: never expires. */
150
+ until?: string | number | null;
151
+ }
152
+ interface HealthWaiver {
153
+ cbid: string;
154
+ check: string;
155
+ subject: string;
156
+ reason: string;
157
+ by: string;
158
+ until: number | null;
159
+ createdAt: number;
160
+ expired?: boolean;
161
+ }
115
162
  /** POST /v1/provision. Secrets are used for the request only and never returned. */
116
163
  interface ProvisionRequest {
117
164
  product: string;
@@ -120,10 +167,12 @@ interface ProvisionRequest {
120
167
  aliases?: string[];
121
168
  cbid?: string;
122
169
  /** `frontendApiHost` (e.g. auth.example.com) lets provision declare Atlas's sign-in cookies on the site. */
170
+ /** `rightsIdentity` (default true) makes Atlas the site's rights sign-in (step `rights.identity`). */
123
171
  atlas?: {
124
172
  secretKey: string;
125
173
  cookieConsent?: boolean;
126
174
  dsrWebhook?: boolean;
175
+ rightsIdentity?: boolean;
127
176
  frontendApiHost?: string;
128
177
  };
129
178
  forumulate?: {
@@ -140,15 +189,21 @@ interface ProvisionRequest {
140
189
  };
141
190
  }
142
191
  interface ProvisionStep {
192
+ /** v2 answers: the stable step id (`fromStep` takes it). */
193
+ id?: string;
143
194
  step: string;
144
- status: 'created' | 'updated' | 'unchanged' | 'would_create' | 'would_update' | 'skipped' | 'waiting' | 'failed' | 'passed';
195
+ status: 'created' | 'updated' | 'unchanged' | 'would_create' | 'would_update' | 'skipped' | 'waiting' | 'waiting_on' | 'failed' | 'passed';
145
196
  detail?: string;
146
197
  diff?: Array<{
147
198
  field: string;
148
199
  before: unknown;
149
200
  after: unknown;
150
201
  }>;
151
- waitingOn?: string;
202
+ /** A string in v1 answers; `{ platform, items }` in v2 answers. */
203
+ waitingOn?: string | {
204
+ platform: string;
205
+ items: string[];
206
+ };
152
207
  }
153
208
  interface ProvisionResult {
154
209
  dryRun: boolean;
@@ -161,8 +216,19 @@ interface ProvisionResult {
161
216
  waiting: number;
162
217
  failed: number;
163
218
  };
219
+ /** v2 answers only. */
220
+ version?: 2;
221
+ ids?: {
222
+ orgId: string;
223
+ cbid: string | null;
224
+ executors: Record<string, string>;
225
+ webhooks: string[];
226
+ };
227
+ sealedSecrets?: Array<Record<string, unknown>>;
228
+ checklist?: string[];
164
229
  }
165
- type PartnerId = 'forumulate' | 'atlas';
230
+ /** A partner the deployment knows: built in (forumulate, atlas, chatly, referalli) or any other registered on it. */
231
+ type PartnerId = 'forumulate' | 'atlas' | 'chatly' | 'referalli' | (string & {});
166
232
  interface PartnerLinkCreate {
167
233
  partner: PartnerId;
168
234
  /** The partner's id for the receiving account (a Forumulate organisation id, an Atlas instance id). */
@@ -235,9 +301,11 @@ interface RangeQuery {
235
301
  interface LogQuery extends RangeQuery {
236
302
  limit?: number;
237
303
  }
238
- type DsarType = 'access' | 'deletion' | 'rectification' | 'portability' | 'opt-out';
304
+ type DsarType = 'access' | 'deletion' | 'rectification' | 'portability' | 'opt-out' | 'closure' | 'restriction';
305
+ /** A type word as sent: the canonical words, or an alias (`erasure`/`erase` → deletion, `export` → access). */
306
+ type DsarTypeWord = DsarType | 'erasure' | 'erase' | 'export';
239
307
  type Regulation = 'gdpr' | 'ccpa';
240
- type DsarStatus = 'received' | 'verifying' | 'in_progress' | 'completed' | 'rejected';
308
+ type DsarStatus = 'received' | 'verifying' | 'in_progress' | 'completed' | 'rejected' | 'cancelled';
241
309
  interface DsarRequest {
242
310
  id: string;
243
311
  type: DsarType;
@@ -254,6 +322,147 @@ interface DsarRequest {
254
322
  messageToSubject?: string;
255
323
  /** A test request: off the SLA board, labelled, and deletable with `dsar.delete`. A closed request can be marked one with `dsar.markTest`. */
256
324
  test?: boolean;
325
+ /** Its type in the suite vocabulary (`erasure` was stored as `deletion`). */
326
+ canonicalType?: string;
327
+ /** The case's X-ForgeDeck-Trace, when it has one. */
328
+ trace?: string;
329
+ }
330
+ /** A signed-in identity from any OIDC issuer the site trusts. `(iss, sub)` is the key. */
331
+ interface SubjectIdentity {
332
+ iss: string;
333
+ sub: string;
334
+ ext?: string;
335
+ principal?: string;
336
+ }
337
+ /** Who a case is about. `atlas` is accepted as an alias of `identity`. */
338
+ interface DsarSubject {
339
+ emails: string[];
340
+ identity?: SubjectIdentity;
341
+ atlas?: SubjectIdentity;
342
+ }
343
+ /** POST /v1/dsar/requests. */
344
+ interface DsarCaseCreate {
345
+ cbid: string;
346
+ type: DsarTypeWord;
347
+ subject?: DsarSubject;
348
+ /** The person's own token from the site's sign-in issuer (aud `cookiemunch:<cbid>`). */
349
+ subjectToken?: string;
350
+ /** product and atlas need dsar:write and attest the person; admin (default) files it received. */
351
+ source?: 'product' | 'atlas' | 'admin';
352
+ reason?: string;
353
+ /** Connections not to ask: system names, connection ids, or `self`. */
354
+ skipSystems?: string[];
355
+ /** Default true. */
356
+ fulfill?: boolean;
357
+ regulation?: 'gdpr' | 'ccpa' | 'lgpd' | 'pipeda' | 'vcdpa';
358
+ jurisdiction?: string;
359
+ test?: boolean;
360
+ }
361
+ type DsarCaseStatus = 'pending' | 'scheduled' | 'processing' | 'completed' | 'completed_with_retention' | 'rejected' | 'cancelled';
362
+ interface RetentionLine {
363
+ category: string;
364
+ basis: 'legal_obligation' | 'legal_claims' | 'contract' | 'public_interest';
365
+ until?: string;
366
+ }
367
+ interface DsarCaseTask {
368
+ system: string;
369
+ executorId: string | null;
370
+ taskId: string;
371
+ status: DsarCaseStatus | 'no_match';
372
+ requestId: string | null;
373
+ eta: string | null;
374
+ completedAt: string | null;
375
+ detail: string | null;
376
+ retention?: RetentionLine[];
377
+ }
378
+ /** A case across every connected system. */
379
+ interface DsarCase {
380
+ id: string;
381
+ type: DsarType;
382
+ canonicalType: string;
383
+ status: DsarCaseStatus;
384
+ requestStatus: DsarStatus;
385
+ cbid?: string;
386
+ source: 'product' | 'atlas' | 'rights_page' | 'admin' | null;
387
+ reason: string | null;
388
+ openedAt: string;
389
+ /** Nothing is erased anywhere before this. */
390
+ executeAfter: string | null;
391
+ graceDays: number | null;
392
+ closedAt: string | null;
393
+ /** False for a closure: no statutory clock. */
394
+ statutory: boolean;
395
+ dueAt: string | null;
396
+ verification: string | null;
397
+ trace: string | null;
398
+ subject: {
399
+ emails: string[];
400
+ identity: SubjectIdentity | null;
401
+ };
402
+ skipSystems: string[];
403
+ fulfill: boolean | null;
404
+ cancelRequestedAt: string | null;
405
+ test: boolean;
406
+ tasks: DsarCaseTask[];
407
+ receiptUrl: string;
408
+ /** Lets the person who asked read this case through POST /api/v1/public/dsar/status. */
409
+ statusToken?: string;
410
+ }
411
+ /** One signed receipt for a case (Ed25519; verify with GET /v1/partner/jwks.json). */
412
+ interface DsarCaseReceipt {
413
+ receiptVersion: number;
414
+ caseId: string;
415
+ type: DsarType;
416
+ canonicalType: string;
417
+ status: DsarCaseStatus;
418
+ openedAt: string;
419
+ executeAfter: string | null;
420
+ closedAt: string | null;
421
+ verification: string | null;
422
+ trace: string | null;
423
+ subject: {
424
+ emailHashes: string[];
425
+ identityHash?: string;
426
+ atlasSubHash?: string;
427
+ };
428
+ systems: Array<{
429
+ system: string;
430
+ executorId: string | null;
431
+ requestId: string | null;
432
+ status: string;
433
+ completedAt: string | null;
434
+ trace: string | null;
435
+ retention?: RetentionLine[];
436
+ }>;
437
+ issuedAt: string;
438
+ signature: {
439
+ alg: 'Ed25519';
440
+ kid: string;
441
+ value: string;
442
+ covers?: string;
443
+ };
444
+ }
445
+ /** A site's rights-request settings. */
446
+ interface DsarSettings {
447
+ cbid: string;
448
+ /** Days an erasure or account closure waits before any system acts (0–30). 7 for a new site; 0 for one that existed before (opt-in). */
449
+ graceDays: number;
450
+ /** site: set explicitly; default: a new site's 7 days; legacy: an existing site, 0 until set. */
451
+ source: 'site' | 'default' | 'legacy';
452
+ updatedAt: number | null;
453
+ }
454
+ /** GET /v1/integrations/{app}/card. */
455
+ interface SubjectCard {
456
+ app: string;
457
+ openCases: Array<{
458
+ id: string;
459
+ type: string;
460
+ status: string;
461
+ executeAfter: string | null;
462
+ openedAt: string;
463
+ receiptUrl: string;
464
+ }>;
465
+ consent: null;
257
466
  }
258
467
  /**
259
468
  * How a rights-page requester was verified — on every answer of the public intake
@@ -366,6 +575,24 @@ interface PreferenceRecord {
366
575
  updatedAt: number;
367
576
  version: number;
368
577
  }
578
+ /** GET /v1/categories/registry — the reserved category templates (CMU-X15). */
579
+ interface CategoryRegistry {
580
+ version: 1;
581
+ standard: string[];
582
+ suite: Array<{
583
+ id: 'support_chat' | 'referrals';
584
+ stance: 'necessary_on_request' | 'opt_in_eu_uk';
585
+ fallback: 'preferences' | 'marketing';
586
+ /** By banner language. */
587
+ labels: Record<string, string>;
588
+ descriptions: Record<string, string>;
589
+ basis?: string[];
590
+ vendors?: Array<{
591
+ product: string;
592
+ storage: string[];
593
+ }>;
594
+ }>;
595
+ }
369
596
 
370
597
  interface VerifyWebhookInput {
371
598
  /** The raw request body, exactly as received. Do NOT re-stringify parsed JSON. */
@@ -404,6 +631,152 @@ interface MintConsentSyncTokenInput {
404
631
  }
405
632
  declare function mintConsentSyncToken(input: MintConsentSyncTokenInput): string;
406
633
 
634
+ /**
635
+ * The cm-standard-v2 executor conformance kit (CMU-X20).
636
+ *
637
+ * cm-standard-v2 is an open contract: any system that holds personal data can implement it and
638
+ * be driven by Cookie Munch with no code on our side (docs: cookiemunch.net/docs/executor-contract-v2).
639
+ * This kit checks an implementation rule by rule, and names the rule that fails. It is the same
640
+ * suite Cookie Munch runs on `POST /v1/dsar/executors/{id}/test {conformance: true}`, and the
641
+ * `cookiemunch executors conformance <baseUrl>` command runs it from a terminal or CI.
642
+ *
643
+ * It only ever touches the CANARY subject — an address no real person has. The contract asks every
644
+ * implementation to treat the canary as an existing synthetic person: it is found by its email and
645
+ * by its identity, requests on it move through the full state machine, and nothing real is ever
646
+ * erased. So the kit can check that an erasure waits for `executeAfter`, that a cancel leaves the
647
+ * person in place, and that an identity is never matched to someone else through a shared email —
648
+ * without a real person's data being anywhere near it.
649
+ *
650
+ * No dependencies: `fetch` only, so it runs in Node 18+, a browser, or an edge runtime.
651
+ */
652
+ type ConformanceStatus = 'pass' | 'fail' | 'skip';
653
+ interface ConformanceRuleResult {
654
+ /** A stable id, e.g. `requests.execute_after.scheduled`. */
655
+ id: string;
656
+ /** What the rule says, in one sentence. */
657
+ title: string;
658
+ status: ConformanceStatus;
659
+ /** What was seen, when it failed or was skipped. */
660
+ detail?: string;
661
+ }
662
+ interface ConformanceReport {
663
+ /** True when no rule failed. */
664
+ ok: boolean;
665
+ passed: number;
666
+ failed: number;
667
+ skipped: number;
668
+ rules: ConformanceRuleResult[];
669
+ /** The `X-Version` the executor answered with, when it sent one. */
670
+ version?: string;
671
+ }
672
+ interface ConformanceOptions {
673
+ /** The executor's base: the contract paths are `{baseUrl}/privacy/lookup` and so on. https (http only for localhost). */
674
+ baseUrl: string;
675
+ /** The credential Cookie Munch would send. */
676
+ secret: string;
677
+ /**
678
+ * The canary address: `canary-<16 hex>@canary.cookiemunch.net`, per organisation
679
+ * (`GET /v1/dsar/executors/presets` → `canaryEmail`).
680
+ */
681
+ canaryEmail: string;
682
+ /** How the secret is sent. Default `Authorization: Bearer {secret}`. */
683
+ auth?: {
684
+ header: string;
685
+ format: string;
686
+ };
687
+ /** Path prefix under baseUrl. Default `/privacy`. */
688
+ prefix?: string;
689
+ fetch?: typeof fetch;
690
+ now?: () => number;
691
+ /** A per-run tag for idempotency keys and case ids. Default random. */
692
+ runId?: string;
693
+ }
694
+ /** The issuer the canary identity carries. */
695
+ declare const CANARY_ISSUER = "https://canary.cookiemunch.net";
696
+ /** The canary subject's identity, derived from its address. */
697
+ declare function canaryIdentityFor(canaryEmail: string): {
698
+ iss: string;
699
+ sub: string;
700
+ ext: string;
701
+ };
702
+ /** Every rule, in the order they run. */
703
+ declare const CONFORMANCE_RULES: ReadonlyArray<{
704
+ id: string;
705
+ title: string;
706
+ }>;
707
+ /** Run every rule against one executor. Never throws for an executor's answer; only for bad options. */
708
+ declare function runExecutorConformance(o: ConformanceOptions): Promise<ConformanceReport>;
709
+
710
+ /**
711
+ * Types for `window.__fdConsent`, the shared consent API any embed can code against — a chat
712
+ * widget, a referral snippet, an analytics tag — whatever CMP the page runs. Cookie Munch sets
713
+ * it natively; `fd-consent-shim.js` sets the same object over Cookiebot, OneTrust or no CMP.
714
+ * Type-only: importing this module adds nothing to a bundle.
715
+ *
716
+ * import type { FdConsent, FdConsentQueue } from '@cookiemunch/sdk';
717
+ * const fd = (window.__fdConsent ??= { q: [] });
718
+ * if ('version' in fd) fd.on('change', (s) => …); else fd.q.push(['on', 'change', (s) => …]);
719
+ *
720
+ * `version` changes only with a breaking change; new members do not bump it.
721
+ */
722
+ /** What caused a change. The same causes Cookie Munch's ledger records. */
723
+ type FdCause = 'replay' | 'accept' | 'decline' | 'selection' | 'withdraw' | 'implied' | 'sync' | 'request' | 'migrated';
724
+ interface FdSnapshot {
725
+ /** False until the visitor has answered. */
726
+ decided: boolean;
727
+ /** False when this visitor's region and the site's rules need no answer (a default applies). */
728
+ required: boolean;
729
+ /** Every category the site offers (standard, custom, reserved) and its answer. */
730
+ categories: Record<string, boolean>;
731
+ /** The decision's stamp (`CookieMunch.consentId()`), or null. */
732
+ stamp: string | null;
733
+ region: string;
734
+ /** A Global Privacy Control signal was seen. */
735
+ gpc: boolean;
736
+ /** ISO 8601, or null before a decision. */
737
+ decidedAt: string | null;
738
+ }
739
+ interface FdRequestOptions {
740
+ /** One sentence in the page's language: what will be stored and why. Shown as the prompt's text. */
741
+ reason: string;
742
+ /** Who is asking: your vendor id. Recorded with the answer. */
743
+ vendor: string;
744
+ }
745
+ interface FdConsent {
746
+ readonly version: 1;
747
+ /** `cookiemunch`, or `shim:cookiebot` / `shim:onetrust` / `shim:none`. */
748
+ readonly provider: string;
749
+ /** Resolves once a decision exists, or at once where the region needs none. */
750
+ ready(): Promise<FdSnapshot>;
751
+ /** true / false, or null while a required decision is pending. Never false for "not decided". */
752
+ has(category: string): boolean | null;
753
+ /** Fires once per decision (a returning visitor's as `replay`); a withdrawal synchronously. Returns unsubscribe. */
754
+ on(event: 'change', cb: (snapshot: FdSnapshot, cause: FdCause) => void): () => void;
755
+ /** Ask for one category at the moment you need it. Never re-asks a refusal; one prompt per category per page view. */
756
+ request(category: string, opts: FdRequestOptions): Promise<boolean>;
757
+ /** Not available yet: warns once and does nothing. */
758
+ identify(token: string): void;
759
+ layout: {
760
+ bottomInset(): number;
761
+ on(cb: (insetPx: number) => void): () => void;
762
+ };
763
+ /** Calls made on the queue before this existed ran in order; later pushes run at once. */
764
+ q: {
765
+ push(...calls: FdQueuedCall[]): number;
766
+ };
767
+ }
768
+ /** A call queued before the real object exists. */
769
+ type FdQueuedCall = ['on', 'change', (snapshot: FdSnapshot, cause: FdCause) => void] | ['ready', (snapshot: FdSnapshot) => void] | ['request', string, FdRequestOptions, (granted: boolean) => void] | ['identify', string];
770
+ /** What an embed that loads first creates: `window.__fdConsent = window.__fdConsent || { q: [] }`. */
771
+ interface FdConsentQueue {
772
+ q: FdQueuedCall[];
773
+ }
774
+ declare global {
775
+ interface Window {
776
+ __fdConsent?: FdConsent | FdConsentQueue;
777
+ }
778
+ }
779
+
407
780
  /**
408
781
  * @cookiemunch/sdk — a small, typed REST client for the Cookie Munch Developer API
409
782
  * (the /v1 surface). Construct it with an API key; the org is derived server-side
@@ -418,7 +791,7 @@ declare function mintConsentSyncToken(input: MintConsentSyncTokenInput): string;
418
791
  * This package's version, sent in the default User-Agent. Cloudflare answers a request with
419
792
  * no recognisable User-Agent with `403 error code: 1010`; a test pins this to package.json.
420
793
  */
421
- declare const SDK_VERSION = "0.5.1";
794
+ declare const SDK_VERSION = "0.6.0";
422
795
  interface CookieMunchOptions {
423
796
  apiKey: string;
424
797
  /** "https://api.cookiemunch.net" — the /v1 prefix is appended automatically. */
@@ -432,7 +805,183 @@ interface CookieMunchOptions {
432
805
  strictUnknownFields?: boolean;
433
806
  /** The `User-Agent` sent on every request. Default `cookiemunch-js/<version>`. */
434
807
  userAgent?: string;
808
+ /**
809
+ * Seal every once-shown secret to this X25519 public key (`x25519:<base64>`): answers carry `sealed_secret`
810
+ * (a libsodium sealed box) and `sealed_field` instead of the plaintext. Sent as `X-Secret-Recipient` on writes.
811
+ */
812
+ secretRecipient?: string;
813
+ /**
814
+ * Extra headers on every request, e.g. `{ 'Idempotency-Key': '<forgedeck ref>:<run>' }` on a client made for
815
+ * one create: a retry with the same key replays the first answer (secrets included) for 24 hours.
816
+ */
817
+ headers?: Record<string, string>;
818
+ }
819
+ /** Tags on a created resource (CMU-X29). `forgedeck_sandbox: true` can only be set at creation. */
820
+ type ResourceMetadata = Record<string, string | number | boolean>;
821
+ /** Keep only resources whose tags match, e.g. `{ forgedeck_product: 'referalli' }`. */
822
+ interface MetadataFilter {
823
+ metadata?: Record<string, string>;
824
+ }
825
+ /** externalRef and metadata, accepted by every create (orgs, sites, webhooks, executors, DSARs, partner links). */
826
+ interface ResourceTagsInput {
827
+ /** Your own name for it, unique per org and type: a repeat create with the same body returns the existing one. */
828
+ externalRef?: string;
829
+ metadata?: ResourceMetadata;
830
+ }
831
+ type TaggedType = 'org' | 'site' | 'webhook' | 'executor' | 'dsar' | 'partner_link';
832
+ interface ResourceTags {
833
+ type: TaggedType;
834
+ id: string;
835
+ metadata: ResourceMetadata;
836
+ externalRef: string | null;
837
+ sandbox: boolean;
838
+ }
839
+ interface ResourceTagsUpdate {
840
+ dryRun?: true;
841
+ type: TaggedType;
842
+ id: string;
843
+ metadata: ResourceMetadata;
844
+ diff: Array<{
845
+ field: string;
846
+ before: unknown;
847
+ after: unknown;
848
+ }>;
849
+ }
850
+ /** What a sandbox hard delete removed. */
851
+ interface SandboxPurge {
852
+ deleted: true;
853
+ cbid?: string;
854
+ orgId?: string;
855
+ counts: Record<string, number>;
856
+ }
857
+ /** A partner link in the suite-standard shape (CMU-X34). */
858
+ interface StandardPartnerLink {
859
+ id: string;
860
+ partner: string;
861
+ resource: string;
862
+ scopes: string[];
863
+ created_at: string | null;
864
+ expires_at: string | null;
865
+ last_used_at: string | null;
866
+ calls_30d: number;
867
+ status: 'active' | 'waiting_on_partner' | 'revoked' | 'expired';
868
+ externalId?: string;
869
+ label?: string;
870
+ }
871
+ interface StandardPartnerLinkCreate extends ResourceTagsInput {
872
+ partner: string;
873
+ /** `site:<cbid>` or `org:<org id>`. */
874
+ resource: string;
875
+ scopes: Array<'consent:read' | 'receipt:read' | 'dsar:read' | 'dsar:write' | 'dsar:rights-links' | 'sites:read'>;
876
+ expires_at?: string;
877
+ externalId?: string;
878
+ label?: string;
879
+ }
880
+ /** POST /v1/provision v2: the `cookiemunch` block of a forgedeck.yaml (see the forgedeck API map page). */
881
+ interface ProvisionRequestV2 {
882
+ forgedeck: {
883
+ ref?: string;
884
+ product: string;
885
+ env?: string;
886
+ sandbox?: boolean;
887
+ };
888
+ site: {
889
+ domain: string;
890
+ name?: string;
891
+ aliases?: string[];
892
+ locales?: string[];
893
+ preset?: string;
894
+ devOrigins?: string[];
895
+ };
896
+ cbid?: string;
897
+ categories?: string[];
898
+ rightsIdentity?: Record<string, unknown>;
899
+ dsar?: {
900
+ graceDays?: number;
901
+ };
902
+ atlas?: {
903
+ instanceId?: string;
904
+ secretKey?: string;
905
+ cookieConsent?: boolean;
906
+ executor?: boolean;
907
+ frontendApiHost?: string;
908
+ };
909
+ forumulate?: {
910
+ org?: string;
911
+ orgId?: string;
912
+ token?: string;
913
+ consent?: boolean;
914
+ executor?: boolean;
915
+ label?: string;
916
+ };
917
+ chatly?: {
918
+ workspace?: string;
919
+ publicId?: string;
920
+ vendorHook?: boolean;
921
+ executor?: boolean;
922
+ };
923
+ self?: {
924
+ baseUrl: string;
925
+ contract?: string;
926
+ secret: string;
927
+ };
928
+ referalli?: {
929
+ orgId?: string;
930
+ trackingToken?: string;
931
+ preset?: boolean;
932
+ partner?: boolean;
933
+ executor?: string | boolean;
934
+ };
935
+ embedManifests?: string | string[];
936
+ brand?: {
937
+ url?: string;
938
+ };
939
+ }
940
+ /** GET /v1/provision/env: names, non-secret values, and references for secrets. */
941
+ interface ProvisionEnv {
942
+ ref: string;
943
+ cbid: string;
944
+ env: Array<{
945
+ name: string;
946
+ value?: string;
947
+ secretRef?: string;
948
+ }>;
435
949
  }
950
+ /** A vended short-lived key, shown once. */
951
+ interface ApiKeyVended {
952
+ key: string;
953
+ prefix: string;
954
+ expiresAt: number;
955
+ scopes: string[];
956
+ cbids: string[] | null;
957
+ }
958
+ /** The suite-standard key listing (GET /v1/keys?shape=standard). */
959
+ interface StandardKeyList {
960
+ keys: Array<{
961
+ id: string;
962
+ prefix: string;
963
+ name: string | null;
964
+ owner: string | null;
965
+ kind: string | null;
966
+ env: string | null;
967
+ format: string | null;
968
+ scopes: string[] | null;
969
+ resources: string[] | null;
970
+ created_at: string | null;
971
+ expires_at: string | null;
972
+ last_used_at: string | null;
973
+ last_used_ip: string | null;
974
+ status: 'active' | 'expired';
975
+ }>;
976
+ }
977
+ /** A leaked secret to revoke (POST /v1/keys/revoke_leaked, no authentication needed). */
978
+ type LeakReport = {
979
+ key: string;
980
+ source?: string;
981
+ } | {
982
+ keys: string[];
983
+ source?: string;
984
+ };
436
985
  /**
437
986
  * Thrown for any non-2xx response. `message` is the server's `error` field when present;
438
987
  * `code` is populated from the server's `code` field whenever the error body carries one
@@ -553,15 +1102,88 @@ interface DeclaredCookie extends DeclaredCookieInput {
553
1102
  vendor?: string;
554
1103
  }
555
1104
  /** A platform whose cookies and storage a preset declares. */
556
- type CookiePresetVendor = 'atlas' | 'forumulate' | 'chatly' | 'cookiemunch' | 'referally';
1105
+ type CookiePresetVendor = 'atlas' | 'forumulate' | 'chatly' | 'cookiemunch' | 'referalli' | 'firstpromoter' | 'partnerstack' | 'tapfiliate' | 'impact'
1106
+ /** @deprecated the old name of `referalli`, accepted until 2027-10-23. */
1107
+ | 'referally';
557
1108
  /** Where a vendor's live manifest will come from, and whether it exists yet. */
558
1109
  interface CookiePresetManifest {
559
- status: 'builtin' | 'waiting_on_vendor';
1110
+ /** `live`/`stale`/`invalid`: the vendor's embed manifest feeds the preset; `waiting_on_vendor`: built-in rows. */
1111
+ status: 'builtin' | 'live' | 'stale' | 'invalid' | 'waiting_on_vendor';
560
1112
  waitingOn?: string;
561
1113
  item?: string;
562
1114
  contract?: string;
1115
+ /** Where the manifest is read from, or `upload`. */
1116
+ source?: string;
1117
+ /** The `updated` of the copy in effect. */
1118
+ updated?: string;
1119
+ fetchedAt?: number;
1120
+ /** Why the latest read was not accepted, by rule (1–6). */
1121
+ errors?: Array<{
1122
+ rule?: number;
1123
+ path?: string;
1124
+ code?: string;
1125
+ message: string;
1126
+ }>;
1127
+ warnings?: Array<{
1128
+ rule?: number;
1129
+ path?: string;
1130
+ code?: string;
1131
+ message: string;
1132
+ }>;
563
1133
  }
564
- /** Preset parameters: Atlas `frontendApiHost`/`crossSubdomainCookies`; Chatly `publicId`/`dragging`/`category`; Referally `cookieDomain`/`cookieDays`/`category`. */
1134
+ /** PUT /v1/sites/:cbid/cookies/presets/custom — any vendor's embed manifest, by URL or as a body. */
1135
+ type CustomPresetInput = ({
1136
+ url: string;
1137
+ manifest?: never;
1138
+ } | {
1139
+ manifest: EmbedManifest;
1140
+ url?: never;
1141
+ }) & {
1142
+ /** Values for the manifest's `{placeholders}`. */
1143
+ params?: Record<string, string>;
1144
+ };
1145
+ /** One suggestion in GET /v1/sites/:cbid/cookies/suggestions. */
1146
+ interface CookieSuggestion {
1147
+ name: string;
1148
+ storage: 'cookie' | 'localStorage' | 'sessionStorage' | 'indexedDB';
1149
+ foundOnPages: string[];
1150
+ /** `denied`: a crawl saw it before any consent; `granted`: after accepting all. */
1151
+ consentStates?: Array<'denied' | 'granted'>;
1152
+ suggestedPreset?: string;
1153
+ suggestedCategory: string;
1154
+ confidence: 'high' | 'medium' | 'low';
1155
+ purpose?: string;
1156
+ reason: string;
1157
+ }
1158
+ /** GET /v1/sites/:cbid/cookies/suggestions */
1159
+ interface CookieSuggestions {
1160
+ suggestions: CookieSuggestion[];
1161
+ vendors: Array<{
1162
+ vendor: string;
1163
+ display: string;
1164
+ preset: string | null;
1165
+ applied: boolean;
1166
+ needsParams: boolean;
1167
+ evidence: Array<{
1168
+ kind: 'script' | 'storage' | 'manifest';
1169
+ value: string;
1170
+ pages?: string[];
1171
+ }>;
1172
+ }>;
1173
+ }
1174
+ /** POST /v1/sites/:cbid/cookies/suggestions/declare */
1175
+ interface CookieSuggestionsDeclared {
1176
+ presetsApplied: string[];
1177
+ declaredCount: number;
1178
+ skipped?: Array<{
1179
+ name: string;
1180
+ reason: string;
1181
+ }>;
1182
+ dryRun?: true;
1183
+ declared?: DeclaredCookie[];
1184
+ diff?: DeclarationDiff;
1185
+ }
1186
+ /** Preset parameters: Atlas `frontendApiHost`/`crossSubdomainCookies`; Chatly `publicId`/`dragging`/`category`; referral and affiliate presets (referalli, firstpromoter, partnerstack, tapfiliate, impact) `cookieDomain`/`cookieDays`/`category`, referalli `legacyName`, impact `campaignId`. */
565
1187
  interface CookiePresetParams {
566
1188
  frontendApiHost?: string;
567
1189
  crossSubdomainCookies?: boolean;
@@ -570,10 +1192,77 @@ interface CookiePresetParams {
570
1192
  category?: string;
571
1193
  cookieDomain?: string;
572
1194
  cookieDays?: number;
1195
+ /** referalli: default true, also declare referally_ctx (the pre-rename copy aff.js still writes). */
1196
+ legacyName?: boolean;
1197
+ /** impact: your program id; declares IR_<campaignId> too. */
1198
+ campaignId?: string;
1199
+ }
1200
+ /** One browser key a surface writes, in an embed manifest. */
1201
+ interface EmbedManifestStorage {
1202
+ name: string;
1203
+ type: 'cookie' | 'localStorage' | 'sessionStorage' | 'indexedDB';
1204
+ category: string;
1205
+ /** `session`, `persistent` or a duration such as `365d`. */
1206
+ lifetime?: string;
1207
+ /** By language; `en` is always there. */
1208
+ purpose: Record<string, string>;
1209
+ domain?: string;
1210
+ sentTo?: string;
1211
+ }
1212
+ /** One embeddable surface in an embed manifest: its origins by CSP directive and its storage. */
1213
+ interface EmbedManifestSurface {
1214
+ /** Origins by CSP directive (`script-src`, `connect-src`, …). */
1215
+ csp?: Record<string, string[]>;
1216
+ /** Non-origin sources the surface needs (`'unsafe-inline'`, `data:`). */
1217
+ requires?: Record<string, string[]>;
1218
+ trustedTypes?: string[];
1219
+ consentCategory?: string;
1220
+ storage?: EmbedManifestStorage[];
1221
+ sri?: Record<string, string>;
1222
+ }
1223
+ /** The shared embed/origins manifest (https://cookiemunch.net/schemas/embed-v1.json). */
1224
+ interface EmbedManifest {
1225
+ schema: string;
1226
+ product: string;
1227
+ updated: string;
1228
+ openapi?: string;
1229
+ llms?: string;
1230
+ status?: string;
1231
+ changelog?: string;
1232
+ docs?: string;
1233
+ checkers?: {
1234
+ userAgent?: string;
1235
+ egress?: string[];
1236
+ agents?: Array<{
1237
+ role: string;
1238
+ userAgent?: string;
1239
+ userAgentContains?: string;
1240
+ description?: string;
1241
+ }>;
1242
+ };
1243
+ surfaces: Record<string, EmbedManifestSurface>;
1244
+ changes?: Array<{
1245
+ effective: string;
1246
+ surface: string;
1247
+ add?: Record<string, string[]>;
1248
+ remove?: Record<string, string[]>;
1249
+ note?: string;
1250
+ }>;
1251
+ /** The tenant variant only: the site and its hosts. */
1252
+ tenant?: {
1253
+ cbid: string;
1254
+ siteHosts: string[];
1255
+ rightsPage: string;
1256
+ preferenceCentre: string;
1257
+ };
573
1258
  }
574
1259
  /** One preset in GET /v1/sites/:cbid/cookies/presets. */
575
1260
  interface CookiePreset {
576
- vendor: CookiePresetVendor;
1261
+ /** A first-class preset, or a custom preset's product id. */
1262
+ vendor: CookiePresetVendor | (string & {});
1263
+ /** A custom preset (importCookieManifest). */
1264
+ custom?: boolean;
1265
+ url?: string;
577
1266
  params: Array<{
578
1267
  name: string;
579
1268
  type: string;
@@ -586,7 +1275,9 @@ interface CookiePreset {
586
1275
  }
587
1276
  /** What applying a preset declared. */
588
1277
  interface CookiePresetResult {
589
- vendor: CookiePresetVendor;
1278
+ vendor: CookiePresetVendor | (string & {});
1279
+ /** `manifest` when the rows came from the vendor's embed manifest. */
1280
+ source?: 'manifest';
590
1281
  cookies: DeclaredCookie[];
591
1282
  removed: string[];
592
1283
  skipped?: Array<{
@@ -594,6 +1285,16 @@ interface CookiePresetResult {
594
1285
  reason: string;
595
1286
  }>;
596
1287
  note?: string;
1288
+ /** Rows filed under a category this site has switched off (`cookies[<name>].category`). */
1289
+ warnings?: Array<{
1290
+ field: string;
1291
+ reason: string;
1292
+ }>;
1293
+ /** With `warnings`: a body for `sites.patchConfig` that fixes them; apply the preset again after. */
1294
+ suggestedConfigPatch?: Record<string, unknown>;
1295
+ /** True when called with the deprecated name `referally`. */
1296
+ deprecated?: true;
1297
+ deprecatedAlias?: string;
597
1298
  manifest: CookiePresetManifest;
598
1299
  dryRun?: true;
599
1300
  declared?: DeclaredCookie[];
@@ -656,8 +1357,8 @@ interface ScanStatus {
656
1357
  lastScannedAt: number | null;
657
1358
  /** What the last scan saw of the live banner's Accept all / Reject all. Absent until measured. */
658
1359
  buttonParity?: ButtonParityScan;
659
- /** Where the last scan is. Absent when the site was never scanned. */
660
- state?: 'queued' | 'scanning' | 'done' | 'failed';
1360
+ /** Where the last scan is: `idle` when the site was never scanned (older servers left it out). */
1361
+ state?: 'idle' | 'queued' | 'scanning' | 'done' | 'failed';
661
1362
  scanId?: string;
662
1363
  startedAt?: number;
663
1364
  finishedAt?: number;
@@ -785,7 +1486,7 @@ interface ParityControlSummary {
785
1486
  * A warning, never an error — the config is saved regardless. See /docs/fair-consent-buttons.
786
1487
  */
787
1488
  interface ButtonParityFinding {
788
- code: 'reject_missing_first_layer' | 'reject_missing_same_layer' | 'reject_hidden' | 'reject_below_fold' | 'reject_isolated' | 'reject_low_emphasis' | 'saturation_gap' | 'color_mismatch' | 'reject_text_low_contrast' | 'reject_styled_as_link' | 'font_size_gap' | 'font_weight_gap' | 'size_gap' | 'padding_gap' | 'border_mismatch' | 'reject_label_missing' | 'reject_label_long' | 'confirmshaming' | 'custom_css_asymmetric';
1489
+ code: 'reject_missing_first_layer' | 'reject_missing_same_layer' | 'reject_hidden' | 'reject_below_fold' | 'reject_isolated' | 'reject_low_emphasis' | 'saturation_gap' | 'color_mismatch' | 'reject_text_low_contrast' | 'reject_styled_as_link' | 'font_size_gap' | 'font_weight_gap' | 'size_gap' | 'padding_gap' | 'border_mismatch' | 'reject_label_missing' | 'reject_label_long' | 'confirmshaming' | 'custom_css_asymmetric' | 'text_low_contrast' | 'link_low_contrast' | 'button_text_low_contrast' | 'focus_ring_low_contrast' | 'toggle_low_contrast' | 'control_boundary_low_contrast';
789
1490
  severity: 'warning' | 'notice';
790
1491
  layer: 'banner' | 'preferences' | 'modal' | 'popup' | 'bar' | 'inline' | 'custom';
791
1492
  accept: ParityControlSummary | null;
@@ -807,6 +1508,8 @@ interface ButtonParityFinding {
807
1508
  language?: string;
808
1509
  url?: string;
809
1510
  };
1511
+ /** On a contrast finding: the WCAG success criterion (1.4.3 text, 1.4.11 non-text). */
1512
+ wcag?: '1.4.3' | '1.4.11';
810
1513
  }
811
1514
  /** Reject all style values that would match the Accept all on the same layer. */
812
1515
  interface SuggestedRejectStyle {
@@ -1072,6 +1775,51 @@ interface BrandSuggestion {
1072
1775
  interface BrandExtractionResult {
1073
1776
  suggestion: BrandSuggestion;
1074
1777
  }
1778
+ /** PUT /v1/sites/{cbid}/brand: `{url}` alone (fetched once, https only), or a DTCG brand.json document. */
1779
+ type BrandImportInput = {
1780
+ url: string;
1781
+ } | Record<string, unknown>;
1782
+ /** One brand.json role and what it became. */
1783
+ interface BrandMappingRow {
1784
+ role: string;
1785
+ /** The site-config path it sets, e.g. `banner.theme.highlight`. */
1786
+ target: string;
1787
+ value: string | number;
1788
+ /** The rights-page theme token the same value feeds. */
1789
+ rightsPage?: string;
1790
+ /** `site` when the site's own banner theme value wins over brand.json. */
1791
+ source: 'brand.json' | 'site';
1792
+ inForce?: string | number;
1793
+ /** Variants that override it for some visitors. */
1794
+ variants?: string[];
1795
+ }
1796
+ /** The read-back of a brand.json import. Precedence: brand.json < site banner theme < per-banner variant. */
1797
+ interface BrandReadBack {
1798
+ cbid: string;
1799
+ dryRun?: boolean;
1800
+ source: {
1801
+ type: 'url';
1802
+ url: string;
1803
+ } | {
1804
+ type: 'body';
1805
+ };
1806
+ importedAt: number;
1807
+ precedence: string;
1808
+ mapping: BrandMappingRow[];
1809
+ ignored: Array<{
1810
+ role: string;
1811
+ reason: string;
1812
+ }>;
1813
+ warnings: Array<{
1814
+ role: string;
1815
+ code: 'third_party_font_host';
1816
+ message: string;
1817
+ }>;
1818
+ configWarnings?: Array<{
1819
+ field: string;
1820
+ reason: string;
1821
+ }>;
1822
+ }
1075
1823
  /** A validation/lint issue on a v2 banner flow. */
1076
1824
  interface FlowIssue {
1077
1825
  code: string;
@@ -1146,6 +1894,30 @@ interface ApiKeyPrefix {
1146
1894
  cbids?: string[] | null;
1147
1895
  /** Epoch ms it last authenticated a request (recorded at most hourly); null = not since recording began. */
1148
1896
  lastUsedAt?: number | null;
1897
+ /** The address of that request. */
1898
+ lastUsedIp?: string | null;
1899
+ /** `user:<id>`, `service:<name>` or `apikey:<prefix>`. */
1900
+ owner?: string | null;
1901
+ kind?: 'org' | 'site' | null;
1902
+ env?: 'live' | 'test' | null;
1903
+ format?: 'cookiemunch' | 'legacy';
1904
+ strictUnknownFields?: boolean;
1905
+ }
1906
+ /** A revoked key in the report: when, by whom, why; never the secret. */
1907
+ interface ApiKeyRevoked {
1908
+ prefix: string;
1909
+ name: string | null;
1910
+ owner: string | null;
1911
+ scopes: string[] | null;
1912
+ cbids: string[] | null;
1913
+ createdAt: number;
1914
+ expiresAt: number | null;
1915
+ lastUsedAt: number | null;
1916
+ lastUsedIp: string | null;
1917
+ revokedAt: number;
1918
+ revokedBy: string;
1919
+ reason: 'revoked' | 'rolled' | 'leaked';
1920
+ leakSource: string | null;
1149
1921
  }
1150
1922
  /** GET /v1/keys/report — key hygiene. */
1151
1923
  interface ApiKeyReport {
@@ -1163,11 +1935,21 @@ interface ApiKeyReport {
1163
1935
  }>;
1164
1936
  noExpiry: number;
1165
1937
  total: number;
1938
+ /** Revoked, rolled and leak-revoked keys, newest first. */
1939
+ revoked?: ApiKeyRevoked[];
1166
1940
  }
1167
- /** A newly issued key. `key` is returned ONCE and never again. Returned by keys.issue(). */
1941
+ /** A newly issued key. `key` is returned ONCE and never again (or, with `secretRecipient`, sealed). */
1168
1942
  interface ApiKeyIssued {
1169
1943
  key: string;
1170
1944
  prefix: string;
1945
+ expiresAt?: number | null;
1946
+ scopes?: string[] | null;
1947
+ cbids?: string[] | null;
1948
+ /** No expiry, or one over 365 days. */
1949
+ warnings?: string[];
1950
+ /** With `secretRecipient`: the key, sealed (and `key` absent). */
1951
+ sealed_secret?: string;
1952
+ sealed_field?: string;
1171
1953
  }
1172
1954
  /** @deprecated No endpoint returns this shape; use {@link ApiKeyPrefix} / {@link ApiKeyIssued}. */
1173
1955
  interface ApiKey {
@@ -1180,14 +1962,14 @@ interface ApiKey {
1180
1962
  secret?: string;
1181
1963
  }
1182
1964
  /**
1183
- * Input for issuing a new API key.
1184
- *
1185
- * NOTE: the server's POST /v1/keys currently accepts no body and always mints an
1186
- * unscoped key — `name` is not yet honoured server-side. It's kept here (rather than
1187
- * dropped) so a future scoped/named-key endpoint can start reading it without an SDK
1188
- * major version bump; see {@link CookieMunchClient.keys}.
1965
+ * Input for issuing a new API key (POST /v1/keys). Every field is honoured: `scopes`, `cbids`,
1966
+ * `expiresInDays` / `expiresAt`, `name`, `owner` and `strictUnknownFields`.
1189
1967
  */
1190
1968
  interface ApiKeyIssueInput {
1969
+ /** `user:<id>`, `service:<name>` or `apikey:<prefix>`. Default: the calling key. */
1970
+ owner?: string;
1971
+ /** Writes with the new key refuse unknown body fields unless they send `Prefer: lenient-unknown-fields`. */
1972
+ strictUnknownFields?: boolean;
1191
1973
  name?: string;
1192
1974
  /** Least privilege: grant only these scopes. Omit for a full-access key. */
1193
1975
  scopes?: string[];
@@ -1201,6 +1983,25 @@ interface ApiKeyIssueInput {
1201
1983
  /** Or when it expires: epoch ms or an ISO date-time (not with expiresInDays). Omit both: never. */
1202
1984
  expiresAt?: number | string;
1203
1985
  }
1986
+ /** One entitlement (suite-standard shape). A feature is `{key, enabled}`; a limit is `limits.<name>`. */
1987
+ interface Entitlement {
1988
+ key: string;
1989
+ enabled: boolean;
1990
+ /** Limits only. null = unlimited, 0 = not on this plan. */
1991
+ limit?: number | null;
1992
+ /** Limits the server meters, when metering is wired. */
1993
+ used?: number;
1994
+ source: 'plan';
1995
+ }
1996
+ /** GET /v1/entitlements: what the org may use, from its effective plan. */
1997
+ interface Entitlements {
1998
+ orgId: string;
1999
+ plan: string;
2000
+ planSource: 'org' | 'account';
2001
+ subscribedPlan: string;
2002
+ entitlements: Entitlement[];
2003
+ generatedAt: string;
2004
+ }
1204
2005
  /** Org usage/quota summary. Matches the server's Usage schema. */
1205
2006
  interface Usage {
1206
2007
  domains: number;
@@ -1217,6 +2018,86 @@ interface WebhookSubscription {
1217
2018
  cbid: string | null;
1218
2019
  active: boolean;
1219
2020
  createdAt: number;
2021
+ /** The endpoint lifecycle: `failing` from the first event that failed every retry, `disabled` after 72 hours. */
2022
+ state?: 'healthy' | 'failing' | 'disabled' | 'paused';
2023
+ failingSince?: number | null;
2024
+ disabledAt?: number | null;
2025
+ lastSuccessAt?: number | null;
2026
+ lastFailure?: {
2027
+ at: number;
2028
+ status: number | null;
2029
+ error: string | null;
2030
+ } | null;
2031
+ lastDeliveryAt?: number | null;
2032
+ lastStatus?: number | null;
2033
+ consecutiveFailures?: number;
2034
+ /** Who is emailed when it fails; null: the organisation's owners. */
2035
+ alertContacts?: string[] | null;
2036
+ /** On an update that re-enabled a disabled endpoint: how to send what it missed. */
2037
+ replay?: {
2038
+ since: number;
2039
+ path: string;
2040
+ };
2041
+ }
2042
+ /** POST /v1/webhooks/{id}/replay. */
2043
+ interface WebhookReplayResult {
2044
+ ok: boolean;
2045
+ replayed: number;
2046
+ failed: number;
2047
+ remaining: number;
2048
+ stoppedAt?: string;
2049
+ status?: number;
2050
+ error?: string;
2051
+ }
2052
+ /** The audit-log export (GET/PUT /v1/audit/sink). Never the secret. */
2053
+ interface AuditSink {
2054
+ type: 'webhook';
2055
+ url: string;
2056
+ secretSet: true;
2057
+ createdAt: number;
2058
+ updatedAt: number;
2059
+ lastDeliveryAt: number | null;
2060
+ lastStatus: number | null;
2061
+ lastError: string | null;
2062
+ }
2063
+ interface AuditSinkInput {
2064
+ type: 'webhook';
2065
+ url: string;
2066
+ /** 16–256 characters; omitted: one is generated and returned once. */
2067
+ secret?: string;
2068
+ }
2069
+ /** GET /v1/sites/{cbid}/consent/insights. */
2070
+ interface ConsentInsights {
2071
+ cbid: string;
2072
+ from: number;
2073
+ to: number;
2074
+ totals: {
2075
+ impressions: number | null;
2076
+ decisions: number;
2077
+ optIns: number;
2078
+ optOuts: number;
2079
+ optInRate: number | null;
2080
+ decisionRate: number | null;
2081
+ };
2082
+ byRegion: Array<{
2083
+ region: string;
2084
+ decisions: number;
2085
+ optIns: number;
2086
+ optInRate: number | null;
2087
+ }>;
2088
+ byVariant: Array<{
2089
+ variant: string;
2090
+ impressions: number;
2091
+ optIns: number;
2092
+ optInRate: number | null;
2093
+ }>;
2094
+ byVariantWindow: 'all_time';
2095
+ byLanguage: null;
2096
+ timeToDecision: null;
2097
+ notRecorded: {
2098
+ byLanguage: string;
2099
+ timeToDecision: string;
2100
+ };
1220
2101
  }
1221
2102
  /** One cookie read from another CMP's export. */
1222
2103
  interface ImportedCookie {
@@ -1495,6 +2376,8 @@ interface AuditEntry {
1495
2376
  }
1496
2377
  /** Rename a key, or replace its scopes or the properties it is locked to. */
1497
2378
  interface ApiKeyUpdate {
2379
+ owner?: string;
2380
+ strictUnknownFields?: boolean;
1498
2381
  name?: string;
1499
2382
  scopes?: string[];
1500
2383
  cbids?: string[];
@@ -1532,8 +2415,10 @@ interface WebhookUpdate {
1532
2415
  events?: string[];
1533
2416
  /** One property, or null for every property in the org. */
1534
2417
  cbid?: string | null;
1535
- /** false pauses delivery without deleting the subscription. */
2418
+ /** false pauses delivery without deleting the subscription; true re-enables a disabled one. */
1536
2419
  active?: boolean;
2420
+ /** 1–10 addresses emailed when it fails; null: back to the organisation's owners. */
2421
+ alertContacts?: string[] | null;
1537
2422
  }
1538
2423
  /** One site to create in a bulk call. */
1539
2424
  interface BulkSiteInput {
@@ -1900,14 +2785,53 @@ interface DsarExecutor {
1900
2785
  presetParams?: Record<string, string>;
1901
2786
  /** How the stored address and profile differ from what its preset version builds. Empty: unmodified. */
1902
2787
  presetDiff?: ConfigChange[];
2788
+ /** Preset-built: profile fields you removed or changed by hand; `upgradeExecutorPreset` keeps them. */
2789
+ profileOverrides?: Array<{
2790
+ path: string;
2791
+ kind: 'removed' | 'changed';
2792
+ at: number;
2793
+ }>;
2794
+ /** Preset-built: true when it must not follow its preset. */
2795
+ presetPinned?: boolean;
2796
+ /** Your name for the credential. */
2797
+ label?: string;
2798
+ /** 2: orchestrator v2 headers on every call; 1: the v1 adapter every connection made before v2 has. */
2799
+ orchestrator?: 1 | 2;
2800
+ hasCompletionSecret?: boolean;
2801
+ completionSecretPrefix?: string;
2802
+ /** When a signed completion last verified; running work is then polled every 6 hours. */
2803
+ lastSignedCompletionAt?: number | null;
2804
+ /** Where signed cm-standard-v2 completions go. */
2805
+ completionsUrl?: string;
2806
+ /** On create only: the completion secret, shown this once. */
2807
+ completionSecret?: string;
2808
+ }
2809
+ /** POST …/completion-secret/roll. */
2810
+ interface CompletionSecretRolled {
2811
+ id: string;
2812
+ completionSecret: string;
2813
+ completionSecretPrefix: string;
2814
+ previousRetiresAt: string | null;
2815
+ completionsUrl?: string;
2816
+ }
2817
+ /** POST …/test {conformance: true}: the conformance kit's report. */
2818
+ interface ExecutorConformanceResult extends ConformanceReport {
2819
+ conformance: true;
2820
+ canary: true;
2821
+ email: string;
1903
2822
  }
1904
- /** A connection's last canary health check. */
2823
+ /** A connection's last health check. */
1905
2824
  interface ExecutorHealth {
1906
2825
  lastCheckedAt: number;
1907
2826
  ok: boolean;
1908
2827
  verdict: string;
1909
2828
  /** e.g. `base_url_redirects`, `credential_unavailable`. */
1910
2829
  code?: string;
2830
+ /** When a check last passed. */
2831
+ lastSuccessAt?: number;
2832
+ /** On reads: true when the last check is more than an hour old, with the command that re-checks it in `hint`. */
2833
+ stale?: boolean;
2834
+ hint?: string;
1911
2835
  }
1912
2836
  /** A preset's name, as `executorPresets()` lists them. Not enumerated here: presets are data. */
1913
2837
  type ExecutorPresetName = string;
@@ -1924,9 +2848,15 @@ interface DsarExecutorPresetInput {
1924
2848
  baseUrl?: string;
1925
2849
  orgId?: string;
1926
2850
  atlasIdAppId?: string;
2851
+ /** A preset param, when the preset lists it: default false. True adds an optional step revoking the person's app grant on erasure. */
2852
+ revokeAtlasIdGrant?: boolean;
1927
2853
  webhookSecret?: string;
1928
2854
  auto?: boolean;
1929
2855
  cbid?: string;
2856
+ /** Your name for the credential, shown beside `keyPrefix`. */
2857
+ label?: string;
2858
+ /** Default 2. */
2859
+ orchestrator?: 1 | 2;
1930
2860
  }
1931
2861
  /** What `upgradeExecutorPreset` takes: a version, a preset to adopt, or params to add. */
1932
2862
  interface ExecutorPresetUpgrade {
@@ -1934,6 +2864,25 @@ interface ExecutorPresetUpgrade {
1934
2864
  presetVersion?: number;
1935
2865
  orgId?: string;
1936
2866
  atlasIdAppId?: string;
2867
+ revokeAtlasIdGrant?: boolean;
2868
+ /** Overridden paths (`profileOverrides`) that take the preset's value again; every other override is kept. */
2869
+ acceptPreset?: string | string[];
2870
+ }
2871
+ /** One step a preset builds, and whether it can run now (CMU-B01). */
2872
+ interface ExecutorPresetStep {
2873
+ name: 'subjectLookup' | 'open' | 'poll' | 'webhook' | 'grantRevoke';
2874
+ available: boolean;
2875
+ /** Never fails a connection: a credential without the scope reports `skipped: insufficient_scope`. */
2876
+ optional?: boolean;
2877
+ /** False: added only with `param`. */
2878
+ defaultOn: boolean;
2879
+ param?: string;
2880
+ note?: string;
2881
+ waitingOn?: {
2882
+ platform: string;
2883
+ items: string[];
2884
+ operations: string[];
2885
+ };
1937
2886
  }
1938
2887
  /** The presets, which are usable now, and this org's canary address. */
1939
2888
  interface ExecutorPresets {
@@ -1947,6 +2896,7 @@ interface ExecutorPresets {
1947
2896
  name: string;
1948
2897
  required: boolean;
1949
2898
  description: string;
2899
+ type?: 'string' | 'boolean';
1950
2900
  }>;
1951
2901
  available: boolean;
1952
2902
  waitingOn?: {
@@ -1954,6 +2904,7 @@ interface ExecutorPresets {
1954
2904
  items: string[];
1955
2905
  operations: string[];
1956
2906
  };
2907
+ steps: ExecutorPresetStep[];
1957
2908
  }>;
1958
2909
  }
1959
2910
  /** What a connection write would do (`?dryRun=1`). Nothing was stored. */
@@ -2015,6 +2966,8 @@ interface DsarExecutorInput {
2015
2966
  subjectNote?: string;
2016
2967
  /** How to drive it. */
2017
2968
  profile: ExecutorProfile;
2969
+ /** Default 2. */
2970
+ orchestrator?: 1 | 2;
2018
2971
  }
2019
2972
  type DsarExecutorCreated = DsarExecutor;
2020
2973
  /** The fields `updateExecutor` may change. */
@@ -2026,12 +2979,18 @@ interface DsarExecutorPatch {
2026
2979
  auto?: boolean;
2027
2980
  /** null removes it. */
2028
2981
  subjectNote?: string | null;
2982
+ /** Your name for the credential; null removes it. */
2983
+ label?: string | null;
2984
+ /** Preset-built only: true stops `upgradeExecutorPreset` changing it. */
2985
+ presetPinned?: boolean;
2986
+ /** Opt in to (2) or out of (1) orchestrator v2. */
2987
+ orchestrator?: 1 | 2;
2029
2988
  }
2030
2989
  /** One entry in a fulfilment task's status history. */
2031
2990
  interface DsarTaskEvent {
2032
2991
  at: number;
2033
2992
  kind: 'created' | 'changed' | 'version_changed';
2034
- status: 'pending' | 'running' | 'done' | 'failed';
2993
+ status: 'pending' | 'running' | 'done' | 'failed' | 'cancelled';
2035
2994
  detail?: string;
2036
2995
  outcome?: DsarTaskOutcome;
2037
2996
  scheduledFor?: number;
@@ -2070,7 +3029,7 @@ interface DsarTask {
2070
3029
  requestId: string;
2071
3030
  system: string;
2072
3031
  operation: FulfillmentOp;
2073
- status: 'pending' | 'running' | 'done' | 'failed';
3032
+ status: 'pending' | 'running' | 'done' | 'failed' | 'cancelled';
2074
3033
  detail?: string;
2075
3034
  outcome?: DsarTaskOutcome;
2076
3035
  attempts: number;
@@ -2111,6 +3070,11 @@ interface ExecutorTestResult {
2111
3070
  code?: string;
2112
3071
  /** The subject's app grant at an identity platform, when the profile has a grant step. Never revoked by a test. */
2113
3072
  grant?: string;
3073
+ /** Optional steps this credential may not run: reported, never a failure. */
3074
+ skipped?: Array<{
3075
+ step: string;
3076
+ reason: 'insufficient_scope';
3077
+ }>;
2114
3078
  /** Present when the test used the org canary address, with the address in `email`. */
2115
3079
  canary?: boolean;
2116
3080
  email?: string;
@@ -2159,7 +3123,7 @@ interface CookieMunchClient {
2159
3123
  * comes from, plus the per-account org cap and the upgrade URL. Needs an unscoped key that
2160
3124
  * is not locked to properties.
2161
3125
  */
2162
- list(): Promise<AccountOrgs>;
3126
+ list(opts?: MetadataFilter): Promise<AccountOrgs>;
2163
3127
  /**
2164
3128
  * Create a sibling organisation owned by the same account — for a separate business of
2165
3129
  * your own. Needs an unscoped key. Not reseller provisioning, which is for your customers.
@@ -2167,7 +3131,9 @@ interface CookieMunchClient {
2167
3131
  create(name: string, opts?: {
2168
3132
  mintKey?: boolean;
2169
3133
  keyScopes?: string[];
2170
- }): Promise<{
3134
+ keyExpiresInDays?: number;
3135
+ keyOwner?: string;
3136
+ } & ResourceTagsInput): Promise<{
2171
3137
  org: {
2172
3138
  id: string;
2173
3139
  name: string;
@@ -2176,10 +3142,28 @@ interface CookieMunchClient {
2176
3142
  apiKey?: string;
2177
3143
  keyError?: string;
2178
3144
  }>;
3145
+ /** Hard-delete a SANDBOX organisation of this account (created with metadata.forgedeck_sandbox). Anything else: 403 not_a_sandbox. */
3146
+ deleteSandbox(id: string): Promise<SandboxPurge>;
3147
+ };
3148
+ /** Tags on any created resource (CMU-X29). */
3149
+ metadata: {
3150
+ get(type: TaggedType, id: string): Promise<ResourceTags>;
3151
+ /** Merge tags (null removes one). `forgedeck_sandbox` cannot be set here. `{ dryRun: true }` answers with the diff. */
3152
+ update(type: TaggedType, id: string, metadata: Record<string, string | number | boolean | null>, opts?: {
3153
+ dryRun?: boolean;
3154
+ }): Promise<ResourceTagsUpdate>;
3155
+ };
3156
+ /** Partner links in the suite-standard shape (CMU-X34). */
3157
+ partnerLinks: {
3158
+ list(opts?: MetadataFilter): Promise<StandardPartnerLink[]>;
3159
+ create(input: StandardPartnerLinkCreate): Promise<StandardPartnerLink>;
3160
+ revoke(id: string): Promise<StandardPartnerLink>;
2179
3161
  };
3162
+ /** What `forgedeck env` writes for a product provisioned with this forgedeck ref: names, values, secret references. */
3163
+ provisionEnv(ref: string): Promise<ProvisionEnv>;
2180
3164
  sites: {
2181
- list(): Promise<Site[]>;
2182
- create(input: SiteCreate): Promise<Site>;
3165
+ list(opts?: MetadataFilter): Promise<Site[]>;
3166
+ create(input: SiteCreate & ResourceTagsInput): Promise<Site>;
2183
3167
  get(cbid: string): Promise<Site>;
2184
3168
  /**
2185
3169
  * Rename or move a site: domain, display name, aliases. The cbid and the consent ledger stay; a domain
@@ -2189,6 +3173,8 @@ interface CookieMunchClient {
2189
3173
  dryRun?: boolean;
2190
3174
  }): Promise<SiteUpdateResult>;
2191
3175
  delete(cbid: string): Promise<void>;
3176
+ /** Purge a SANDBOX site: its consent ledger, declarations and test rights requests too. Anything else: 403 not_a_sandbox. */
3177
+ deleteSandbox(cbid: string): Promise<SandboxPurge>;
2192
3178
  /** Partner platforms granted this site's consent events, and the partners on offer. */
2193
3179
  listPartners(cbid: string): Promise<{
2194
3180
  links: PartnerLink[];
@@ -2326,9 +3312,10 @@ interface CookieMunchClient {
2326
3312
  dryRun: true;
2327
3313
  retired: RetiredCookie[];
2328
3314
  }>;
2329
- /** Every declaration preset (atlas, forumulate, chatly, cookiemunch, referally): params, what it declared here, manifest status. */
3315
+ /** Every declaration preset (atlas, forumulate, chatly, cookiemunch, referalli, firstpromoter, partnerstack, tapfiliate, impact): params, what it declared here, manifest status. */
2330
3316
  cookiePresets(cbid: string): Promise<{
2331
3317
  presets: CookiePreset[];
3318
+ aliases?: Record<string, string>;
2332
3319
  }>;
2333
3320
  /**
2334
3321
  * Apply (or re-sync) a vendor preset: declares what that platform writes, marked
@@ -2337,11 +3324,28 @@ interface CookieMunchClient {
2337
3324
  applyCookiePreset(cbid: string, vendor: CookiePresetVendor, params?: CookiePresetParams, opts?: {
2338
3325
  dryRun?: boolean;
2339
3326
  }): Promise<CookiePresetResult>;
3327
+ /**
3328
+ * Declare ANY vendor's cookies and storage from its embed manifest (`url`, re-read hourly, or
3329
+ * the `manifest` itself). The vendor id is the manifest's `product`; remove it with
3330
+ * removeCookiePreset(cbid, product). `dryRun` stores nothing.
3331
+ */
3332
+ importCookieManifest(cbid: string, input: CustomPresetInput, opts?: {
3333
+ dryRun?: boolean;
3334
+ }): Promise<CookiePresetResult>;
3335
+ /** What to declare: detected vendors (script, storage, manifest) and one suggestion per undeclared row. */
3336
+ cookieSuggestions(cbid: string): Promise<CookieSuggestions>;
3337
+ /** Declare the suggestions: detected vendors' presets, then every other suggestion with a purpose. Try `dryRun` first. */
3338
+ declareCookieSuggestions(cbid: string, input?: {
3339
+ names?: string[];
3340
+ presets?: boolean;
3341
+ }, opts?: {
3342
+ dryRun?: boolean;
3343
+ }): Promise<CookieSuggestionsDeclared>;
2340
3344
  /** Remove every declaration a vendor preset made. */
2341
- removeCookiePreset(cbid: string, vendor: CookiePresetVendor, opts?: {
3345
+ removeCookiePreset(cbid: string, vendor: CookiePresetVendor | (string & {}), opts?: {
2342
3346
  dryRun?: boolean;
2343
3347
  }): Promise<{
2344
- vendor: CookiePresetVendor;
3348
+ vendor: string;
2345
3349
  removed: string[];
2346
3350
  dryRun?: true;
2347
3351
  declared?: DeclaredCookie[];
@@ -2400,6 +3404,12 @@ interface CookieMunchClient {
2400
3404
  results: BulkSiteResult[];
2401
3405
  }>;
2402
3406
  brand(cbid: string): Promise<BrandExtractionResult>;
3407
+ /** Read back the brand.json last imported: each role, its source (brand.json or site), ignored[] and warnings[]. 404 when none. */
3408
+ getBrand(cbid: string): Promise<BrandReadBack>;
3409
+ /** Import a brand.json (`{url}` or the document) into the banner theme and the rights page. `dryRun` saves nothing. */
3410
+ setBrand(cbid: string, input: BrandImportInput, opts?: {
3411
+ dryRun?: boolean;
3412
+ }): Promise<BrandReadBack>;
2403
3413
  /** Read a site's v2 banner flow (views, categories) plus any lint issues. */
2404
3414
  getFlow(cbid: string): Promise<SiteFlow>;
2405
3415
  /** Apply an ordered batch of structured edit ops; validated + persisted if lint-clean. */
@@ -2417,6 +3427,8 @@ interface CookieMunchClient {
2417
3427
  valid: boolean;
2418
3428
  }>;
2419
3429
  stats(cbid: string, query?: RangeQuery): Promise<ConsentDay[]>;
3430
+ /** Opt-in by region and A/B variant, and the decision rate. Language and time-to-decision are not recorded (null). */
3431
+ insights(cbid: string, query?: RangeQuery): Promise<ConsentInsights>;
2420
3432
  log(cbid: string, query?: LogQuery): Promise<ConsentLogRow[]>;
2421
3433
  export(cbid: string, query?: RangeQuery): Promise<string>;
2422
3434
  receipt(cbid: string, stamp: string): Promise<SignedReceipt>;
@@ -2435,6 +3447,12 @@ interface CookieMunchClient {
2435
3447
  * prefix and no auth is required by the server (the cbid must be a registered site); for
2436
3448
  * server-side / non-browser consent flows. Pass `subjectId` to correlate a subject cross-surface. */
2437
3449
  ingest(input: ConsentIngestInput): Promise<void>;
3450
+ /**
3451
+ * The reserved categories any site can switch on with `categories.suite` (`support_chat`,
3452
+ * `referrals`): stance, fallback, regulatory basis, wording in every banner language, and
3453
+ * known vendors. Public — `GET /v1/categories/registry` needs no key.
3454
+ */
3455
+ categoryRegistry(): Promise<CategoryRegistry>;
2438
3456
  };
2439
3457
  dsar: {
2440
3458
  list(): Promise<DsarRequest[]>;
@@ -2443,7 +3461,7 @@ interface CookieMunchClient {
2443
3461
  * wrapped as `{ request }`, so `create(...).request.id` is what you pass here.
2444
3462
  */
2445
3463
  get(id: string): Promise<DsarRequest>;
2446
- create(input: DsarCreate): Promise<{
3464
+ create(input: DsarCreate & ResourceTagsInput): Promise<{
2447
3465
  request: DsarRequest;
2448
3466
  }>;
2449
3467
  /** `opts.messageToSubject` replaces the line the subject reads in the notice — for a rejection, why. */
@@ -2478,6 +3496,24 @@ interface CookieMunchClient {
2478
3496
  request: DsarRequest;
2479
3497
  changed: boolean;
2480
3498
  }>;
3499
+ /** Requests carrying one X-ForgeDeck-Trace (`GET /v1/dsar?trace=`). */
3500
+ listByTrace(trace: string): Promise<DsarRequest[]>;
3501
+ /**
3502
+ * Open a case fanned out to every connected system (POST /v1/dsar/requests). `opts.idempotencyKey`
3503
+ * (16–128 chars) makes a retry answer the same case; `opts.trace` passes your X-ForgeDeck-Trace on.
3504
+ */
3505
+ openCase(input: DsarCaseCreate, opts?: {
3506
+ idempotencyKey?: string;
3507
+ trace?: string;
3508
+ }): Promise<DsarCase>;
3509
+ /** One case across every system. */
3510
+ getCase(id: string): Promise<DsarCase>;
3511
+ /** Cancel a case before executeAfter; status `cancelled` once every system confirmed. */
3512
+ cancelCase(id: string): Promise<DsarCase>;
3513
+ /** The signed receipt for a case. */
3514
+ caseReceipt(id: string): Promise<DsarCaseReceipt>;
3515
+ /** The signed receipt as a PDF. */
3516
+ caseReceiptPdf(id: string): Promise<ArrayBuffer>;
2481
3517
  };
2482
3518
  vendors: {
2483
3519
  list(): Promise<ScoredVendor[]>;
@@ -2716,12 +3752,14 @@ interface CookieMunchClient {
2716
3752
  * platform holding your users' accounts, for instance. The in-VPC agent covers the
2717
3753
  * systems we cannot reach; these are the ones we can.
2718
3754
  */
2719
- executors(): Promise<DsarExecutor[]>;
3755
+ executors(opts?: MetadataFilter): Promise<DsarExecutor[]>;
3756
+ /** One connection with its full profile, never the credentials. Read it before changing `profile`: `updateExecutor` replaces the whole profile. */
3757
+ executor(id: string): Promise<DsarExecutor>;
2720
3758
  /**
2721
3759
  * Connect one. The secret is stored encrypted and never returned; the response carries
2722
3760
  * the URL to point that system's webhook at.
2723
3761
  */
2724
- connectExecutor(input: DsarExecutorInput | DsarExecutorPresetInput): Promise<DsarExecutorCreated>;
3762
+ connectExecutor(input: (DsarExecutorInput | DsarExecutorPresetInput) & ResourceTagsInput): Promise<DsarExecutorCreated>;
2725
3763
  /**
2726
3764
  * Change a connection in place. Only what you send changes, and the stored credential
2727
3765
  * is kept unless you pass a new `secretKey` — so adding a field to a profile does not
@@ -2771,6 +3809,16 @@ interface CookieMunchClient {
2771
3809
  * the raw (redacted) upstream answers and what a real request would have sent.
2772
3810
  */
2773
3811
  testExecutor(id: string, input: ExecutorTestInput): Promise<ExecutorTestResult>;
3812
+ /** Re-check a connection now (a canary test that records its health); for a deploy pipeline. */
3813
+ recheckExecutor(id: string): Promise<ExecutorTestResult>;
3814
+ /** A connection's last health checks, newest first (`limit` 1 to 50, default 50). */
3815
+ executorHealthHistory(id: string, opts?: {
3816
+ limit?: number;
3817
+ }): Promise<ExecutorHealth[]>;
3818
+ /** Run the cm-standard-v2 conformance kit against a connection, on the canary subject only. */
3819
+ executorConformance(id: string): Promise<ExecutorConformanceResult>;
3820
+ /** A new completion secret, shown once; the old one keeps verifying for 24 hours. */
3821
+ rollExecutorCompletionSecret(id: string): Promise<CompletionSecretRolled>;
2774
3822
  };
2775
3823
  preferences: {
2776
3824
  list(): Promise<PreferenceItem[]>;
@@ -2831,16 +3879,55 @@ interface CookieMunchClient {
2831
3879
  unusedDays?: number;
2832
3880
  expiringDays?: number;
2833
3881
  }): Promise<ApiKeyReport>;
3882
+ /** The suite-standard listing (`?shape=standard`). */
3883
+ listStandard(): Promise<StandardKeyList>;
3884
+ /** The calling key itself, whatever its scopes: check its own expiry. */
3885
+ self(): Promise<ApiKeyPrefix>;
3886
+ /** The calling key rotates itself; the old secret stops at once. Use a client with an Idempotency-Key header. */
3887
+ rollSelf(): Promise<ApiKeyIssued>;
3888
+ /** A short-lived key (ttlSeconds at most 43200) within this key's own scopes and properties. Needs keys:write or full access. */
3889
+ vend(input: {
3890
+ scopes: string[];
3891
+ ttlSeconds: number;
3892
+ cbids?: string[];
3893
+ name?: string;
3894
+ }): Promise<ApiKeyVended>;
3895
+ /** Revoke a leaked secret (works without a valid key; always answers { received }). */
3896
+ revokeLeaked(report: LeakReport): Promise<{
3897
+ received: number;
3898
+ }>;
2834
3899
  };
2835
3900
  usage(): Promise<Usage>;
3901
+ /** What the org may use: every plan feature (`whiteLabel`, `tcf`, …) and limit, in the suite-standard shape. Any key may read it. */
3902
+ entitlements(): Promise<Entitlements>;
2836
3903
  /** Every link a site's privacy wiring depends on, one row each with `ok` and a fix hint. `cbid` may be omitted with one site. */
2837
3904
  integrationHealth(cbid?: string): Promise<IntegrationHealthReport>;
3905
+ /** Waive a health check you chose not to meet: the row reports `ok: null` with `waived`. Audited. */
3906
+ healthWaivers: {
3907
+ list(cbid?: string): Promise<{
3908
+ cbid: string;
3909
+ waivers: HealthWaiver[];
3910
+ }>;
3911
+ set(input: HealthWaiverInput): Promise<{
3912
+ waiver: HealthWaiver;
3913
+ }>;
3914
+ remove(check: string, opts?: {
3915
+ cbid?: string;
3916
+ subject?: string;
3917
+ }): Promise<void>;
3918
+ };
3919
+ /**
3920
+ * The site's embed manifest: the tenant variant of `/.well-known/forgedeck-embed.json` — every
3921
+ * origin by CSP directive and every browser key the embed writes for this site's config. Public.
3922
+ */
3923
+ embedManifest(cbid: string): Promise<EmbedManifest>;
2838
3924
  /**
2839
3925
  * Wire a product's privacy in one call: the site, connected systems, Atlas and Forumulate. Idempotent;
2840
3926
  * `{ dryRun: true }` writes nothing anywhere. No secret appears in the answer.
2841
3927
  */
2842
- provision(input: ProvisionRequest, opts?: {
3928
+ provision(input: ProvisionRequest | ProvisionRequestV2, opts?: {
2843
3929
  dryRun?: boolean;
3930
+ fromStep?: string;
2844
3931
  }): Promise<ProvisionResult>;
2845
3932
  /** The key's organisation. Requires an unscoped key that is not property-locked. */
2846
3933
  org: {
@@ -2889,9 +3976,23 @@ interface CookieMunchClient {
2889
3976
  };
2890
3977
  };
2891
3978
  /** The org's audit log, newest first. API actions appear as `apikey:<prefix>`. */
2892
- audit(limit?: number): Promise<{
3979
+ /** `{ actor: 'self' }` reads the calling key's own rows, the one form a scoped key may call. */
3980
+ audit(limit?: number, opts?: {
3981
+ actor?: string;
3982
+ }): Promise<{
2893
3983
  entries: AuditEntry[];
2894
3984
  }>;
3985
+ /** Stream the audit log to an HTTPS endpoint as CloudEvents 1.0. Unscoped keys. */
3986
+ auditSink: {
3987
+ get(): Promise<{
3988
+ sink: AuditSink;
3989
+ }>;
3990
+ set(input: AuditSinkInput): Promise<{
3991
+ sink: AuditSink;
3992
+ secret?: string;
3993
+ }>;
3994
+ remove(): Promise<void>;
3995
+ };
2895
3996
  assets: {
2896
3997
  /** Upload a banner image (≤ 1,000,000 bytes) and get its public URL. Requires sites:write. */
2897
3998
  upload(input: AssetUpload): Promise<{
@@ -2926,8 +4027,8 @@ interface CookieMunchClient {
2926
4027
  revokeKey(id: string, prefix: string): Promise<void>;
2927
4028
  };
2928
4029
  webhooks: {
2929
- list(): Promise<WebhookSubscription[]>;
2930
- create(input: WebhookCreate): Promise<WebhookSubscription>;
4030
+ list(opts?: MetadataFilter): Promise<WebhookSubscription[]>;
4031
+ create(input: WebhookCreate & ResourceTagsInput): Promise<WebhookSubscription>;
2931
4032
  /** Change or pause a subscription. `{ active: false }` pauses without deleting it. */
2932
4033
  update(id: string, patch: WebhookUpdate): Promise<WebhookSubscription>;
2933
4034
  delete(id: string): Promise<void>;
@@ -2943,6 +4044,10 @@ interface CookieMunchClient {
2943
4044
  }>;
2944
4045
  /** Deliver a dead letter again, to the subscription as it is now. */
2945
4046
  replayDeadLetter(id: string): Promise<unknown>;
4047
+ /** Send what a failing or disabled endpoint missed since `since` (epoch ms or ISO), oldest first, stopping at the first failure. */
4048
+ replay(id: string, since: number | string, opts?: {
4049
+ limit?: number;
4050
+ }): Promise<WebhookReplayResult>;
2946
4051
  };
2947
4052
  /**
2948
4053
  * Account-linked rights requests: a single-use link to the hosted rights page for a person your
@@ -2984,6 +4089,23 @@ interface CookieMunchClient {
2984
4089
  /** Remove the site's own setting: it inherits the organisation default again. */
2985
4090
  remove(cbid: string): Promise<RightsIdentity>;
2986
4091
  };
4092
+ /** A site's rights-request settings: graceDays (0–30; 7 for a new site, 0 until set for one that existed before). Requires dsar:read / dsar:write. */
4093
+ dsarSettings: {
4094
+ get(cbid: string): Promise<DsarSettings>;
4095
+ set(cbid: string, input: {
4096
+ graceDays: number;
4097
+ }): Promise<DsarSettings>;
4098
+ };
4099
+ /** Cards for support, CRM and helpdesk sidebars. Requires dsar:read. */
4100
+ integrations: {
4101
+ /** Open rights requests for one person, by identity (preferred) or email. */
4102
+ subjectCard(app: string, person: {
4103
+ iss: string;
4104
+ sub: string;
4105
+ } | {
4106
+ email: string;
4107
+ }): Promise<SubjectCard>;
4108
+ };
2987
4109
  /** One person's consent across every site in the org, by the subjectId your apps attach. */
2988
4110
  subjects: {
2989
4111
  /** Requires consent:read; not available to property-locked keys. */
@@ -3019,4 +4141,4 @@ interface CookieMunchClient {
3019
4141
  }
3020
4142
  declare function createCookieMunch(opts: CookieMunchOptions): CookieMunchClient;
3021
4143
 
3022
- export { type AbResult, type AccountOrg, type AccountOrgs, type AdPersonalizationInput, type AiInspectInput, type AiInspectResult, type ApiKey, type ApiKeyIssueInput, type ApiKeyIssued, type ApiKeyPrefix, type ApiKeyReport, type ApiKeyUpdate, type AppliedImport, type AssetUpload, type AuditEntry, type BannerRecord, type BannerSummary, type BlockedReport, type BrandExtractionResult, type BrandKit, type BrandKitCreate, type BrandSuggestion, type BulkSiteInput, type BulkSiteResult, type ButtonParityFinding, type ButtonParityLint, type ButtonParityScan, type CategorizedCookie, type CenterToken, type CenterTokenInput, type ChildKeyInput, type ConfigChange, type ConfigDryRun, type ConfigWarning, type ConsentDay, type ConsentDecisionInput, type ConsentIngestInput, type ConsentLogRow, type ConsentSyncSecret, type ConsentSyncSecretMinted, type CookieDeclaration, CookieMunchApiError, type CookieMunchClient, type CookieMunchOptions, type CookiePreset, type CookiePresetManifest, type CookiePresetParams, type CookiePresetResult, type CookiePresetVendor, type CspSources, type DeclarationDiff, type DeclarationDryRun, type DeclarationWarning, type DeclaredCookie, type DeclaredCookieInput, type DnsRecordInstruction, type DsarCreate, type DsarEraseResult, type DsarExecutor, type DsarExecutorCreated, type DsarExecutorDryRun, type DsarExecutorInput, type DsarExecutorPatch, type DsarExecutorPresetInput, type DsarExportResult, type DsarRequest, type DsarStatus, type DsarTask, type DsarTaskEvent, type DsarTaskExport, type DsarTaskLogEntry, type DsarTaskOutcome, type DsarType, type EnforcementRuleInput, type ExecutorHealth, type ExecutorPresetName, type ExecutorPresetUpgrade, type ExecutorPresets, type ExecutorProfile, type ExecutorTestInput, type ExecutorTestResult, type ExecutorWebhookDelivery, type ExecutorWebhookTestResult, type FlowIssue, type FlowOp, type FlowOpResponse, type FulfillmentOp, type HealthRow, type Identifier, type Identity, type ImportedCookie, type ImportedDeclaration, type InstallSnippet, type IntegrationHealthReport, type LegalBasis, type LogQuery, type MailProvider, type MailProviderInput, type MailProviderKind, type MailProviderTestResult, type Member, type MintConsentSyncTokenInput, type ObservedPurgeResult, type OptInMethod, type Org, type OrgControllerIdentity, type OrgControllerInput, type OrgUpdate, type ParityControlSummary, type PartnerCatalogEntry, type PartnerId, type PartnerLink, type PartnerLinkCreate, type PlanSource, type PolicyOptions, type PreferenceItem, type PreferenceRecord, type PreviewToken, type PreviewTokenOptions, type ProfileAttributeInput, type ProvisionRequest, type ProvisionResult, type ProvisionStep, type PublicDsarFiled, type PublicDsarPending, type PublicVerification, type PutConfigOptions, type RangeQuery, type Regulation, type RegulationSummary, type RegulatoryFeedResult, type ResellerChild, type ResellerChildCreate, type ResellerChildList, type ResellerChildPatch, type RetiredCookie, type RightKind, type RightsCaptcha, type RightsCaptchaInput, type RightsCaptchaProvider, type RightsIdentity, type RightsIdentityInput, type RightsIdentityType, type RightsLink, type RightsLinkInput, type RightsPageDocument, type RightsPageDomain, type RightsPageDomainList, type RightsPageDraft, type RightsPageDraftConflict, type RightsPageDryRun, type RightsPageIssue, type RightsPagePublishResult, type RightsPagePublished, type RightsPagePublisher, type RightsPageVersions, type RightsPageWriteOptions, type RiskScore, type RopaEntry, type RopaInput, SDK_VERSION, type ScanResult, type ScanStatus, type ScoredVendor, type ScrollbarTheme, type SessionAnalysisInput, type SignedReceipt, type Site, type SiteConfig, type SiteCookie, type SiteCreate, type SiteFlow, type SiteUpdate, type SiteUpdateResult, type SnippetOptions, type StorageType, type SubscriptionTopicInput, type SuggestedRejectStyle, type SupportedLanguage, type Usage, type VendorInput, type VendorRecord, type VerifyResult, type VerifyWebhookInput, type WebhookCreate, type WebhookDeadLetter, type WebhookKeyForm, type WebhookStage, type WebhookSubscription, type WebhookTestResult, type WebhookUpdate, createCookieMunch, mintConsentSyncToken, verifyWebhookSignature };
4144
+ export { type AbResult, type AccountOrg, type AccountOrgs, type AdPersonalizationInput, type AiInspectInput, type AiInspectResult, type ApiKey, type ApiKeyIssueInput, type ApiKeyIssued, type ApiKeyPrefix, type ApiKeyReport, type ApiKeyRevoked, type ApiKeyUpdate, type ApiKeyVended, type AppliedImport, type AssetUpload, type AuditEntry, type AuditSink, type AuditSinkInput, type BannerRecord, type BannerSummary, type BlockedReport, type BrandExtractionResult, type BrandImportInput, type BrandKit, type BrandKitCreate, type BrandMappingRow, type BrandReadBack, type BrandSuggestion, type BulkSiteInput, type BulkSiteResult, type ButtonParityFinding, type ButtonParityLint, type ButtonParityScan, CANARY_ISSUER, CONFORMANCE_RULES, type CategorizedCookie, type CategoryRegistry, type CenterToken, type CenterTokenInput, type ChildKeyInput, type CompletionSecretRolled, type ConfigChange, type ConfigDryRun, type ConfigWarning, type ConformanceOptions, type ConformanceReport, type ConformanceRuleResult, type ConformanceStatus, type ConsentDay, type ConsentDecisionInput, type ConsentIngestInput, type ConsentInsights, type ConsentLogRow, type ConsentSyncSecret, type ConsentSyncSecretMinted, type CookieDeclaration, CookieMunchApiError, type CookieMunchClient, type CookieMunchOptions, type CookiePreset, type CookiePresetManifest, type CookiePresetParams, type CookiePresetResult, type CookiePresetVendor, type CookieSuggestion, type CookieSuggestions, type CookieSuggestionsDeclared, type CspSources, type CustomPresetInput, type DeclarationDiff, type DeclarationDryRun, type DeclarationWarning, type DeclaredCookie, type DeclaredCookieInput, type DnsRecordInstruction, type DsarCase, type DsarCaseCreate, type DsarCaseReceipt, type DsarCaseStatus, type DsarCaseTask, type DsarCreate, type DsarEraseResult, type DsarExecutor, type DsarExecutorCreated, type DsarExecutorDryRun, type DsarExecutorInput, type DsarExecutorPatch, type DsarExecutorPresetInput, type DsarExportResult, type DsarRequest, type DsarSettings, type DsarStatus, type DsarSubject, type DsarTask, type DsarTaskEvent, type DsarTaskExport, type DsarTaskLogEntry, type DsarTaskOutcome, type DsarType, type DsarTypeWord, type EmbedManifest, type EmbedManifestStorage, type EmbedManifestSurface, type EnforcementRuleInput, type Entitlement, type Entitlements, type ExecutorConformanceResult, type ExecutorHealth, type ExecutorPresetName, type ExecutorPresetStep, type ExecutorPresetUpgrade, type ExecutorPresets, type ExecutorProfile, type ExecutorTestInput, type ExecutorTestResult, type ExecutorWebhookDelivery, type ExecutorWebhookTestResult, type FdCause, type FdConsent, type FdConsentQueue, type FdQueuedCall, type FdRequestOptions, type FdSnapshot, type FlowIssue, type FlowOp, type FlowOpResponse, type FulfillmentOp, type HealthRow, type HealthWaiver, type HealthWaiverInput, type Identifier, type Identity, type ImportedCookie, type ImportedDeclaration, type InstallSnippet, type IntegrationHealthReport, type LeakReport, type LegalBasis, type LogQuery, type MailProvider, type MailProviderInput, type MailProviderKind, type MailProviderTestResult, type Member, type MetadataFilter, type MintConsentSyncTokenInput, type ObservedPurgeResult, type OptInMethod, type Org, type OrgControllerIdentity, type OrgControllerInput, type OrgUpdate, type ParityControlSummary, type PartnerCatalogEntry, type PartnerId, type PartnerLink, type PartnerLinkCreate, type PlanSource, type PolicyOptions, type PreferenceItem, type PreferenceRecord, type PreviewToken, type PreviewTokenOptions, type ProfileAttributeInput, type ProvisionEnv, type ProvisionRequest, type ProvisionRequestV2, type ProvisionResult, type ProvisionStep, type PublicDsarFiled, type PublicDsarPending, type PublicVerification, type PutConfigOptions, type RangeQuery, type Regulation, type RegulationSummary, type RegulatoryFeedResult, type ResellerChild, type ResellerChildCreate, type ResellerChildList, type ResellerChildPatch, type ResourceMetadata, type ResourceTags, type ResourceTagsInput, type ResourceTagsUpdate, type RetentionLine, type RetiredCookie, type RightKind, type RightsCaptcha, type RightsCaptchaInput, type RightsCaptchaProvider, type RightsIdentity, type RightsIdentityInput, type RightsIdentityType, type RightsLink, type RightsLinkInput, type RightsPageDocument, type RightsPageDomain, type RightsPageDomainList, type RightsPageDraft, type RightsPageDraftConflict, type RightsPageDryRun, type RightsPageIssue, type RightsPagePublishResult, type RightsPagePublished, type RightsPagePublisher, type RightsPageVersions, type RightsPageWriteOptions, type RiskScore, type RopaEntry, type RopaInput, SDK_VERSION, type SandboxPurge, type ScanResult, type ScanStatus, type ScoredVendor, type ScrollbarTheme, type SessionAnalysisInput, type SignedReceipt, type Site, type SiteConfig, type SiteCookie, type SiteCreate, type SiteFlow, type SiteUpdate, type SiteUpdateResult, type SnippetOptions, type StandardKeyList, type StandardPartnerLink, type StandardPartnerLinkCreate, type StorageType, type SubjectCard, type SubjectIdentity, type SubscriptionTopicInput, type SuggestedRejectStyle, type SupportedLanguage, type TaggedType, type Usage, type VendorInput, type VendorRecord, type VerifyResult, type VerifyWebhookInput, type WebhookCreate, type WebhookDeadLetter, type WebhookKeyForm, type WebhookReplayResult, type WebhookStage, type WebhookSubscription, type WebhookTestResult, type WebhookUpdate, canaryIdentityFor, createCookieMunch, mintConsentSyncToken, runExecutorConformance, verifyWebhookSignature };