@cookiemunch/sdk 0.5.1 → 0.7.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.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { CONSENT_COOKIE_NAME, ConsentCategory, ConsentSource, ReadConsentOptions, ServerConsent, getConsent, isAllowed, parseConsentValue, readConsent } from './consent.cjs';
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.cjs';
2
2
 
3
3
  /**
4
4
  * Request/response shapes for the Cookie Munch Developer API (/v1). These mirror the
@@ -26,6 +26,10 @@ interface Identity {
26
26
  propertyLocked?: boolean;
27
27
  cbids?: string[];
28
28
  reseller?: boolean;
29
+ /** This organisation is a sandbox (`sandbox.create()`): test keys, test rights requests, never billed. */
30
+ sandbox?: boolean;
31
+ /** For a sandbox: the live organisation it belongs to. */
32
+ sandboxOf?: string;
29
33
  }
30
34
  type PlanSource = 'org' | 'account';
31
35
  /** One organisation on an account (GET /v1/orgs, and the `org_limit` refusal). */
@@ -93,25 +97,72 @@ interface SiteUpdateResult {
93
97
  }
94
98
  /** One row of GET /v1/integration-health. `ok: null` = the check could not run (see `detail`). */
95
99
  interface HealthRow {
100
+ /** The suite shape's name for `check` (always equal). */
101
+ id: string;
96
102
  check: string;
103
+ /** The generic check this row is an instance of (`forumulate.webhook` → `webhook.delivery`); otherwise `check`. */
104
+ kind: string;
105
+ /** The vendor a vendor-specific instance is about. */
106
+ vendor?: string;
97
107
  ok: boolean | null;
98
108
  severity: 'error' | 'warning' | 'info';
99
109
  subject: string;
100
110
  fixHint?: string;
111
+ /** The same as fixHint (suite shape). */
112
+ fix?: string;
113
+ /** Where the check and its fix are explained. */
114
+ docs: string;
101
115
  detail?: string;
116
+ /** Network checks: the hop that failed (or, on success, the last one reached). */
117
+ hop?: 'dns' | 'tls' | 'http' | 'challenge' | 'auth';
118
+ status?: number;
119
+ elapsedMs?: number;
120
+ /** Failed network checks: a stable code (ENOTFOUND, timeout, challenge, http_503, …). */
121
+ error?: string;
122
+ /** A waiver covers this failing row; `ok` is then null. */
123
+ waived?: {
124
+ reason: string;
125
+ by: string;
126
+ until: number | null;
127
+ };
102
128
  lastCheckedAt: number;
103
129
  }
104
130
  interface IntegrationHealthReport {
105
131
  cbid: string;
106
132
  checkedAt: number;
133
+ generatedAt: string;
107
134
  ok: boolean;
108
135
  counts: {
109
136
  error: number;
110
137
  warning: number;
111
138
  notChecked: number;
139
+ waived: number;
112
140
  };
113
141
  checks: HealthRow[];
114
142
  }
143
+ /** PUT /v1/integration-health/waivers. */
144
+ interface HealthWaiverInput {
145
+ /** Optional when the organisation has one site. */
146
+ cbid?: string;
147
+ /** A row's `check` or `kind`. */
148
+ check: string;
149
+ /** A row's `subject`; omitted: every subject of the check (`*`). */
150
+ subject?: string;
151
+ /** Why this is deliberate (1–500 characters). */
152
+ reason: string;
153
+ /** ISO date or epoch ms, future, within a year; omitted or null: never expires. */
154
+ until?: string | number | null;
155
+ }
156
+ interface HealthWaiver {
157
+ cbid: string;
158
+ check: string;
159
+ subject: string;
160
+ reason: string;
161
+ by: string;
162
+ until: number | null;
163
+ createdAt: number;
164
+ expired?: boolean;
165
+ }
115
166
  /** POST /v1/provision. Secrets are used for the request only and never returned. */
116
167
  interface ProvisionRequest {
117
168
  product: string;
@@ -120,10 +171,12 @@ interface ProvisionRequest {
120
171
  aliases?: string[];
121
172
  cbid?: string;
122
173
  /** `frontendApiHost` (e.g. auth.example.com) lets provision declare Atlas's sign-in cookies on the site. */
174
+ /** `rightsIdentity` (default true) makes Atlas the site's rights sign-in (step `rights.identity`). */
123
175
  atlas?: {
124
176
  secretKey: string;
125
177
  cookieConsent?: boolean;
126
178
  dsrWebhook?: boolean;
179
+ rightsIdentity?: boolean;
127
180
  frontendApiHost?: string;
128
181
  };
129
182
  forumulate?: {
@@ -140,15 +193,21 @@ interface ProvisionRequest {
140
193
  };
141
194
  }
142
195
  interface ProvisionStep {
196
+ /** v2 answers: the stable step id (`fromStep` takes it). */
197
+ id?: string;
143
198
  step: string;
144
- status: 'created' | 'updated' | 'unchanged' | 'would_create' | 'would_update' | 'skipped' | 'waiting' | 'failed' | 'passed';
199
+ status: 'created' | 'updated' | 'unchanged' | 'would_create' | 'would_update' | 'skipped' | 'waiting' | 'waiting_on' | 'failed' | 'passed';
145
200
  detail?: string;
146
201
  diff?: Array<{
147
202
  field: string;
148
203
  before: unknown;
149
204
  after: unknown;
150
205
  }>;
151
- waitingOn?: string;
206
+ /** A string in v1 answers; `{ platform, items }` in v2 answers. */
207
+ waitingOn?: string | {
208
+ platform: string;
209
+ items: string[];
210
+ };
152
211
  }
153
212
  interface ProvisionResult {
154
213
  dryRun: boolean;
@@ -161,8 +220,19 @@ interface ProvisionResult {
161
220
  waiting: number;
162
221
  failed: number;
163
222
  };
223
+ /** v2 answers only. */
224
+ version?: 2;
225
+ ids?: {
226
+ orgId: string;
227
+ cbid: string | null;
228
+ executors: Record<string, string>;
229
+ webhooks: string[];
230
+ };
231
+ sealedSecrets?: Array<Record<string, unknown>>;
232
+ checklist?: string[];
164
233
  }
165
- type PartnerId = 'forumulate' | 'atlas';
234
+ /** A partner the deployment knows: built in (forumulate, atlas, chatly, referalli) or any other registered on it. */
235
+ type PartnerId = 'forumulate' | 'atlas' | 'chatly' | 'referalli' | (string & {});
166
236
  interface PartnerLinkCreate {
167
237
  partner: PartnerId;
168
238
  /** The partner's id for the receiving account (a Forumulate organisation id, an Atlas instance id). */
@@ -235,9 +305,11 @@ interface RangeQuery {
235
305
  interface LogQuery extends RangeQuery {
236
306
  limit?: number;
237
307
  }
238
- type DsarType = 'access' | 'deletion' | 'rectification' | 'portability' | 'opt-out';
308
+ type DsarType = 'access' | 'deletion' | 'rectification' | 'portability' | 'opt-out' | 'closure' | 'restriction';
309
+ /** A type word as sent: the canonical words, or an alias (`erasure`/`erase` → deletion, `export` → access). */
310
+ type DsarTypeWord = DsarType | 'erasure' | 'erase' | 'export';
239
311
  type Regulation = 'gdpr' | 'ccpa';
240
- type DsarStatus = 'received' | 'verifying' | 'in_progress' | 'completed' | 'rejected';
312
+ type DsarStatus = 'received' | 'verifying' | 'in_progress' | 'completed' | 'rejected' | 'cancelled';
241
313
  interface DsarRequest {
242
314
  id: string;
243
315
  type: DsarType;
@@ -254,6 +326,147 @@ interface DsarRequest {
254
326
  messageToSubject?: string;
255
327
  /** A test request: off the SLA board, labelled, and deletable with `dsar.delete`. A closed request can be marked one with `dsar.markTest`. */
256
328
  test?: boolean;
329
+ /** Its type in the suite vocabulary (`erasure` was stored as `deletion`). */
330
+ canonicalType?: string;
331
+ /** The case's X-ForgeDeck-Trace, when it has one. */
332
+ trace?: string;
333
+ }
334
+ /** A signed-in identity from any OIDC issuer the site trusts. `(iss, sub)` is the key. */
335
+ interface SubjectIdentity {
336
+ iss: string;
337
+ sub: string;
338
+ ext?: string;
339
+ principal?: string;
340
+ }
341
+ /** Who a case is about. `atlas` is accepted as an alias of `identity`. */
342
+ interface DsarSubject {
343
+ emails: string[];
344
+ identity?: SubjectIdentity;
345
+ atlas?: SubjectIdentity;
346
+ }
347
+ /** POST /v1/dsar/requests. */
348
+ interface DsarCaseCreate {
349
+ cbid: string;
350
+ type: DsarTypeWord;
351
+ subject?: DsarSubject;
352
+ /** The person's own token from the site's sign-in issuer (aud `cookiemunch:<cbid>`). */
353
+ subjectToken?: string;
354
+ /** product and atlas need dsar:write and attest the person; admin (default) files it received. */
355
+ source?: 'product' | 'atlas' | 'admin';
356
+ reason?: string;
357
+ /** Connections not to ask: system names, connection ids, or `self`. */
358
+ skipSystems?: string[];
359
+ /** Default true. */
360
+ fulfill?: boolean;
361
+ regulation?: 'gdpr' | 'ccpa' | 'lgpd' | 'pipeda' | 'vcdpa';
362
+ jurisdiction?: string;
363
+ test?: boolean;
364
+ }
365
+ type DsarCaseStatus = 'pending' | 'scheduled' | 'processing' | 'completed' | 'completed_with_retention' | 'rejected' | 'cancelled';
366
+ interface RetentionLine {
367
+ category: string;
368
+ basis: 'legal_obligation' | 'legal_claims' | 'contract' | 'public_interest';
369
+ until?: string;
370
+ }
371
+ interface DsarCaseTask {
372
+ system: string;
373
+ executorId: string | null;
374
+ taskId: string;
375
+ status: DsarCaseStatus | 'no_match';
376
+ requestId: string | null;
377
+ eta: string | null;
378
+ completedAt: string | null;
379
+ detail: string | null;
380
+ retention?: RetentionLine[];
381
+ }
382
+ /** A case across every connected system. */
383
+ interface DsarCase {
384
+ id: string;
385
+ type: DsarType;
386
+ canonicalType: string;
387
+ status: DsarCaseStatus;
388
+ requestStatus: DsarStatus;
389
+ cbid?: string;
390
+ source: 'product' | 'atlas' | 'rights_page' | 'admin' | null;
391
+ reason: string | null;
392
+ openedAt: string;
393
+ /** Nothing is erased anywhere before this. */
394
+ executeAfter: string | null;
395
+ graceDays: number | null;
396
+ closedAt: string | null;
397
+ /** False for a closure: no statutory clock. */
398
+ statutory: boolean;
399
+ dueAt: string | null;
400
+ verification: string | null;
401
+ trace: string | null;
402
+ subject: {
403
+ emails: string[];
404
+ identity: SubjectIdentity | null;
405
+ };
406
+ skipSystems: string[];
407
+ fulfill: boolean | null;
408
+ cancelRequestedAt: string | null;
409
+ test: boolean;
410
+ tasks: DsarCaseTask[];
411
+ receiptUrl: string;
412
+ /** Lets the person who asked read this case through POST /api/v1/public/dsar/status. */
413
+ statusToken?: string;
414
+ }
415
+ /** One signed receipt for a case (Ed25519; verify with GET /v1/partner/jwks.json). */
416
+ interface DsarCaseReceipt {
417
+ receiptVersion: number;
418
+ caseId: string;
419
+ type: DsarType;
420
+ canonicalType: string;
421
+ status: DsarCaseStatus;
422
+ openedAt: string;
423
+ executeAfter: string | null;
424
+ closedAt: string | null;
425
+ verification: string | null;
426
+ trace: string | null;
427
+ subject: {
428
+ emailHashes: string[];
429
+ identityHash?: string;
430
+ atlasSubHash?: string;
431
+ };
432
+ systems: Array<{
433
+ system: string;
434
+ executorId: string | null;
435
+ requestId: string | null;
436
+ status: string;
437
+ completedAt: string | null;
438
+ trace: string | null;
439
+ retention?: RetentionLine[];
440
+ }>;
441
+ issuedAt: string;
442
+ signature: {
443
+ alg: 'Ed25519';
444
+ kid: string;
445
+ value: string;
446
+ covers?: string;
447
+ };
448
+ }
449
+ /** A site's rights-request settings. */
450
+ interface DsarSettings {
451
+ cbid: string;
452
+ /** 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). */
453
+ graceDays: number;
454
+ /** site: set explicitly; default: a new site's 7 days; legacy: an existing site, 0 until set. */
455
+ source: 'site' | 'default' | 'legacy';
456
+ updatedAt: number | null;
457
+ }
458
+ /** GET /v1/integrations/{app}/card. */
459
+ interface SubjectCard {
460
+ app: string;
461
+ openCases: Array<{
462
+ id: string;
463
+ type: string;
464
+ status: string;
465
+ executeAfter: string | null;
466
+ openedAt: string;
467
+ receiptUrl: string;
468
+ }>;
469
+ consent: null;
257
470
  }
258
471
  /**
259
472
  * How a rights-page requester was verified — on every answer of the public intake
@@ -366,6 +579,24 @@ interface PreferenceRecord {
366
579
  updatedAt: number;
367
580
  version: number;
368
581
  }
582
+ /** GET /v1/categories/registry — the reserved category templates (CMU-X15). */
583
+ interface CategoryRegistry {
584
+ version: 1;
585
+ standard: string[];
586
+ suite: Array<{
587
+ id: 'support_chat' | 'referrals';
588
+ stance: 'necessary_on_request' | 'opt_in_eu_uk';
589
+ fallback: 'preferences' | 'marketing';
590
+ /** By banner language. */
591
+ labels: Record<string, string>;
592
+ descriptions: Record<string, string>;
593
+ basis?: string[];
594
+ vendors?: Array<{
595
+ product: string;
596
+ storage: string[];
597
+ }>;
598
+ }>;
599
+ }
369
600
 
370
601
  interface VerifyWebhookInput {
371
602
  /** The raw request body, exactly as received. Do NOT re-stringify parsed JSON. */
@@ -404,6 +635,195 @@ interface MintConsentSyncTokenInput {
404
635
  }
405
636
  declare function mintConsentSyncToken(input: MintConsentSyncTokenInput): string;
406
637
 
638
+ /**
639
+ * The cm-standard-v2 executor conformance kit (CMU-X20).
640
+ *
641
+ * cm-standard-v2 is an open contract: any system that holds personal data can implement it and
642
+ * be driven by Cookie Munch with no code on our side (docs: cookiemunch.net/docs/executor-contract-v2).
643
+ * This kit checks an implementation rule by rule, and names the rule that fails. It is the same
644
+ * suite Cookie Munch runs on `POST /v1/dsar/executors/{id}/test {conformance: true}`, and the
645
+ * `cookiemunch executors conformance <baseUrl>` command runs it from a terminal or CI.
646
+ *
647
+ * It only ever touches the CANARY subject — an address no real person has. The contract asks every
648
+ * implementation to treat the canary as an existing synthetic person: it is found by its email and
649
+ * by its identity, requests on it move through the full state machine, and nothing real is ever
650
+ * erased. So the kit can check that an erasure waits for `executeAfter`, that a cancel leaves the
651
+ * person in place, and that an identity is never matched to someone else through a shared email —
652
+ * without a real person's data being anywhere near it.
653
+ *
654
+ * No dependencies: `fetch` only, so it runs in Node 18+, a browser, or an edge runtime.
655
+ */
656
+ type ConformanceStatus = 'pass' | 'fail' | 'skip';
657
+ interface ConformanceRuleResult {
658
+ /** A stable id, e.g. `requests.execute_after.scheduled`. */
659
+ id: string;
660
+ /** What the rule says, in one sentence. */
661
+ title: string;
662
+ status: ConformanceStatus;
663
+ /** What was seen, when it failed or was skipped. */
664
+ detail?: string;
665
+ }
666
+ interface ConformanceReport {
667
+ /** True when no rule failed. */
668
+ ok: boolean;
669
+ passed: number;
670
+ failed: number;
671
+ skipped: number;
672
+ rules: ConformanceRuleResult[];
673
+ /** The `X-Version` the executor answered with, when it sent one. */
674
+ version?: string;
675
+ }
676
+ interface ConformanceOptions {
677
+ /** The executor's base: the contract paths are `{baseUrl}/privacy/lookup` and so on. https (http only for localhost). */
678
+ baseUrl: string;
679
+ /** The credential Cookie Munch would send. */
680
+ secret: string;
681
+ /**
682
+ * The canary address: `canary-<16 hex>@canary.cookiemunch.net`, per organisation
683
+ * (`GET /v1/dsar/executors/presets` → `canaryEmail`).
684
+ */
685
+ canaryEmail: string;
686
+ /** How the secret is sent. Default `Authorization: Bearer {secret}`. */
687
+ auth?: {
688
+ header: string;
689
+ format: string;
690
+ };
691
+ /** Path prefix under baseUrl. Default `/privacy`. */
692
+ prefix?: string;
693
+ fetch?: typeof fetch;
694
+ now?: () => number;
695
+ /** A per-run tag for idempotency keys and case ids. Default random. */
696
+ runId?: string;
697
+ }
698
+ /** The issuer the canary identity carries. */
699
+ declare const CANARY_ISSUER = "https://canary.cookiemunch.net";
700
+ /** The canary subject's identity, derived from its address. */
701
+ declare function canaryIdentityFor(canaryEmail: string): {
702
+ iss: string;
703
+ sub: string;
704
+ ext: string;
705
+ };
706
+ /** Every rule, in the order they run. */
707
+ declare const CONFORMANCE_RULES: ReadonlyArray<{
708
+ id: string;
709
+ title: string;
710
+ }>;
711
+ /** Run every rule against one executor. Never throws for an executor's answer; only for bad options. */
712
+ declare function runExecutorConformance(o: ConformanceOptions): Promise<ConformanceReport>;
713
+
714
+ /**
715
+ * Operator token exchange (RFC 8693, CMU-X33): swap your identity provider's token for a short-lived,
716
+ * scoped Cookie Munch API key, so no long-lived key has to live in a file.
717
+ *
718
+ * import { exchangeOperatorToken, createCookieMunch } from '@cookiemunch/sdk';
719
+ * const { accessToken } = await exchangeOperatorToken({
720
+ * subjectToken: process.env.STAFF_ACCESS_TOKEN!, // from the sign-in your organisation trusts
721
+ * scope: ['sites:read', 'dsar:read'],
722
+ * resource: 'org:2f1c…', // or 'site:<cbid>' to lock the key to one site
723
+ * });
724
+ * const client = createCookieMunch({ apiKey: accessToken, baseUrl: 'https://api.cookiemunch.net' });
725
+ *
726
+ * No API key is needed for the exchange itself. The key it returns expires on its own (at most an hour).
727
+ */
728
+ interface OperatorTokenExchangeInput {
729
+ /** The access or ID token from an OIDC issuer the deployment trusts. */
730
+ subjectToken: string;
731
+ /** Which kind of token `subjectToken` is. Default `access_token`. */
732
+ subjectTokenType?: 'access_token' | 'jwt' | 'id_token';
733
+ /** The API scopes the key should carry. Required: an exchanged key is never full access. */
734
+ scope: string[];
735
+ /** `org:<id>`, or `site:<cbid>` to lock the key to one site. */
736
+ resource: `org:${string}` | `site:${string}`;
737
+ /** Seconds, 60 to 3600. Default 3600. */
738
+ expiresIn?: number;
739
+ /** Default `https://api.cookiemunch.net`. */
740
+ baseUrl?: string;
741
+ fetch?: typeof fetch;
742
+ }
743
+ interface OperatorTokenExchangeResult {
744
+ /** A scoped Cookie Munch API key. */
745
+ accessToken: string;
746
+ expiresIn: number;
747
+ scope: string[];
748
+ }
749
+ /** Thrown with the RFC 6749 `error` and `error_description` the server answered. */
750
+ declare class TokenExchangeError extends Error {
751
+ readonly error: string;
752
+ readonly status: number;
753
+ constructor(error: string, status: number, description?: string);
754
+ }
755
+ declare function exchangeOperatorToken(input: OperatorTokenExchangeInput): Promise<OperatorTokenExchangeResult>;
756
+
757
+ /**
758
+ * Types for `window.__fdConsent`, the shared consent API any embed can code against — a chat
759
+ * widget, a referral snippet, an analytics tag — whatever CMP the page runs. Cookie Munch sets
760
+ * it natively; `fd-consent-shim.js` sets the same object over Cookiebot, OneTrust or no CMP.
761
+ * Type-only: importing this module adds nothing to a bundle.
762
+ *
763
+ * import type { FdConsent, FdConsentQueue } from '@cookiemunch/sdk';
764
+ * const fd = (window.__fdConsent ??= { q: [] });
765
+ * if ('version' in fd) fd.on('change', (s) => …); else fd.q.push(['on', 'change', (s) => …]);
766
+ *
767
+ * `version` changes only with a breaking change; new members do not bump it.
768
+ */
769
+ /** What caused a change. The same causes Cookie Munch's ledger records. */
770
+ type FdCause = 'replay' | 'accept' | 'decline' | 'selection' | 'withdraw' | 'implied' | 'sync' | 'request' | 'migrated';
771
+ interface FdSnapshot {
772
+ /** False until the visitor has answered. */
773
+ decided: boolean;
774
+ /** False when this visitor's region and the site's rules need no answer (a default applies). */
775
+ required: boolean;
776
+ /** Every category the site offers (standard, custom, reserved) and its answer. */
777
+ categories: Record<string, boolean>;
778
+ /** The decision's stamp (`CookieMunch.consentId()`), or null. */
779
+ stamp: string | null;
780
+ region: string;
781
+ /** A Global Privacy Control signal was seen. */
782
+ gpc: boolean;
783
+ /** ISO 8601, or null before a decision. */
784
+ decidedAt: string | null;
785
+ }
786
+ interface FdRequestOptions {
787
+ /** One sentence in the page's language: what will be stored and why. Shown as the prompt's text. */
788
+ reason: string;
789
+ /** Who is asking: your vendor id. Recorded with the answer. */
790
+ vendor: string;
791
+ }
792
+ interface FdConsent {
793
+ readonly version: 1;
794
+ /** `cookiemunch`, or `shim:cookiebot` / `shim:onetrust` / `shim:none`. */
795
+ readonly provider: string;
796
+ /** Resolves once a decision exists, or at once where the region needs none. */
797
+ ready(): Promise<FdSnapshot>;
798
+ /** true / false, or null while a required decision is pending. Never false for "not decided". */
799
+ has(category: string): boolean | null;
800
+ /** Fires once per decision (a returning visitor's as `replay`); a withdrawal synchronously. Returns unsubscribe. */
801
+ on(event: 'change', cb: (snapshot: FdSnapshot, cause: FdCause) => void): () => void;
802
+ /** Ask for one category at the moment you need it. Never re-asks a refusal; one prompt per category per page view. */
803
+ request(category: string, opts: FdRequestOptions): Promise<boolean>;
804
+ /** Not available yet: warns once and does nothing. */
805
+ identify(token: string): void;
806
+ layout: {
807
+ bottomInset(): number;
808
+ on(cb: (insetPx: number) => void): () => void;
809
+ };
810
+ /** Calls made on the queue before this existed ran in order; later pushes run at once. */
811
+ q: {
812
+ push(...calls: FdQueuedCall[]): number;
813
+ };
814
+ }
815
+ /** A call queued before the real object exists. */
816
+ type FdQueuedCall = ['on', 'change', (snapshot: FdSnapshot, cause: FdCause) => void] | ['ready', (snapshot: FdSnapshot) => void] | ['request', string, FdRequestOptions, (granted: boolean) => void] | ['identify', string];
817
+ /** What an embed that loads first creates: `window.__fdConsent = window.__fdConsent || { q: [] }`. */
818
+ interface FdConsentQueue {
819
+ q: FdQueuedCall[];
820
+ }
821
+ declare global {
822
+ interface Window {
823
+ __fdConsent?: FdConsent | FdConsentQueue;
824
+ }
825
+ }
826
+
407
827
  /**
408
828
  * @cookiemunch/sdk — a small, typed REST client for the Cookie Munch Developer API
409
829
  * (the /v1 surface). Construct it with an API key; the org is derived server-side
@@ -418,7 +838,7 @@ declare function mintConsentSyncToken(input: MintConsentSyncTokenInput): string;
418
838
  * This package's version, sent in the default User-Agent. Cloudflare answers a request with
419
839
  * no recognisable User-Agent with `403 error code: 1010`; a test pins this to package.json.
420
840
  */
421
- declare const SDK_VERSION = "0.5.1";
841
+ declare const SDK_VERSION = "0.7.0";
422
842
  interface CookieMunchOptions {
423
843
  apiKey: string;
424
844
  /** "https://api.cookiemunch.net" — the /v1 prefix is appended automatically. */
@@ -432,7 +852,188 @@ interface CookieMunchOptions {
432
852
  strictUnknownFields?: boolean;
433
853
  /** The `User-Agent` sent on every request. Default `cookiemunch-js/<version>`. */
434
854
  userAgent?: string;
855
+ /**
856
+ * Serve every request under this dated API version (`CookieMunch-Version`, e.g. `'2026-10-24'`) instead of the
857
+ * one your key is pinned to. `versions()` lists them; `keys.updateSelf({ apiVersion })` re-pins the key.
858
+ */
859
+ apiVersion?: string;
860
+ /**
861
+ * Seal every once-shown secret to this X25519 public key (`x25519:<base64>`): answers carry `sealed_secret`
862
+ * (a libsodium sealed box) and `sealed_field` instead of the plaintext. Sent as `X-Secret-Recipient` on writes.
863
+ */
864
+ secretRecipient?: string;
865
+ /**
866
+ * Extra headers on every request, e.g. `{ 'Idempotency-Key': '<forgedeck ref>:<run>' }` on a client made for
867
+ * one create: a retry with the same key replays the first answer (secrets included) for 24 hours.
868
+ */
869
+ headers?: Record<string, string>;
870
+ }
871
+ /** Tags on a created resource (CMU-X29). `forgedeck_sandbox: true` can only be set at creation. */
872
+ type ResourceMetadata = Record<string, string | number | boolean>;
873
+ /** Keep only resources whose tags match, e.g. `{ forgedeck_product: 'referalli' }`. */
874
+ interface MetadataFilter {
875
+ metadata?: Record<string, string>;
876
+ }
877
+ /** externalRef and metadata, accepted by every create (orgs, sites, webhooks, executors, DSARs, partner links). */
878
+ interface ResourceTagsInput {
879
+ /** Your own name for it, unique per org and type: a repeat create with the same body returns the existing one. */
880
+ externalRef?: string;
881
+ metadata?: ResourceMetadata;
882
+ }
883
+ type TaggedType = 'org' | 'site' | 'webhook' | 'executor' | 'dsar' | 'partner_link';
884
+ interface ResourceTags {
885
+ type: TaggedType;
886
+ id: string;
887
+ metadata: ResourceMetadata;
888
+ externalRef: string | null;
889
+ sandbox: boolean;
890
+ }
891
+ interface ResourceTagsUpdate {
892
+ dryRun?: true;
893
+ type: TaggedType;
894
+ id: string;
895
+ metadata: ResourceMetadata;
896
+ diff: Array<{
897
+ field: string;
898
+ before: unknown;
899
+ after: unknown;
900
+ }>;
901
+ }
902
+ /** What a sandbox hard delete removed. */
903
+ interface SandboxPurge {
904
+ deleted: true;
905
+ cbid?: string;
906
+ orgId?: string;
907
+ counts: Record<string, number>;
908
+ }
909
+ /** A partner link in the suite-standard shape (CMU-X34). */
910
+ interface StandardPartnerLink {
911
+ id: string;
912
+ partner: string;
913
+ resource: string;
914
+ scopes: string[];
915
+ created_at: string | null;
916
+ expires_at: string | null;
917
+ last_used_at: string | null;
918
+ calls_30d: number;
919
+ status: 'active' | 'waiting_on_partner' | 'revoked' | 'expired';
920
+ externalId?: string;
921
+ label?: string;
922
+ }
923
+ interface StandardPartnerLinkCreate extends ResourceTagsInput {
924
+ partner: string;
925
+ /** `site:<cbid>` or `org:<org id>`. */
926
+ resource: string;
927
+ scopes: Array<'consent:read' | 'receipt:read' | 'dsar:read' | 'dsar:write' | 'dsar:rights-links' | 'sites:read'>;
928
+ expires_at?: string;
929
+ externalId?: string;
930
+ label?: string;
931
+ }
932
+ /** POST /v1/provision v2: the `cookiemunch` block of a forgedeck.yaml (see the forgedeck API map page). */
933
+ interface ProvisionRequestV2 {
934
+ forgedeck: {
935
+ ref?: string;
936
+ product: string;
937
+ env?: string;
938
+ sandbox?: boolean;
939
+ };
940
+ site: {
941
+ domain: string;
942
+ name?: string;
943
+ aliases?: string[];
944
+ locales?: string[];
945
+ preset?: string;
946
+ devOrigins?: string[];
947
+ };
948
+ cbid?: string;
949
+ categories?: string[];
950
+ rightsIdentity?: Record<string, unknown>;
951
+ dsar?: {
952
+ graceDays?: number;
953
+ };
954
+ atlas?: {
955
+ instanceId?: string;
956
+ secretKey?: string;
957
+ cookieConsent?: boolean;
958
+ executor?: boolean;
959
+ frontendApiHost?: string;
960
+ };
961
+ forumulate?: {
962
+ org?: string;
963
+ orgId?: string;
964
+ token?: string;
965
+ consent?: boolean;
966
+ executor?: boolean;
967
+ label?: string;
968
+ };
969
+ chatly?: {
970
+ workspace?: string;
971
+ publicId?: string;
972
+ vendorHook?: boolean;
973
+ executor?: boolean;
974
+ };
975
+ self?: {
976
+ baseUrl: string;
977
+ contract?: string;
978
+ secret: string;
979
+ };
980
+ referalli?: {
981
+ orgId?: string;
982
+ trackingToken?: string;
983
+ preset?: boolean;
984
+ partner?: boolean;
985
+ executor?: string | boolean;
986
+ };
987
+ embedManifests?: string | string[];
988
+ brand?: {
989
+ url?: string;
990
+ };
991
+ }
992
+ /** GET /v1/provision/env: names, non-secret values, and references for secrets. */
993
+ interface ProvisionEnv {
994
+ ref: string;
995
+ cbid: string;
996
+ env: Array<{
997
+ name: string;
998
+ value?: string;
999
+ secretRef?: string;
1000
+ }>;
435
1001
  }
1002
+ /** A vended short-lived key, shown once. */
1003
+ interface ApiKeyVended {
1004
+ key: string;
1005
+ prefix: string;
1006
+ expiresAt: number;
1007
+ scopes: string[];
1008
+ cbids: string[] | null;
1009
+ }
1010
+ /** The suite-standard key listing (GET /v1/keys?shape=standard). */
1011
+ interface StandardKeyList {
1012
+ keys: Array<{
1013
+ id: string;
1014
+ prefix: string;
1015
+ name: string | null;
1016
+ owner: string | null;
1017
+ kind: string | null;
1018
+ env: string | null;
1019
+ format: string | null;
1020
+ scopes: string[] | null;
1021
+ resources: string[] | null;
1022
+ created_at: string | null;
1023
+ expires_at: string | null;
1024
+ last_used_at: string | null;
1025
+ last_used_ip: string | null;
1026
+ status: 'active' | 'expired';
1027
+ }>;
1028
+ }
1029
+ /** A leaked secret to revoke (POST /v1/keys/revoke_leaked, no authentication needed). */
1030
+ type LeakReport = {
1031
+ key: string;
1032
+ source?: string;
1033
+ } | {
1034
+ keys: string[];
1035
+ source?: string;
1036
+ };
436
1037
  /**
437
1038
  * Thrown for any non-2xx response. `message` is the server's `error` field when present;
438
1039
  * `code` is populated from the server's `code` field whenever the error body carries one
@@ -553,15 +1154,88 @@ interface DeclaredCookie extends DeclaredCookieInput {
553
1154
  vendor?: string;
554
1155
  }
555
1156
  /** A platform whose cookies and storage a preset declares. */
556
- type CookiePresetVendor = 'atlas' | 'forumulate' | 'chatly' | 'cookiemunch' | 'referally';
1157
+ type CookiePresetVendor = 'atlas' | 'forumulate' | 'chatly' | 'cookiemunch' | 'referalli' | 'firstpromoter' | 'partnerstack' | 'tapfiliate' | 'impact'
1158
+ /** @deprecated the old name of `referalli`, accepted until 2027-10-23. */
1159
+ | 'referally';
557
1160
  /** Where a vendor's live manifest will come from, and whether it exists yet. */
558
1161
  interface CookiePresetManifest {
559
- status: 'builtin' | 'waiting_on_vendor';
1162
+ /** `live`/`stale`/`invalid`: the vendor's embed manifest feeds the preset; `waiting_on_vendor`: built-in rows. */
1163
+ status: 'builtin' | 'live' | 'stale' | 'invalid' | 'waiting_on_vendor';
560
1164
  waitingOn?: string;
561
1165
  item?: string;
562
1166
  contract?: string;
1167
+ /** Where the manifest is read from, or `upload`. */
1168
+ source?: string;
1169
+ /** The `updated` of the copy in effect. */
1170
+ updated?: string;
1171
+ fetchedAt?: number;
1172
+ /** Why the latest read was not accepted, by rule (1–6). */
1173
+ errors?: Array<{
1174
+ rule?: number;
1175
+ path?: string;
1176
+ code?: string;
1177
+ message: string;
1178
+ }>;
1179
+ warnings?: Array<{
1180
+ rule?: number;
1181
+ path?: string;
1182
+ code?: string;
1183
+ message: string;
1184
+ }>;
1185
+ }
1186
+ /** PUT /v1/sites/:cbid/cookies/presets/custom — any vendor's embed manifest, by URL or as a body. */
1187
+ type CustomPresetInput = ({
1188
+ url: string;
1189
+ manifest?: never;
1190
+ } | {
1191
+ manifest: EmbedManifest;
1192
+ url?: never;
1193
+ }) & {
1194
+ /** Values for the manifest's `{placeholders}`. */
1195
+ params?: Record<string, string>;
1196
+ };
1197
+ /** One suggestion in GET /v1/sites/:cbid/cookies/suggestions. */
1198
+ interface CookieSuggestion {
1199
+ name: string;
1200
+ storage: 'cookie' | 'localStorage' | 'sessionStorage' | 'indexedDB';
1201
+ foundOnPages: string[];
1202
+ /** `denied`: a crawl saw it before any consent; `granted`: after accepting all. */
1203
+ consentStates?: Array<'denied' | 'granted'>;
1204
+ suggestedPreset?: string;
1205
+ suggestedCategory: string;
1206
+ confidence: 'high' | 'medium' | 'low';
1207
+ purpose?: string;
1208
+ reason: string;
563
1209
  }
564
- /** Preset parameters: Atlas `frontendApiHost`/`crossSubdomainCookies`; Chatly `publicId`/`dragging`/`category`; Referally `cookieDomain`/`cookieDays`/`category`. */
1210
+ /** GET /v1/sites/:cbid/cookies/suggestions */
1211
+ interface CookieSuggestions {
1212
+ suggestions: CookieSuggestion[];
1213
+ vendors: Array<{
1214
+ vendor: string;
1215
+ display: string;
1216
+ preset: string | null;
1217
+ applied: boolean;
1218
+ needsParams: boolean;
1219
+ evidence: Array<{
1220
+ kind: 'script' | 'storage' | 'manifest';
1221
+ value: string;
1222
+ pages?: string[];
1223
+ }>;
1224
+ }>;
1225
+ }
1226
+ /** POST /v1/sites/:cbid/cookies/suggestions/declare */
1227
+ interface CookieSuggestionsDeclared {
1228
+ presetsApplied: string[];
1229
+ declaredCount: number;
1230
+ skipped?: Array<{
1231
+ name: string;
1232
+ reason: string;
1233
+ }>;
1234
+ dryRun?: true;
1235
+ declared?: DeclaredCookie[];
1236
+ diff?: DeclarationDiff;
1237
+ }
1238
+ /** 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
1239
  interface CookiePresetParams {
566
1240
  frontendApiHost?: string;
567
1241
  crossSubdomainCookies?: boolean;
@@ -570,10 +1244,77 @@ interface CookiePresetParams {
570
1244
  category?: string;
571
1245
  cookieDomain?: string;
572
1246
  cookieDays?: number;
1247
+ /** referalli: default true, also declare referally_ctx (the pre-rename copy aff.js still writes). */
1248
+ legacyName?: boolean;
1249
+ /** impact: your program id; declares IR_<campaignId> too. */
1250
+ campaignId?: string;
1251
+ }
1252
+ /** One browser key a surface writes, in an embed manifest. */
1253
+ interface EmbedManifestStorage {
1254
+ name: string;
1255
+ type: 'cookie' | 'localStorage' | 'sessionStorage' | 'indexedDB';
1256
+ category: string;
1257
+ /** `session`, `persistent` or a duration such as `365d`. */
1258
+ lifetime?: string;
1259
+ /** By language; `en` is always there. */
1260
+ purpose: Record<string, string>;
1261
+ domain?: string;
1262
+ sentTo?: string;
1263
+ }
1264
+ /** One embeddable surface in an embed manifest: its origins by CSP directive and its storage. */
1265
+ interface EmbedManifestSurface {
1266
+ /** Origins by CSP directive (`script-src`, `connect-src`, …). */
1267
+ csp?: Record<string, string[]>;
1268
+ /** Non-origin sources the surface needs (`'unsafe-inline'`, `data:`). */
1269
+ requires?: Record<string, string[]>;
1270
+ trustedTypes?: string[];
1271
+ consentCategory?: string;
1272
+ storage?: EmbedManifestStorage[];
1273
+ sri?: Record<string, string>;
1274
+ }
1275
+ /** The shared embed/origins manifest (https://cookiemunch.net/schemas/embed-v1.json). */
1276
+ interface EmbedManifest {
1277
+ schema: string;
1278
+ product: string;
1279
+ updated: string;
1280
+ openapi?: string;
1281
+ llms?: string;
1282
+ status?: string;
1283
+ changelog?: string;
1284
+ docs?: string;
1285
+ checkers?: {
1286
+ userAgent?: string;
1287
+ egress?: string[];
1288
+ agents?: Array<{
1289
+ role: string;
1290
+ userAgent?: string;
1291
+ userAgentContains?: string;
1292
+ description?: string;
1293
+ }>;
1294
+ };
1295
+ surfaces: Record<string, EmbedManifestSurface>;
1296
+ changes?: Array<{
1297
+ effective: string;
1298
+ surface: string;
1299
+ add?: Record<string, string[]>;
1300
+ remove?: Record<string, string[]>;
1301
+ note?: string;
1302
+ }>;
1303
+ /** The tenant variant only: the site and its hosts. */
1304
+ tenant?: {
1305
+ cbid: string;
1306
+ siteHosts: string[];
1307
+ rightsPage: string;
1308
+ preferenceCentre: string;
1309
+ };
573
1310
  }
574
1311
  /** One preset in GET /v1/sites/:cbid/cookies/presets. */
575
1312
  interface CookiePreset {
576
- vendor: CookiePresetVendor;
1313
+ /** A first-class preset, or a custom preset's product id. */
1314
+ vendor: CookiePresetVendor | (string & {});
1315
+ /** A custom preset (importCookieManifest). */
1316
+ custom?: boolean;
1317
+ url?: string;
577
1318
  params: Array<{
578
1319
  name: string;
579
1320
  type: string;
@@ -586,7 +1327,9 @@ interface CookiePreset {
586
1327
  }
587
1328
  /** What applying a preset declared. */
588
1329
  interface CookiePresetResult {
589
- vendor: CookiePresetVendor;
1330
+ vendor: CookiePresetVendor | (string & {});
1331
+ /** `manifest` when the rows came from the vendor's embed manifest. */
1332
+ source?: 'manifest';
590
1333
  cookies: DeclaredCookie[];
591
1334
  removed: string[];
592
1335
  skipped?: Array<{
@@ -594,6 +1337,16 @@ interface CookiePresetResult {
594
1337
  reason: string;
595
1338
  }>;
596
1339
  note?: string;
1340
+ /** Rows filed under a category this site has switched off (`cookies[<name>].category`). */
1341
+ warnings?: Array<{
1342
+ field: string;
1343
+ reason: string;
1344
+ }>;
1345
+ /** With `warnings`: a body for `sites.patchConfig` that fixes them; apply the preset again after. */
1346
+ suggestedConfigPatch?: Record<string, unknown>;
1347
+ /** True when called with the deprecated name `referally`. */
1348
+ deprecated?: true;
1349
+ deprecatedAlias?: string;
597
1350
  manifest: CookiePresetManifest;
598
1351
  dryRun?: true;
599
1352
  declared?: DeclaredCookie[];
@@ -656,8 +1409,8 @@ interface ScanStatus {
656
1409
  lastScannedAt: number | null;
657
1410
  /** What the last scan saw of the live banner's Accept all / Reject all. Absent until measured. */
658
1411
  buttonParity?: ButtonParityScan;
659
- /** Where the last scan is. Absent when the site was never scanned. */
660
- state?: 'queued' | 'scanning' | 'done' | 'failed';
1412
+ /** Where the last scan is: `idle` when the site was never scanned (older servers left it out). */
1413
+ state?: 'idle' | 'queued' | 'scanning' | 'done' | 'failed';
661
1414
  scanId?: string;
662
1415
  startedAt?: number;
663
1416
  finishedAt?: number;
@@ -785,7 +1538,7 @@ interface ParityControlSummary {
785
1538
  * A warning, never an error — the config is saved regardless. See /docs/fair-consent-buttons.
786
1539
  */
787
1540
  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';
1541
+ 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
1542
  severity: 'warning' | 'notice';
790
1543
  layer: 'banner' | 'preferences' | 'modal' | 'popup' | 'bar' | 'inline' | 'custom';
791
1544
  accept: ParityControlSummary | null;
@@ -807,6 +1560,8 @@ interface ButtonParityFinding {
807
1560
  language?: string;
808
1561
  url?: string;
809
1562
  };
1563
+ /** On a contrast finding: the WCAG success criterion (1.4.3 text, 1.4.11 non-text). */
1564
+ wcag?: '1.4.3' | '1.4.11';
810
1565
  }
811
1566
  /** Reject all style values that would match the Accept all on the same layer. */
812
1567
  interface SuggestedRejectStyle {
@@ -1072,6 +1827,51 @@ interface BrandSuggestion {
1072
1827
  interface BrandExtractionResult {
1073
1828
  suggestion: BrandSuggestion;
1074
1829
  }
1830
+ /** PUT /v1/sites/{cbid}/brand: `{url}` alone (fetched once, https only), or a DTCG brand.json document. */
1831
+ type BrandImportInput = {
1832
+ url: string;
1833
+ } | Record<string, unknown>;
1834
+ /** One brand.json role and what it became. */
1835
+ interface BrandMappingRow {
1836
+ role: string;
1837
+ /** The site-config path it sets, e.g. `banner.theme.highlight`. */
1838
+ target: string;
1839
+ value: string | number;
1840
+ /** The rights-page theme token the same value feeds. */
1841
+ rightsPage?: string;
1842
+ /** `site` when the site's own banner theme value wins over brand.json. */
1843
+ source: 'brand.json' | 'site';
1844
+ inForce?: string | number;
1845
+ /** Variants that override it for some visitors. */
1846
+ variants?: string[];
1847
+ }
1848
+ /** The read-back of a brand.json import. Precedence: brand.json < site banner theme < per-banner variant. */
1849
+ interface BrandReadBack {
1850
+ cbid: string;
1851
+ dryRun?: boolean;
1852
+ source: {
1853
+ type: 'url';
1854
+ url: string;
1855
+ } | {
1856
+ type: 'body';
1857
+ };
1858
+ importedAt: number;
1859
+ precedence: string;
1860
+ mapping: BrandMappingRow[];
1861
+ ignored: Array<{
1862
+ role: string;
1863
+ reason: string;
1864
+ }>;
1865
+ warnings: Array<{
1866
+ role: string;
1867
+ code: 'third_party_font_host';
1868
+ message: string;
1869
+ }>;
1870
+ configWarnings?: Array<{
1871
+ field: string;
1872
+ reason: string;
1873
+ }>;
1874
+ }
1075
1875
  /** A validation/lint issue on a v2 banner flow. */
1076
1876
  interface FlowIssue {
1077
1877
  code: string;
@@ -1146,6 +1946,63 @@ interface ApiKeyPrefix {
1146
1946
  cbids?: string[] | null;
1147
1947
  /** Epoch ms it last authenticated a request (recorded at most hourly); null = not since recording began. */
1148
1948
  lastUsedAt?: number | null;
1949
+ /** The address of that request. */
1950
+ lastUsedIp?: string | null;
1951
+ /** `user:<id>`, `service:<name>` or `apikey:<prefix>`. */
1952
+ owner?: string | null;
1953
+ kind?: 'org' | 'site' | null;
1954
+ env?: 'live' | 'test' | null;
1955
+ format?: 'cookiemunch' | 'legacy';
1956
+ strictUnknownFields?: boolean;
1957
+ /** The dated API version this key is pinned to. */
1958
+ apiVersion?: string;
1959
+ }
1960
+ /** A live organisation's sandbox (GET /v1/sandbox). */
1961
+ interface SandboxOrg {
1962
+ orgId: string;
1963
+ name: string;
1964
+ sandboxOf: string;
1965
+ createdAt: string;
1966
+ }
1967
+ /** POST /v1/sandbox: the sandbox and a test key for it, shown once. */
1968
+ interface SandboxCreated {
1969
+ sandbox: SandboxOrg;
1970
+ created: boolean;
1971
+ key: string;
1972
+ keyPrefix: string;
1973
+ keyExpiresAt: string;
1974
+ }
1975
+ /** GET /v1/versions. */
1976
+ interface ApiVersions {
1977
+ latest: string;
1978
+ base: string;
1979
+ /** With a key: the version it is pinned to. */
1980
+ yours?: string;
1981
+ versions: Array<{
1982
+ version: string;
1983
+ summary: string;
1984
+ changes: Array<{
1985
+ id: string;
1986
+ summary: string;
1987
+ docs: string;
1988
+ }>;
1989
+ }>;
1990
+ }
1991
+ /** A revoked key in the report: when, by whom, why; never the secret. */
1992
+ interface ApiKeyRevoked {
1993
+ prefix: string;
1994
+ name: string | null;
1995
+ owner: string | null;
1996
+ scopes: string[] | null;
1997
+ cbids: string[] | null;
1998
+ createdAt: number;
1999
+ expiresAt: number | null;
2000
+ lastUsedAt: number | null;
2001
+ lastUsedIp: string | null;
2002
+ revokedAt: number;
2003
+ revokedBy: string;
2004
+ reason: 'revoked' | 'rolled' | 'leaked';
2005
+ leakSource: string | null;
1149
2006
  }
1150
2007
  /** GET /v1/keys/report — key hygiene. */
1151
2008
  interface ApiKeyReport {
@@ -1163,11 +2020,21 @@ interface ApiKeyReport {
1163
2020
  }>;
1164
2021
  noExpiry: number;
1165
2022
  total: number;
2023
+ /** Revoked, rolled and leak-revoked keys, newest first. */
2024
+ revoked?: ApiKeyRevoked[];
1166
2025
  }
1167
- /** A newly issued key. `key` is returned ONCE and never again. Returned by keys.issue(). */
2026
+ /** A newly issued key. `key` is returned ONCE and never again (or, with `secretRecipient`, sealed). */
1168
2027
  interface ApiKeyIssued {
1169
2028
  key: string;
1170
2029
  prefix: string;
2030
+ expiresAt?: number | null;
2031
+ scopes?: string[] | null;
2032
+ cbids?: string[] | null;
2033
+ /** No expiry, or one over 365 days. */
2034
+ warnings?: string[];
2035
+ /** With `secretRecipient`: the key, sealed (and `key` absent). */
2036
+ sealed_secret?: string;
2037
+ sealed_field?: string;
1171
2038
  }
1172
2039
  /** @deprecated No endpoint returns this shape; use {@link ApiKeyPrefix} / {@link ApiKeyIssued}. */
1173
2040
  interface ApiKey {
@@ -1180,14 +2047,14 @@ interface ApiKey {
1180
2047
  secret?: string;
1181
2048
  }
1182
2049
  /**
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}.
2050
+ * Input for issuing a new API key (POST /v1/keys). Every field is honoured: `scopes`, `cbids`,
2051
+ * `expiresInDays` / `expiresAt`, `name`, `owner` and `strictUnknownFields`.
1189
2052
  */
1190
2053
  interface ApiKeyIssueInput {
2054
+ /** `user:<id>`, `service:<name>` or `apikey:<prefix>`. Default: the calling key. */
2055
+ owner?: string;
2056
+ /** Writes with the new key refuse unknown body fields unless they send `Prefer: lenient-unknown-fields`. */
2057
+ strictUnknownFields?: boolean;
1191
2058
  name?: string;
1192
2059
  /** Least privilege: grant only these scopes. Omit for a full-access key. */
1193
2060
  scopes?: string[];
@@ -1201,6 +2068,25 @@ interface ApiKeyIssueInput {
1201
2068
  /** Or when it expires: epoch ms or an ISO date-time (not with expiresInDays). Omit both: never. */
1202
2069
  expiresAt?: number | string;
1203
2070
  }
2071
+ /** One entitlement (suite-standard shape). A feature is `{key, enabled}`; a limit is `limits.<name>`. */
2072
+ interface Entitlement {
2073
+ key: string;
2074
+ enabled: boolean;
2075
+ /** Limits only. null = unlimited, 0 = not on this plan. */
2076
+ limit?: number | null;
2077
+ /** Limits the server meters, when metering is wired. */
2078
+ used?: number;
2079
+ source: 'plan';
2080
+ }
2081
+ /** GET /v1/entitlements: what the org may use, from its effective plan. */
2082
+ interface Entitlements {
2083
+ orgId: string;
2084
+ plan: string;
2085
+ planSource: 'org' | 'account';
2086
+ subscribedPlan: string;
2087
+ entitlements: Entitlement[];
2088
+ generatedAt: string;
2089
+ }
1204
2090
  /** Org usage/quota summary. Matches the server's Usage schema. */
1205
2091
  interface Usage {
1206
2092
  domains: number;
@@ -1217,6 +2103,86 @@ interface WebhookSubscription {
1217
2103
  cbid: string | null;
1218
2104
  active: boolean;
1219
2105
  createdAt: number;
2106
+ /** The endpoint lifecycle: `failing` from the first event that failed every retry, `disabled` after 72 hours. */
2107
+ state?: 'healthy' | 'failing' | 'disabled' | 'paused';
2108
+ failingSince?: number | null;
2109
+ disabledAt?: number | null;
2110
+ lastSuccessAt?: number | null;
2111
+ lastFailure?: {
2112
+ at: number;
2113
+ status: number | null;
2114
+ error: string | null;
2115
+ } | null;
2116
+ lastDeliveryAt?: number | null;
2117
+ lastStatus?: number | null;
2118
+ consecutiveFailures?: number;
2119
+ /** Who is emailed when it fails; null: the organisation's owners. */
2120
+ alertContacts?: string[] | null;
2121
+ /** On an update that re-enabled a disabled endpoint: how to send what it missed. */
2122
+ replay?: {
2123
+ since: number;
2124
+ path: string;
2125
+ };
2126
+ }
2127
+ /** POST /v1/webhooks/{id}/replay. */
2128
+ interface WebhookReplayResult {
2129
+ ok: boolean;
2130
+ replayed: number;
2131
+ failed: number;
2132
+ remaining: number;
2133
+ stoppedAt?: string;
2134
+ status?: number;
2135
+ error?: string;
2136
+ }
2137
+ /** The audit-log export (GET/PUT /v1/audit/sink). Never the secret. */
2138
+ interface AuditSink {
2139
+ type: 'webhook';
2140
+ url: string;
2141
+ secretSet: true;
2142
+ createdAt: number;
2143
+ updatedAt: number;
2144
+ lastDeliveryAt: number | null;
2145
+ lastStatus: number | null;
2146
+ lastError: string | null;
2147
+ }
2148
+ interface AuditSinkInput {
2149
+ type: 'webhook';
2150
+ url: string;
2151
+ /** 16–256 characters; omitted: one is generated and returned once. */
2152
+ secret?: string;
2153
+ }
2154
+ /** GET /v1/sites/{cbid}/consent/insights. */
2155
+ interface ConsentInsights {
2156
+ cbid: string;
2157
+ from: number;
2158
+ to: number;
2159
+ totals: {
2160
+ impressions: number | null;
2161
+ decisions: number;
2162
+ optIns: number;
2163
+ optOuts: number;
2164
+ optInRate: number | null;
2165
+ decisionRate: number | null;
2166
+ };
2167
+ byRegion: Array<{
2168
+ region: string;
2169
+ decisions: number;
2170
+ optIns: number;
2171
+ optInRate: number | null;
2172
+ }>;
2173
+ byVariant: Array<{
2174
+ variant: string;
2175
+ impressions: number;
2176
+ optIns: number;
2177
+ optInRate: number | null;
2178
+ }>;
2179
+ byVariantWindow: 'all_time';
2180
+ byLanguage: null;
2181
+ timeToDecision: null;
2182
+ notRecorded: {
2183
+ byLanguage: string;
2184
+ timeToDecision: string;
2185
+ };
1220
2186
  }
1221
2187
  /** One cookie read from another CMP's export. */
1222
2188
  interface ImportedCookie {
@@ -1495,6 +2461,8 @@ interface AuditEntry {
1495
2461
  }
1496
2462
  /** Rename a key, or replace its scopes or the properties it is locked to. */
1497
2463
  interface ApiKeyUpdate {
2464
+ owner?: string;
2465
+ strictUnknownFields?: boolean;
1498
2466
  name?: string;
1499
2467
  scopes?: string[];
1500
2468
  cbids?: string[];
@@ -1532,8 +2500,10 @@ interface WebhookUpdate {
1532
2500
  events?: string[];
1533
2501
  /** One property, or null for every property in the org. */
1534
2502
  cbid?: string | null;
1535
- /** false pauses delivery without deleting the subscription. */
2503
+ /** false pauses delivery without deleting the subscription; true re-enables a disabled one. */
1536
2504
  active?: boolean;
2505
+ /** 1–10 addresses emailed when it fails; null: back to the organisation's owners. */
2506
+ alertContacts?: string[] | null;
1537
2507
  }
1538
2508
  /** One site to create in a bulk call. */
1539
2509
  interface BulkSiteInput {
@@ -1900,14 +2870,53 @@ interface DsarExecutor {
1900
2870
  presetParams?: Record<string, string>;
1901
2871
  /** How the stored address and profile differ from what its preset version builds. Empty: unmodified. */
1902
2872
  presetDiff?: ConfigChange[];
2873
+ /** Preset-built: profile fields you removed or changed by hand; `upgradeExecutorPreset` keeps them. */
2874
+ profileOverrides?: Array<{
2875
+ path: string;
2876
+ kind: 'removed' | 'changed';
2877
+ at: number;
2878
+ }>;
2879
+ /** Preset-built: true when it must not follow its preset. */
2880
+ presetPinned?: boolean;
2881
+ /** Your name for the credential. */
2882
+ label?: string;
2883
+ /** 2: orchestrator v2 headers on every call; 1: the v1 adapter every connection made before v2 has. */
2884
+ orchestrator?: 1 | 2;
2885
+ hasCompletionSecret?: boolean;
2886
+ completionSecretPrefix?: string;
2887
+ /** When a signed completion last verified; running work is then polled every 6 hours. */
2888
+ lastSignedCompletionAt?: number | null;
2889
+ /** Where signed cm-standard-v2 completions go. */
2890
+ completionsUrl?: string;
2891
+ /** On create only: the completion secret, shown this once. */
2892
+ completionSecret?: string;
2893
+ }
2894
+ /** POST …/completion-secret/roll. */
2895
+ interface CompletionSecretRolled {
2896
+ id: string;
2897
+ completionSecret: string;
2898
+ completionSecretPrefix: string;
2899
+ previousRetiresAt: string | null;
2900
+ completionsUrl?: string;
2901
+ }
2902
+ /** POST …/test {conformance: true}: the conformance kit's report. */
2903
+ interface ExecutorConformanceResult extends ConformanceReport {
2904
+ conformance: true;
2905
+ canary: true;
2906
+ email: string;
1903
2907
  }
1904
- /** A connection's last canary health check. */
2908
+ /** A connection's last health check. */
1905
2909
  interface ExecutorHealth {
1906
2910
  lastCheckedAt: number;
1907
2911
  ok: boolean;
1908
2912
  verdict: string;
1909
2913
  /** e.g. `base_url_redirects`, `credential_unavailable`. */
1910
2914
  code?: string;
2915
+ /** When a check last passed. */
2916
+ lastSuccessAt?: number;
2917
+ /** On reads: true when the last check is more than an hour old, with the command that re-checks it in `hint`. */
2918
+ stale?: boolean;
2919
+ hint?: string;
1911
2920
  }
1912
2921
  /** A preset's name, as `executorPresets()` lists them. Not enumerated here: presets are data. */
1913
2922
  type ExecutorPresetName = string;
@@ -1924,9 +2933,15 @@ interface DsarExecutorPresetInput {
1924
2933
  baseUrl?: string;
1925
2934
  orgId?: string;
1926
2935
  atlasIdAppId?: string;
2936
+ /** A preset param, when the preset lists it: default false. True adds an optional step revoking the person's app grant on erasure. */
2937
+ revokeAtlasIdGrant?: boolean;
1927
2938
  webhookSecret?: string;
1928
2939
  auto?: boolean;
1929
2940
  cbid?: string;
2941
+ /** Your name for the credential, shown beside `keyPrefix`. */
2942
+ label?: string;
2943
+ /** Default 2. */
2944
+ orchestrator?: 1 | 2;
1930
2945
  }
1931
2946
  /** What `upgradeExecutorPreset` takes: a version, a preset to adopt, or params to add. */
1932
2947
  interface ExecutorPresetUpgrade {
@@ -1934,6 +2949,25 @@ interface ExecutorPresetUpgrade {
1934
2949
  presetVersion?: number;
1935
2950
  orgId?: string;
1936
2951
  atlasIdAppId?: string;
2952
+ revokeAtlasIdGrant?: boolean;
2953
+ /** Overridden paths (`profileOverrides`) that take the preset's value again; every other override is kept. */
2954
+ acceptPreset?: string | string[];
2955
+ }
2956
+ /** One step a preset builds, and whether it can run now (CMU-B01). */
2957
+ interface ExecutorPresetStep {
2958
+ name: 'subjectLookup' | 'open' | 'poll' | 'webhook' | 'grantRevoke';
2959
+ available: boolean;
2960
+ /** Never fails a connection: a credential without the scope reports `skipped: insufficient_scope`. */
2961
+ optional?: boolean;
2962
+ /** False: added only with `param`. */
2963
+ defaultOn: boolean;
2964
+ param?: string;
2965
+ note?: string;
2966
+ waitingOn?: {
2967
+ platform: string;
2968
+ items: string[];
2969
+ operations: string[];
2970
+ };
1937
2971
  }
1938
2972
  /** The presets, which are usable now, and this org's canary address. */
1939
2973
  interface ExecutorPresets {
@@ -1947,6 +2981,7 @@ interface ExecutorPresets {
1947
2981
  name: string;
1948
2982
  required: boolean;
1949
2983
  description: string;
2984
+ type?: 'string' | 'boolean';
1950
2985
  }>;
1951
2986
  available: boolean;
1952
2987
  waitingOn?: {
@@ -1954,6 +2989,7 @@ interface ExecutorPresets {
1954
2989
  items: string[];
1955
2990
  operations: string[];
1956
2991
  };
2992
+ steps: ExecutorPresetStep[];
1957
2993
  }>;
1958
2994
  }
1959
2995
  /** What a connection write would do (`?dryRun=1`). Nothing was stored. */
@@ -2015,6 +3051,8 @@ interface DsarExecutorInput {
2015
3051
  subjectNote?: string;
2016
3052
  /** How to drive it. */
2017
3053
  profile: ExecutorProfile;
3054
+ /** Default 2. */
3055
+ orchestrator?: 1 | 2;
2018
3056
  }
2019
3057
  type DsarExecutorCreated = DsarExecutor;
2020
3058
  /** The fields `updateExecutor` may change. */
@@ -2026,12 +3064,18 @@ interface DsarExecutorPatch {
2026
3064
  auto?: boolean;
2027
3065
  /** null removes it. */
2028
3066
  subjectNote?: string | null;
3067
+ /** Your name for the credential; null removes it. */
3068
+ label?: string | null;
3069
+ /** Preset-built only: true stops `upgradeExecutorPreset` changing it. */
3070
+ presetPinned?: boolean;
3071
+ /** Opt in to (2) or out of (1) orchestrator v2. */
3072
+ orchestrator?: 1 | 2;
2029
3073
  }
2030
3074
  /** One entry in a fulfilment task's status history. */
2031
3075
  interface DsarTaskEvent {
2032
3076
  at: number;
2033
3077
  kind: 'created' | 'changed' | 'version_changed';
2034
- status: 'pending' | 'running' | 'done' | 'failed';
3078
+ status: 'pending' | 'running' | 'done' | 'failed' | 'cancelled';
2035
3079
  detail?: string;
2036
3080
  outcome?: DsarTaskOutcome;
2037
3081
  scheduledFor?: number;
@@ -2070,7 +3114,7 @@ interface DsarTask {
2070
3114
  requestId: string;
2071
3115
  system: string;
2072
3116
  operation: FulfillmentOp;
2073
- status: 'pending' | 'running' | 'done' | 'failed';
3117
+ status: 'pending' | 'running' | 'done' | 'failed' | 'cancelled';
2074
3118
  detail?: string;
2075
3119
  outcome?: DsarTaskOutcome;
2076
3120
  attempts: number;
@@ -2111,6 +3155,11 @@ interface ExecutorTestResult {
2111
3155
  code?: string;
2112
3156
  /** The subject's app grant at an identity platform, when the profile has a grant step. Never revoked by a test. */
2113
3157
  grant?: string;
3158
+ /** Optional steps this credential may not run: reported, never a failure. */
3159
+ skipped?: Array<{
3160
+ step: string;
3161
+ reason: 'insufficient_scope';
3162
+ }>;
2114
3163
  /** Present when the test used the org canary address, with the address in `email`. */
2115
3164
  canary?: boolean;
2116
3165
  email?: string;
@@ -2159,7 +3208,7 @@ interface CookieMunchClient {
2159
3208
  * comes from, plus the per-account org cap and the upgrade URL. Needs an unscoped key that
2160
3209
  * is not locked to properties.
2161
3210
  */
2162
- list(): Promise<AccountOrgs>;
3211
+ list(opts?: MetadataFilter): Promise<AccountOrgs>;
2163
3212
  /**
2164
3213
  * Create a sibling organisation owned by the same account — for a separate business of
2165
3214
  * your own. Needs an unscoped key. Not reseller provisioning, which is for your customers.
@@ -2167,7 +3216,9 @@ interface CookieMunchClient {
2167
3216
  create(name: string, opts?: {
2168
3217
  mintKey?: boolean;
2169
3218
  keyScopes?: string[];
2170
- }): Promise<{
3219
+ keyExpiresInDays?: number;
3220
+ keyOwner?: string;
3221
+ } & ResourceTagsInput): Promise<{
2171
3222
  org: {
2172
3223
  id: string;
2173
3224
  name: string;
@@ -2176,10 +3227,28 @@ interface CookieMunchClient {
2176
3227
  apiKey?: string;
2177
3228
  keyError?: string;
2178
3229
  }>;
3230
+ /** Hard-delete a SANDBOX organisation of this account (created with metadata.forgedeck_sandbox). Anything else: 403 not_a_sandbox. */
3231
+ deleteSandbox(id: string): Promise<SandboxPurge>;
3232
+ };
3233
+ /** Tags on any created resource (CMU-X29). */
3234
+ metadata: {
3235
+ get(type: TaggedType, id: string): Promise<ResourceTags>;
3236
+ /** Merge tags (null removes one). `forgedeck_sandbox` cannot be set here. `{ dryRun: true }` answers with the diff. */
3237
+ update(type: TaggedType, id: string, metadata: Record<string, string | number | boolean | null>, opts?: {
3238
+ dryRun?: boolean;
3239
+ }): Promise<ResourceTagsUpdate>;
3240
+ };
3241
+ /** Partner links in the suite-standard shape (CMU-X34). */
3242
+ partnerLinks: {
3243
+ list(opts?: MetadataFilter): Promise<StandardPartnerLink[]>;
3244
+ create(input: StandardPartnerLinkCreate): Promise<StandardPartnerLink>;
3245
+ revoke(id: string): Promise<StandardPartnerLink>;
2179
3246
  };
3247
+ /** What `forgedeck env` writes for a product provisioned with this forgedeck ref: names, values, secret references. */
3248
+ provisionEnv(ref: string): Promise<ProvisionEnv>;
2180
3249
  sites: {
2181
- list(): Promise<Site[]>;
2182
- create(input: SiteCreate): Promise<Site>;
3250
+ list(opts?: MetadataFilter): Promise<Site[]>;
3251
+ create(input: SiteCreate & ResourceTagsInput): Promise<Site>;
2183
3252
  get(cbid: string): Promise<Site>;
2184
3253
  /**
2185
3254
  * Rename or move a site: domain, display name, aliases. The cbid and the consent ledger stay; a domain
@@ -2189,6 +3258,8 @@ interface CookieMunchClient {
2189
3258
  dryRun?: boolean;
2190
3259
  }): Promise<SiteUpdateResult>;
2191
3260
  delete(cbid: string): Promise<void>;
3261
+ /** Purge a SANDBOX site: its consent ledger, declarations and test rights requests too. Anything else: 403 not_a_sandbox. */
3262
+ deleteSandbox(cbid: string): Promise<SandboxPurge>;
2192
3263
  /** Partner platforms granted this site's consent events, and the partners on offer. */
2193
3264
  listPartners(cbid: string): Promise<{
2194
3265
  links: PartnerLink[];
@@ -2326,9 +3397,10 @@ interface CookieMunchClient {
2326
3397
  dryRun: true;
2327
3398
  retired: RetiredCookie[];
2328
3399
  }>;
2329
- /** Every declaration preset (atlas, forumulate, chatly, cookiemunch, referally): params, what it declared here, manifest status. */
3400
+ /** Every declaration preset (atlas, forumulate, chatly, cookiemunch, referalli, firstpromoter, partnerstack, tapfiliate, impact): params, what it declared here, manifest status. */
2330
3401
  cookiePresets(cbid: string): Promise<{
2331
3402
  presets: CookiePreset[];
3403
+ aliases?: Record<string, string>;
2332
3404
  }>;
2333
3405
  /**
2334
3406
  * Apply (or re-sync) a vendor preset: declares what that platform writes, marked
@@ -2337,11 +3409,28 @@ interface CookieMunchClient {
2337
3409
  applyCookiePreset(cbid: string, vendor: CookiePresetVendor, params?: CookiePresetParams, opts?: {
2338
3410
  dryRun?: boolean;
2339
3411
  }): Promise<CookiePresetResult>;
3412
+ /**
3413
+ * Declare ANY vendor's cookies and storage from its embed manifest (`url`, re-read hourly, or
3414
+ * the `manifest` itself). The vendor id is the manifest's `product`; remove it with
3415
+ * removeCookiePreset(cbid, product). `dryRun` stores nothing.
3416
+ */
3417
+ importCookieManifest(cbid: string, input: CustomPresetInput, opts?: {
3418
+ dryRun?: boolean;
3419
+ }): Promise<CookiePresetResult>;
3420
+ /** What to declare: detected vendors (script, storage, manifest) and one suggestion per undeclared row. */
3421
+ cookieSuggestions(cbid: string): Promise<CookieSuggestions>;
3422
+ /** Declare the suggestions: detected vendors' presets, then every other suggestion with a purpose. Try `dryRun` first. */
3423
+ declareCookieSuggestions(cbid: string, input?: {
3424
+ names?: string[];
3425
+ presets?: boolean;
3426
+ }, opts?: {
3427
+ dryRun?: boolean;
3428
+ }): Promise<CookieSuggestionsDeclared>;
2340
3429
  /** Remove every declaration a vendor preset made. */
2341
- removeCookiePreset(cbid: string, vendor: CookiePresetVendor, opts?: {
3430
+ removeCookiePreset(cbid: string, vendor: CookiePresetVendor | (string & {}), opts?: {
2342
3431
  dryRun?: boolean;
2343
3432
  }): Promise<{
2344
- vendor: CookiePresetVendor;
3433
+ vendor: string;
2345
3434
  removed: string[];
2346
3435
  dryRun?: true;
2347
3436
  declared?: DeclaredCookie[];
@@ -2400,6 +3489,12 @@ interface CookieMunchClient {
2400
3489
  results: BulkSiteResult[];
2401
3490
  }>;
2402
3491
  brand(cbid: string): Promise<BrandExtractionResult>;
3492
+ /** Read back the brand.json last imported: each role, its source (brand.json or site), ignored[] and warnings[]. 404 when none. */
3493
+ getBrand(cbid: string): Promise<BrandReadBack>;
3494
+ /** Import a brand.json (`{url}` or the document) into the banner theme and the rights page. `dryRun` saves nothing. */
3495
+ setBrand(cbid: string, input: BrandImportInput, opts?: {
3496
+ dryRun?: boolean;
3497
+ }): Promise<BrandReadBack>;
2403
3498
  /** Read a site's v2 banner flow (views, categories) plus any lint issues. */
2404
3499
  getFlow(cbid: string): Promise<SiteFlow>;
2405
3500
  /** Apply an ordered batch of structured edit ops; validated + persisted if lint-clean. */
@@ -2417,6 +3512,8 @@ interface CookieMunchClient {
2417
3512
  valid: boolean;
2418
3513
  }>;
2419
3514
  stats(cbid: string, query?: RangeQuery): Promise<ConsentDay[]>;
3515
+ /** Opt-in by region and A/B variant, and the decision rate. Language and time-to-decision are not recorded (null). */
3516
+ insights(cbid: string, query?: RangeQuery): Promise<ConsentInsights>;
2420
3517
  log(cbid: string, query?: LogQuery): Promise<ConsentLogRow[]>;
2421
3518
  export(cbid: string, query?: RangeQuery): Promise<string>;
2422
3519
  receipt(cbid: string, stamp: string): Promise<SignedReceipt>;
@@ -2435,6 +3532,12 @@ interface CookieMunchClient {
2435
3532
  * prefix and no auth is required by the server (the cbid must be a registered site); for
2436
3533
  * server-side / non-browser consent flows. Pass `subjectId` to correlate a subject cross-surface. */
2437
3534
  ingest(input: ConsentIngestInput): Promise<void>;
3535
+ /**
3536
+ * The reserved categories any site can switch on with `categories.suite` (`support_chat`,
3537
+ * `referrals`): stance, fallback, regulatory basis, wording in every banner language, and
3538
+ * known vendors. Public — `GET /v1/categories/registry` needs no key.
3539
+ */
3540
+ categoryRegistry(): Promise<CategoryRegistry>;
2438
3541
  };
2439
3542
  dsar: {
2440
3543
  list(): Promise<DsarRequest[]>;
@@ -2443,7 +3546,7 @@ interface CookieMunchClient {
2443
3546
  * wrapped as `{ request }`, so `create(...).request.id` is what you pass here.
2444
3547
  */
2445
3548
  get(id: string): Promise<DsarRequest>;
2446
- create(input: DsarCreate): Promise<{
3549
+ create(input: DsarCreate & ResourceTagsInput): Promise<{
2447
3550
  request: DsarRequest;
2448
3551
  }>;
2449
3552
  /** `opts.messageToSubject` replaces the line the subject reads in the notice — for a rejection, why. */
@@ -2478,6 +3581,24 @@ interface CookieMunchClient {
2478
3581
  request: DsarRequest;
2479
3582
  changed: boolean;
2480
3583
  }>;
3584
+ /** Requests carrying one X-ForgeDeck-Trace (`GET /v1/dsar?trace=`). */
3585
+ listByTrace(trace: string): Promise<DsarRequest[]>;
3586
+ /**
3587
+ * Open a case fanned out to every connected system (POST /v1/dsar/requests). `opts.idempotencyKey`
3588
+ * (16–128 chars) makes a retry answer the same case; `opts.trace` passes your X-ForgeDeck-Trace on.
3589
+ */
3590
+ openCase(input: DsarCaseCreate, opts?: {
3591
+ idempotencyKey?: string;
3592
+ trace?: string;
3593
+ }): Promise<DsarCase>;
3594
+ /** One case across every system. */
3595
+ getCase(id: string): Promise<DsarCase>;
3596
+ /** Cancel a case before executeAfter; status `cancelled` once every system confirmed. */
3597
+ cancelCase(id: string): Promise<DsarCase>;
3598
+ /** The signed receipt for a case. */
3599
+ caseReceipt(id: string): Promise<DsarCaseReceipt>;
3600
+ /** The signed receipt as a PDF. */
3601
+ caseReceiptPdf(id: string): Promise<ArrayBuffer>;
2481
3602
  };
2482
3603
  vendors: {
2483
3604
  list(): Promise<ScoredVendor[]>;
@@ -2716,12 +3837,14 @@ interface CookieMunchClient {
2716
3837
  * platform holding your users' accounts, for instance. The in-VPC agent covers the
2717
3838
  * systems we cannot reach; these are the ones we can.
2718
3839
  */
2719
- executors(): Promise<DsarExecutor[]>;
3840
+ executors(opts?: MetadataFilter): Promise<DsarExecutor[]>;
3841
+ /** One connection with its full profile, never the credentials. Read it before changing `profile`: `updateExecutor` replaces the whole profile. */
3842
+ executor(id: string): Promise<DsarExecutor>;
2720
3843
  /**
2721
3844
  * Connect one. The secret is stored encrypted and never returned; the response carries
2722
3845
  * the URL to point that system's webhook at.
2723
3846
  */
2724
- connectExecutor(input: DsarExecutorInput | DsarExecutorPresetInput): Promise<DsarExecutorCreated>;
3847
+ connectExecutor(input: (DsarExecutorInput | DsarExecutorPresetInput) & ResourceTagsInput): Promise<DsarExecutorCreated>;
2725
3848
  /**
2726
3849
  * Change a connection in place. Only what you send changes, and the stored credential
2727
3850
  * is kept unless you pass a new `secretKey` — so adding a field to a profile does not
@@ -2771,6 +3894,16 @@ interface CookieMunchClient {
2771
3894
  * the raw (redacted) upstream answers and what a real request would have sent.
2772
3895
  */
2773
3896
  testExecutor(id: string, input: ExecutorTestInput): Promise<ExecutorTestResult>;
3897
+ /** Re-check a connection now (a canary test that records its health); for a deploy pipeline. */
3898
+ recheckExecutor(id: string): Promise<ExecutorTestResult>;
3899
+ /** A connection's last health checks, newest first (`limit` 1 to 50, default 50). */
3900
+ executorHealthHistory(id: string, opts?: {
3901
+ limit?: number;
3902
+ }): Promise<ExecutorHealth[]>;
3903
+ /** Run the cm-standard-v2 conformance kit against a connection, on the canary subject only. */
3904
+ executorConformance(id: string): Promise<ExecutorConformanceResult>;
3905
+ /** A new completion secret, shown once; the old one keeps verifying for 24 hours. */
3906
+ rollExecutorCompletionSecret(id: string): Promise<CompletionSecretRolled>;
2774
3907
  };
2775
3908
  preferences: {
2776
3909
  list(): Promise<PreferenceItem[]>;
@@ -2831,16 +3964,75 @@ interface CookieMunchClient {
2831
3964
  unusedDays?: number;
2832
3965
  expiringDays?: number;
2833
3966
  }): Promise<ApiKeyReport>;
3967
+ /** The suite-standard listing (`?shape=standard`). */
3968
+ listStandard(): Promise<StandardKeyList>;
3969
+ /** The calling key itself, whatever its scopes: check its own expiry. */
3970
+ self(): Promise<ApiKeyPrefix>;
3971
+ /** Re-pin the calling key to another dated API version. Any key may, for itself. */
3972
+ updateSelf(input: {
3973
+ apiVersion: string;
3974
+ }): Promise<ApiKeyPrefix>;
3975
+ /** The calling key rotates itself; the old secret stops at once. Use a client with an Idempotency-Key header. */
3976
+ rollSelf(): Promise<ApiKeyIssued>;
3977
+ /** A short-lived key (ttlSeconds at most 43200) within this key's own scopes and properties. Needs keys:write or full access. */
3978
+ vend(input: {
3979
+ scopes: string[];
3980
+ ttlSeconds: number;
3981
+ cbids?: string[];
3982
+ name?: string;
3983
+ }): Promise<ApiKeyVended>;
3984
+ /** Revoke a leaked secret (works without a valid key; always answers { received }). */
3985
+ revokeLeaked(report: LeakReport): Promise<{
3986
+ received: number;
3987
+ }>;
2834
3988
  };
2835
3989
  usage(): Promise<Usage>;
3990
+ /** The dated API versions, what each changed, and the one this key is pinned to (`yours`). */
3991
+ versions(): Promise<ApiVersions>;
3992
+ /** What the org may use: every plan feature (`whiteLabel`, `tcf`, …) and limit, in the suite-standard shape. Any key may read it. */
3993
+ entitlements(): Promise<Entitlements>;
3994
+ /**
3995
+ * The organisation's sandbox: a separate test organisation with the same people and plan features, never billed.
3996
+ * Its keys are test-format keys and its rights requests are all tests. `create` and `delete` need an unscoped key or `orgs:create`.
3997
+ */
3998
+ sandbox: {
3999
+ /** The sandbox, or null. From a sandbox key, the sandbox itself. */
4000
+ get(): Promise<SandboxOrg | null>;
4001
+ /** Make the sandbox (or return the existing one, `created: false`) with a new test key for it. */
4002
+ create(input?: {
4003
+ keyName?: string;
4004
+ }): Promise<SandboxCreated>;
4005
+ /** Erase the sandbox entirely. Cannot be undone; the live organisation is not touched. */
4006
+ delete(): Promise<SandboxPurge>;
4007
+ };
2836
4008
  /** 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
4009
  integrationHealth(cbid?: string): Promise<IntegrationHealthReport>;
4010
+ /** Waive a health check you chose not to meet: the row reports `ok: null` with `waived`. Audited. */
4011
+ healthWaivers: {
4012
+ list(cbid?: string): Promise<{
4013
+ cbid: string;
4014
+ waivers: HealthWaiver[];
4015
+ }>;
4016
+ set(input: HealthWaiverInput): Promise<{
4017
+ waiver: HealthWaiver;
4018
+ }>;
4019
+ remove(check: string, opts?: {
4020
+ cbid?: string;
4021
+ subject?: string;
4022
+ }): Promise<void>;
4023
+ };
4024
+ /**
4025
+ * The site's embed manifest: the tenant variant of `/.well-known/forgedeck-embed.json` — every
4026
+ * origin by CSP directive and every browser key the embed writes for this site's config. Public.
4027
+ */
4028
+ embedManifest(cbid: string): Promise<EmbedManifest>;
2838
4029
  /**
2839
4030
  * Wire a product's privacy in one call: the site, connected systems, Atlas and Forumulate. Idempotent;
2840
4031
  * `{ dryRun: true }` writes nothing anywhere. No secret appears in the answer.
2841
4032
  */
2842
- provision(input: ProvisionRequest, opts?: {
4033
+ provision(input: ProvisionRequest | ProvisionRequestV2, opts?: {
2843
4034
  dryRun?: boolean;
4035
+ fromStep?: string;
2844
4036
  }): Promise<ProvisionResult>;
2845
4037
  /** The key's organisation. Requires an unscoped key that is not property-locked. */
2846
4038
  org: {
@@ -2889,9 +4081,23 @@ interface CookieMunchClient {
2889
4081
  };
2890
4082
  };
2891
4083
  /** The org's audit log, newest first. API actions appear as `apikey:<prefix>`. */
2892
- audit(limit?: number): Promise<{
4084
+ /** `{ actor: 'self' }` reads the calling key's own rows, the one form a scoped key may call. */
4085
+ audit(limit?: number, opts?: {
4086
+ actor?: string;
4087
+ }): Promise<{
2893
4088
  entries: AuditEntry[];
2894
4089
  }>;
4090
+ /** Stream the audit log to an HTTPS endpoint as CloudEvents 1.0. Unscoped keys. */
4091
+ auditSink: {
4092
+ get(): Promise<{
4093
+ sink: AuditSink;
4094
+ }>;
4095
+ set(input: AuditSinkInput): Promise<{
4096
+ sink: AuditSink;
4097
+ secret?: string;
4098
+ }>;
4099
+ remove(): Promise<void>;
4100
+ };
2895
4101
  assets: {
2896
4102
  /** Upload a banner image (≤ 1,000,000 bytes) and get its public URL. Requires sites:write. */
2897
4103
  upload(input: AssetUpload): Promise<{
@@ -2926,8 +4132,8 @@ interface CookieMunchClient {
2926
4132
  revokeKey(id: string, prefix: string): Promise<void>;
2927
4133
  };
2928
4134
  webhooks: {
2929
- list(): Promise<WebhookSubscription[]>;
2930
- create(input: WebhookCreate): Promise<WebhookSubscription>;
4135
+ list(opts?: MetadataFilter): Promise<WebhookSubscription[]>;
4136
+ create(input: WebhookCreate & ResourceTagsInput): Promise<WebhookSubscription>;
2931
4137
  /** Change or pause a subscription. `{ active: false }` pauses without deleting it. */
2932
4138
  update(id: string, patch: WebhookUpdate): Promise<WebhookSubscription>;
2933
4139
  delete(id: string): Promise<void>;
@@ -2943,6 +4149,10 @@ interface CookieMunchClient {
2943
4149
  }>;
2944
4150
  /** Deliver a dead letter again, to the subscription as it is now. */
2945
4151
  replayDeadLetter(id: string): Promise<unknown>;
4152
+ /** Send what a failing or disabled endpoint missed since `since` (epoch ms or ISO), oldest first, stopping at the first failure. */
4153
+ replay(id: string, since: number | string, opts?: {
4154
+ limit?: number;
4155
+ }): Promise<WebhookReplayResult>;
2946
4156
  };
2947
4157
  /**
2948
4158
  * Account-linked rights requests: a single-use link to the hosted rights page for a person your
@@ -2984,6 +4194,23 @@ interface CookieMunchClient {
2984
4194
  /** Remove the site's own setting: it inherits the organisation default again. */
2985
4195
  remove(cbid: string): Promise<RightsIdentity>;
2986
4196
  };
4197
+ /** 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. */
4198
+ dsarSettings: {
4199
+ get(cbid: string): Promise<DsarSettings>;
4200
+ set(cbid: string, input: {
4201
+ graceDays: number;
4202
+ }): Promise<DsarSettings>;
4203
+ };
4204
+ /** Cards for support, CRM and helpdesk sidebars. Requires dsar:read. */
4205
+ integrations: {
4206
+ /** Open rights requests for one person, by identity (preferred) or email. */
4207
+ subjectCard(app: string, person: {
4208
+ iss: string;
4209
+ sub: string;
4210
+ } | {
4211
+ email: string;
4212
+ }): Promise<SubjectCard>;
4213
+ };
2987
4214
  /** One person's consent across every site in the org, by the subjectId your apps attach. */
2988
4215
  subjects: {
2989
4216
  /** Requires consent:read; not available to property-locked keys. */
@@ -3019,4 +4246,4 @@ interface CookieMunchClient {
3019
4246
  }
3020
4247
  declare function createCookieMunch(opts: CookieMunchOptions): CookieMunchClient;
3021
4248
 
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 };
4249
+ 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 ApiVersions, 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 OperatorTokenExchangeInput, type OperatorTokenExchangeResult, 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 SandboxCreated, type SandboxOrg, 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, TokenExchangeError, 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, exchangeOperatorToken, mintConsentSyncToken, runExecutorConformance, verifyWebhookSignature };