@dpdpguard/react-native 1.3.0 → 2.1.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/DpdpGuardReactNative.podspec +35 -0
- package/README.md +128 -24
- package/android/build.gradle +45 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/ai/dpdpguard/offline/DpdpGuardOfflineModule.kt +317 -0
- package/android/src/main/java/ai/dpdpguard/offline/DpdpGuardOfflinePackage.kt +33 -0
- package/ios/DpdpGuardOffline.h +18 -0
- package/ios/DpdpGuardOffline.mm +481 -0
- package/ios/DpdpGuardOfflineCrypto.swift +27 -0
- package/package.json +23 -4
- package/src/CONTRACT_VERSION +1 -1
- package/src/NativeDpdpGuardOffline.ts +64 -0
- package/src/generated/api-types.ts +1005 -224
- package/src/index.ts +33 -0
- package/src/offline/OfflineCaptureManager.ts +249 -0
- package/src/offline/captureArtifact.ts +184 -0
- package/src/offline/types.ts +134 -0
|
@@ -15,8 +15,7 @@ export interface paths {
|
|
|
15
15
|
put?: never;
|
|
16
16
|
/**
|
|
17
17
|
* Record a new consent on behalf of a known data principal.
|
|
18
|
-
* @description
|
|
19
|
-
* behaves as if it doesn't exist (404). Blocks tracking/marketing/
|
|
18
|
+
* @description Blocks tracking/marketing/
|
|
20
19
|
* targeting purposes for verified minors when the organization has
|
|
21
20
|
* `disableTrackingForMinors` set (403).
|
|
22
21
|
*/
|
|
@@ -55,10 +54,7 @@ export interface paths {
|
|
|
55
54
|
path?: never;
|
|
56
55
|
cookie?: never;
|
|
57
56
|
};
|
|
58
|
-
/**
|
|
59
|
-
* Resolve an organization by slug (public).
|
|
60
|
-
* @description Requires the `dpdp_mobile_api_enabled` flag; while it is off, this route behaves as if it doesn't exist (404).
|
|
61
|
-
*/
|
|
57
|
+
/** Resolve an organization by slug (public). */
|
|
62
58
|
get: operations["getOrgBySlug"];
|
|
63
59
|
put?: never;
|
|
64
60
|
post?: never;
|
|
@@ -131,7 +127,7 @@ export interface paths {
|
|
|
131
127
|
};
|
|
132
128
|
/**
|
|
133
129
|
* Resolve org, notice, and banner styling for the no-React embeddable widget script in one round trip (public).
|
|
134
|
-
* @description
|
|
130
|
+
* @description Powers the no-React embeddable widget script's single config call: given the domain-group id its script tag was generated with (`?id=`) and the embedding page's hostname (`?domain=`), resolves the organization, the notice that applies to that domain group (its own if published, else the org's default), and the domain group's banner styling. Strict domain check: a `domainGroupId` whose organization has no matching registered `domains` row for the given hostname resolves to 404, mirroring the same trust boundary as fetching a published notice.
|
|
135
131
|
*/
|
|
136
132
|
get: operations["getWidgetConfig"];
|
|
137
133
|
put?: never;
|
|
@@ -173,7 +169,7 @@ export interface paths {
|
|
|
173
169
|
put?: never;
|
|
174
170
|
/**
|
|
175
171
|
* Government CM API Bridge — receive an inbound consent signal from a registered third-party Consent Manager.
|
|
176
|
-
* @description
|
|
172
|
+
* @description Authenticated with the same org-scoped API key as `/cm/v1/consent` (never a brokered principal token) — the reverse direction of that flow: here a third-party Consent Manager pushes a signal on behalf of one of its Data Principals, rather than the fiduciary recording its own consent. MeitY's registered-CM interoperability spec isn't published yet, so every signal lands `mappingStatus: "unresolved"` unless it exactly repeats a signal already recorded, in which case it lands `"duplicate"` — CM webhooks are expected to retry, so a repeat delivery still returns 201 rather than erroring.
|
|
177
173
|
* **Known gap:** unlike every other `/api/v1` endpoint, this route's error responses use the free-text-only `Error` shape, not `ApiError` — it predates this API's error-catalog rollout to `/api/v1` and hasn't been migrated yet. Treat this as a documented inconsistency, not a schema-design choice to imitate for new endpoints.
|
|
178
174
|
*/
|
|
179
175
|
post: operations["receiveCmSignal"];
|
|
@@ -223,6 +219,46 @@ export interface paths {
|
|
|
223
219
|
patch?: never;
|
|
224
220
|
trace?: never;
|
|
225
221
|
};
|
|
222
|
+
"/api/v1/consents/anonymous/withdraw": {
|
|
223
|
+
parameters: {
|
|
224
|
+
query?: never;
|
|
225
|
+
header?: never;
|
|
226
|
+
path?: never;
|
|
227
|
+
cookie?: never;
|
|
228
|
+
};
|
|
229
|
+
get?: never;
|
|
230
|
+
put?: never;
|
|
231
|
+
/**
|
|
232
|
+
* Withdraw a guest's consent for one or more purposes.
|
|
233
|
+
* @description Unauthenticated public write, authorised by possession of the client-generated `anonymousId` that recorded the consent. Rate-limited. Idempotent: purposes with no active consent are not counted. Notifies connected processors, as an authenticated withdrawal does.
|
|
234
|
+
*/
|
|
235
|
+
post: operations["withdrawConsentAnonymous"];
|
|
236
|
+
delete?: never;
|
|
237
|
+
options?: never;
|
|
238
|
+
head?: never;
|
|
239
|
+
patch?: never;
|
|
240
|
+
trace?: never;
|
|
241
|
+
};
|
|
242
|
+
"/api/v1/consents/{consentId}/withdrawal-acknowledgement": {
|
|
243
|
+
parameters: {
|
|
244
|
+
query?: never;
|
|
245
|
+
header?: never;
|
|
246
|
+
path?: never;
|
|
247
|
+
cookie?: never;
|
|
248
|
+
};
|
|
249
|
+
get?: never;
|
|
250
|
+
put?: never;
|
|
251
|
+
/**
|
|
252
|
+
* Report that a connected processor acted on a `consent.withdrawn` notification (research/2026-08-30-dpdp-research.md, §5-P1).
|
|
253
|
+
* @description `processorNotificationLogs` (see `convex/webhooks.ts`) only ever records whether the outbound `consent.withdrawn` webhook delivery reached the processor, never whether the processor actually stopped processing. A connected processor calls this endpoint to report what it did, closing the loop the same way `/api/v1/dsr/{requestId}/processor-confirmation` does for erasure requests.
|
|
254
|
+
*/
|
|
255
|
+
post: operations["acknowledgeConsentWithdrawal"];
|
|
256
|
+
delete?: never;
|
|
257
|
+
options?: never;
|
|
258
|
+
head?: never;
|
|
259
|
+
patch?: never;
|
|
260
|
+
trace?: never;
|
|
261
|
+
};
|
|
226
262
|
"/api/v1/dsr": {
|
|
227
263
|
parameters: {
|
|
228
264
|
query?: never;
|
|
@@ -319,7 +355,7 @@ export interface paths {
|
|
|
319
355
|
};
|
|
320
356
|
/**
|
|
321
357
|
* List the organization's data principals past their retention window (docs/specs/crm-backend-integration-blockers.md, B1).
|
|
322
|
-
* @description Read-only: returns active (not yet cancelled/executed) `scheduledErasures` rows whose window has already elapsed, so a fiduciary's server integration can trigger its own erasure automation instead of a human watching the dpdpbot dashboard.
|
|
358
|
+
* @description Read-only: returns active (not yet cancelled/executed) `scheduledErasures` rows whose window has already elapsed, so a fiduciary's server integration can trigger its own erasure automation instead of a human watching the dpdpbot dashboard. Write access to retention policies and scheduled erasures stays dashboard-only (ADR-007 D3) — there is no corresponding write route.
|
|
323
359
|
*/
|
|
324
360
|
get: operations["listDueRetentions"];
|
|
325
361
|
put?: never;
|
|
@@ -339,7 +375,7 @@ export interface paths {
|
|
|
339
375
|
};
|
|
340
376
|
/**
|
|
341
377
|
* Look up an org's per-purpose consent state by email (docs/specs/ecommerce-cms-plugins.md, §4).
|
|
342
|
-
* @description Read-only: a WooCommerce/Shopify plugin's only fact about a customer is an email address from its own storefront — every other consent-reading route requires a dpdpbot-internal consent id or a brokered principal token. This resolves an email to the calling organization's own current per-purpose consent grants, so a plugin can gate a marketing sync in real time. `found: false` (not a 404) means the identifier is not yet a customer of record for this organization — distinct from "known, with no active consent", which is `found: true` and an empty or all-opted-out `purposes` array.
|
|
378
|
+
* @description Read-only: a WooCommerce/Shopify plugin's only fact about a customer is an email address from its own storefront — every other consent-reading route requires a dpdpbot-internal consent id or a brokered principal token. This resolves an email to the calling organization's own current per-purpose consent grants, so a plugin can gate a marketing sync in real time. `found: false` (not a 404) means the identifier is not yet a customer of record for this organization — distinct from "known, with no active consent", which is `found: true` and an empty or all-opted-out `purposes` array. Write access to consent stays `POST`/`DELETE /cm/v1/consent` — there is no corresponding write route here (ADR-007 D3).
|
|
343
379
|
*/
|
|
344
380
|
get: operations["getConsentStatus"];
|
|
345
381
|
put?: never;
|
|
@@ -350,6 +386,86 @@ export interface paths {
|
|
|
350
386
|
patch?: never;
|
|
351
387
|
trace?: never;
|
|
352
388
|
};
|
|
389
|
+
"/api/v1/dsr/{requestId}/processor-confirmation": {
|
|
390
|
+
parameters: {
|
|
391
|
+
query?: never;
|
|
392
|
+
header?: never;
|
|
393
|
+
path?: never;
|
|
394
|
+
cookie?: never;
|
|
395
|
+
};
|
|
396
|
+
get?: never;
|
|
397
|
+
put?: never;
|
|
398
|
+
/**
|
|
399
|
+
* Report what a connected processor actually did about an erasure request (docs/specs/ecommerce-cms-plugins.md, §7).
|
|
400
|
+
* @description `dsr.completed` (§2) tells a plugin an erasure was approved on dpdpbot's side; store-side erasure is rarely total deletion (an order record may be anonymized rather than deleted for tax/accounting retention, or a downstream API call may fail). This is the inbound record of what each connected system actually did, surfaced on the DSR detail view so a DPO auditing an erasure can see more than "dpdpbot marked this complete". Additive and read-mostly from dpdpbot's perspective — it does not reopen or alter the DSR's own status.
|
|
401
|
+
*/
|
|
402
|
+
post: operations["recordDsrProcessorConfirmation"];
|
|
403
|
+
delete?: never;
|
|
404
|
+
options?: never;
|
|
405
|
+
head?: never;
|
|
406
|
+
patch?: never;
|
|
407
|
+
trace?: never;
|
|
408
|
+
};
|
|
409
|
+
"/api/v1/withdrawals/{propagationId}/ack": {
|
|
410
|
+
parameters: {
|
|
411
|
+
query?: never;
|
|
412
|
+
header?: never;
|
|
413
|
+
path?: never;
|
|
414
|
+
cookie?: never;
|
|
415
|
+
};
|
|
416
|
+
get?: never;
|
|
417
|
+
put?: never;
|
|
418
|
+
/**
|
|
419
|
+
* Confirm that a consent withdrawal took effect at this destination (research/2026-08-30-dpdp-research.md, §5-P1).
|
|
420
|
+
* @description The public half of the withdrawal-propagation acknowledgement ledger: `suppressionList` proves a withdrawal was *registered*, and this closes the loop the same way `/api/v1/dsr/{requestId}/processor-confirmation` does for erasure requests — a downstream destination reports for itself that it actually stopped processing, rather than a DPO taking dpdpbot's word for it. Idempotent: acknowledging an already-acknowledged row succeeds without changing its `acknowledgedAt`, because a retried confirmation must never fail.
|
|
421
|
+
*/
|
|
422
|
+
post: operations["acknowledgeWithdrawalPropagation"];
|
|
423
|
+
delete?: never;
|
|
424
|
+
options?: never;
|
|
425
|
+
head?: never;
|
|
426
|
+
patch?: never;
|
|
427
|
+
trace?: never;
|
|
428
|
+
};
|
|
429
|
+
"/api/v1/withdrawals/{suppressionId}/propagations": {
|
|
430
|
+
parameters: {
|
|
431
|
+
query?: never;
|
|
432
|
+
header?: never;
|
|
433
|
+
path?: never;
|
|
434
|
+
cookie?: never;
|
|
435
|
+
};
|
|
436
|
+
/**
|
|
437
|
+
* Poll "N of M systems confirmed" for a withdrawal (research/2026-08-30-dpdp-research.md, §5-P1, §6.2).
|
|
438
|
+
* @description The read-side counterpart to `/api/v1/consents/{consentId}/withdrawal-acknowledgement`: lets a connected plugin poll how many downstream destinations have confirmed a withdrawal it caused, the same way `/api/v1/suppression-list` lets it poll the suppression list itself, rather than requiring a DPO to check the console.
|
|
439
|
+
*/
|
|
440
|
+
get: operations["getWithdrawalPropagationStatus"];
|
|
441
|
+
put?: never;
|
|
442
|
+
post?: never;
|
|
443
|
+
delete?: never;
|
|
444
|
+
options?: never;
|
|
445
|
+
head?: never;
|
|
446
|
+
patch?: never;
|
|
447
|
+
trace?: never;
|
|
448
|
+
};
|
|
449
|
+
"/api/v1/suppression-list": {
|
|
450
|
+
parameters: {
|
|
451
|
+
query?: never;
|
|
452
|
+
header?: never;
|
|
453
|
+
path?: never;
|
|
454
|
+
cookie?: never;
|
|
455
|
+
};
|
|
456
|
+
/**
|
|
457
|
+
* Incrementally pull identifiers to stop marketing to (docs/specs/ecommerce-cms-plugins.md, §5).
|
|
458
|
+
* @description Read-only, cursor-by-`suppressedAt`: the reconciliation half of the webhook + poll pattern — a plugin's fallback sweep for when a `consent.withdrawn` webhook delivery failed, since delivery is at-least-once-attempted but not guaranteed. Populated whenever a withdrawing consent's principal has a known email; an anonymous/guest consent has nothing to suppress. Write access is withdrawal/erasure-triggered only — there is no manual write route.
|
|
459
|
+
*/
|
|
460
|
+
get: operations["listSuppressionList"];
|
|
461
|
+
put?: never;
|
|
462
|
+
post?: never;
|
|
463
|
+
delete?: never;
|
|
464
|
+
options?: never;
|
|
465
|
+
head?: never;
|
|
466
|
+
patch?: never;
|
|
467
|
+
trace?: never;
|
|
468
|
+
};
|
|
353
469
|
"/api/v1/breaches": {
|
|
354
470
|
parameters: {
|
|
355
471
|
query?: never;
|
|
@@ -359,7 +475,7 @@ export interface paths {
|
|
|
359
475
|
};
|
|
360
476
|
/**
|
|
361
477
|
* List the organization's breach register (docs/specs/crm-backend-integration-blockers.md, B1).
|
|
362
|
-
* @description Read-only: returns the organization's breach register (s.8(6)), so a fiduciary's server integration can trigger its own containment-erasure automation off a reported breach instead of a human watching the dpdpbot dashboard. Simulated breaches from the Breach Drill Simulator are excluded.
|
|
478
|
+
* @description Read-only: returns the organization's breach register (s.8(6)), so a fiduciary's server integration can trigger its own containment-erasure automation off a reported breach instead of a human watching the dpdpbot dashboard. Simulated breaches from the Breach Drill Simulator are excluded. Write access to the breach register stays dashboard-only (ADR-007 D3) — there is no corresponding write route.
|
|
363
479
|
*/
|
|
364
480
|
get: operations["listBreaches"];
|
|
365
481
|
put?: never;
|
|
@@ -370,6 +486,26 @@ export interface paths {
|
|
|
370
486
|
patch?: never;
|
|
371
487
|
trace?: never;
|
|
372
488
|
};
|
|
489
|
+
"/api/v1/consent-portability/exports/{exportId}/manifest": {
|
|
490
|
+
parameters: {
|
|
491
|
+
query?: never;
|
|
492
|
+
header?: never;
|
|
493
|
+
path?: never;
|
|
494
|
+
cookie?: never;
|
|
495
|
+
};
|
|
496
|
+
/**
|
|
497
|
+
* Read a signed consent-portability export's manifest (research/2026-09-27-dpdp-research.md, Idea P0 "you can leave with your evidence").
|
|
498
|
+
* @description The certificate, not the cargo: schema version, scope, record counters, the running SHA-256 digest folded over every exported record, and its platform HMAC signature — never the record payloads themselves (those stay on the in-console `pageExportRecords` query, unreachable from this surface). Lets a fiduciary's own server integration, or the receiving party on a change of Consent Manager (Indian Bank RFP GEM/2026/B/7823086 §1.6.1(e)), fetch a signed manifest without a human in a browser. Authenticated with the same org-scoped API key as `/api/v1/breaches`.
|
|
499
|
+
*/
|
|
500
|
+
get: operations["getConsentPortabilityManifest"];
|
|
501
|
+
put?: never;
|
|
502
|
+
post?: never;
|
|
503
|
+
delete?: never;
|
|
504
|
+
options?: never;
|
|
505
|
+
head?: never;
|
|
506
|
+
patch?: never;
|
|
507
|
+
trace?: never;
|
|
508
|
+
};
|
|
373
509
|
"/api/v1/consent/verify": {
|
|
374
510
|
parameters: {
|
|
375
511
|
query?: never;
|
|
@@ -394,13 +530,9 @@ export interface paths {
|
|
|
394
530
|
* calling key's org.
|
|
395
531
|
*
|
|
396
532
|
* Withdrawal itself stays `DELETE /cm/v1/consent/{consentId}`'s job —
|
|
397
|
-
* this route never mutates the consent record. It
|
|
398
|
-
* immutable decision row to the org's Consent Gate audit log
|
|
399
|
-
*
|
|
400
|
-
* from the dashboard, not from this API.
|
|
401
|
-
*
|
|
402
|
-
* Requires the `dpdp_consent_gate_api_enabled` flag; while it is off,
|
|
403
|
-
* this route behaves as if it doesn't exist (404).
|
|
533
|
+
* this route never mutates the consent record. It appends an
|
|
534
|
+
* immutable decision row to the org's Consent Gate audit log; that log
|
|
535
|
+
* is read from the dashboard, not from this API.
|
|
404
536
|
*/
|
|
405
537
|
post: operations["verifyConsentGate"];
|
|
406
538
|
delete?: never;
|
|
@@ -429,12 +561,8 @@ export interface paths {
|
|
|
429
561
|
* what it was told. The log is append-only: `verifyForApiKey` is the
|
|
430
562
|
* only writer and there is no corresponding write route (ADR-007 D3).
|
|
431
563
|
*
|
|
432
|
-
*
|
|
433
|
-
*
|
|
434
|
-
* *transport* only and is not a way around
|
|
435
|
-
* `dpdp_consent_gate_decision_audit_enabled`, which gates the
|
|
436
|
-
* recording itself — while that flag is off nothing is written, so
|
|
437
|
-
* this route returns an empty `decisions` array rather than an error.
|
|
564
|
+
* Returns an empty `decisions` array rather than an error when nothing
|
|
565
|
+
* has been recorded.
|
|
438
566
|
*/
|
|
439
567
|
get: operations["listConsentGateDecisions"];
|
|
440
568
|
put?: never;
|
|
@@ -469,13 +597,9 @@ export interface paths {
|
|
|
469
597
|
* as `/api/v1/consent/verify` (ADR-004 D2). Derived entirely from the
|
|
470
598
|
* decision log — it stores nothing of its own and mutates nothing.
|
|
471
599
|
*
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
*
|
|
475
|
-
* `dpdp_consent_gate_bypass_alerts_enabled`, which gates the detection
|
|
476
|
-
* itself — while that flag is off this route returns an empty `alerts`
|
|
477
|
-
* array (with `windowMs`/`denyThreshold` still populated) rather than
|
|
478
|
-
* an error.
|
|
600
|
+
* Returns an empty `alerts` array (with `windowMs`/`denyThreshold`
|
|
601
|
+
* still populated) rather than an error when no bypass pattern is
|
|
602
|
+
* detected.
|
|
479
603
|
*/
|
|
480
604
|
get: operations["listConsentGateBypassAlerts"];
|
|
481
605
|
put?: never;
|
|
@@ -495,7 +619,7 @@ export interface paths {
|
|
|
495
619
|
};
|
|
496
620
|
/**
|
|
497
621
|
* List the organization's cross-border transfer register (docs/specs/crm-backend-integration-blockers.md, B1).
|
|
498
|
-
* @description Read-only: returns the organization's RoPA (`processingActivities`) entries declared as crossing borders (s.16), so a fiduciary's server integration can act on that register programmatically instead of a human reading it off the RoPA Builder dashboard. Archived activities are excluded.
|
|
622
|
+
* @description Read-only: returns the organization's RoPA (`processingActivities`) entries declared as crossing borders (s.16), so a fiduciary's server integration can act on that register programmatically instead of a human reading it off the RoPA Builder dashboard. Archived activities are excluded. Write access to the RoPA stays dashboard-only (ADR-007 D3) — there is no corresponding write route.
|
|
499
623
|
*/
|
|
500
624
|
get: operations["listCrossBorderTransfers"];
|
|
501
625
|
put?: never;
|
|
@@ -506,6 +630,30 @@ export interface paths {
|
|
|
506
630
|
patch?: never;
|
|
507
631
|
trace?: never;
|
|
508
632
|
};
|
|
633
|
+
"/api/v1/discovery/manifest": {
|
|
634
|
+
parameters: {
|
|
635
|
+
query?: never;
|
|
636
|
+
header?: never;
|
|
637
|
+
path?: never;
|
|
638
|
+
cookie?: never;
|
|
639
|
+
};
|
|
640
|
+
get?: never;
|
|
641
|
+
put?: never;
|
|
642
|
+
/**
|
|
643
|
+
* Ingest a column manifest for a data discovery source (research/2026-09-06-dpdp-research.md, §5-P0).
|
|
644
|
+
* @description The connector half of Data Discovery & Classification. Run a read-only `information_schema` (or equivalent) query against your own database replica, inside your own network, and POST the resulting column list here on whatever schedule you choose. The platform never holds your database credentials — nothing here is a connection string, and there is nothing for an attacker who breaches this platform to steal but a schema you can already see in the console.
|
|
645
|
+
* Each column is classified against the India-specific personal-data taxonomy (Aadhaar, PAN, IFSC, UPI VPA, Voter ID, ABHA, guardian indicators) and reconciled against what is already on file: a column already known is re-classified in place, keeping any review recorded against it, rather than duplicated. A nightly run keeps the source inside its 90-day re-scan horizon without anyone opening a browser.
|
|
646
|
+
* `sampleValues` is accepted only for a source whose owner has explicitly opted it in from the console. Values are matched against the patterns above and discarded inside the request; nothing stores them. Sending them for a source that has not opted in is a 400, not a silent drop.
|
|
647
|
+
* Listing a table in `reconcileTablePaths` asserts that this manifest describes it in full: any column on file under it and absent here is marked as dropped from your schema and stops counting toward your coverage gaps (it stays readable, because an evidence bundle may already attest to it). A table named there but carrying no column in `columns` is a 400 — otherwise one mis-pasted manifest would retire an entire inventory.
|
|
648
|
+
* Writes are narrow by design: this route can add to and reclassify one source's columns and retire columns in tables you reconcile. Creating or archiving a source, reviewing a field, and changing the sample-value opt-in all stay decisions someone makes in the console, signed in as themselves.
|
|
649
|
+
*/
|
|
650
|
+
post: operations["ingestDiscoveryManifest"];
|
|
651
|
+
delete?: never;
|
|
652
|
+
options?: never;
|
|
653
|
+
head?: never;
|
|
654
|
+
patch?: never;
|
|
655
|
+
trace?: never;
|
|
656
|
+
};
|
|
509
657
|
"/api/v1/offline-consent/links": {
|
|
510
658
|
parameters: {
|
|
511
659
|
query?: never;
|
|
@@ -517,7 +665,7 @@ export interface paths {
|
|
|
517
665
|
put?: never;
|
|
518
666
|
/**
|
|
519
667
|
* Generate an offline/QR consent link (docs/specs/offline-consent-capture.md, Problem Statement gap 6 — "no integration surface").
|
|
520
|
-
* @description Creates the same `offlineConsentLinks` row the dashboard's "Offline consent link" generator does, so a fiduciary's server integration (HIS, POS terminal, CBS) can mint one without a human using the React admin page. The returned `token` resolves at `/offline-consent/{token}` on the fiduciary's own dpdpbot app origin — turn that URL into a QR code for a branch counter, agent desk, or POS terminal.
|
|
668
|
+
* @description Creates the same `offlineConsentLinks` row the dashboard's "Offline consent link" generator does, so a fiduciary's server integration (HIS, POS terminal, CBS) can mint one without a human using the React admin page. The returned `token` resolves at `/offline-consent/{token}` on the fiduciary's own dpdpbot app origin — turn that URL into a QR code for a branch counter, agent desk, or POS terminal.
|
|
521
669
|
*/
|
|
522
670
|
post: operations["createOfflineConsentLink"];
|
|
523
671
|
delete?: never;
|
|
@@ -539,7 +687,7 @@ export interface paths {
|
|
|
539
687
|
* Sync a batch of offline capture sessions (docs/specs/offline-consent-capture.md 4.4).
|
|
540
688
|
* @description An enrolled field device — or the HIS/CBS/POS server fronting a fleet of them — pushes queued capture sessions here when connectivity returns. Each session carries an ECDSA P-256 signature produced in the device's secure element over the canonical string defined in `conformance/audit-hash-spec.md` (Cryptographic Consent Artifact); the server recomputes that string and verifies it against the enrolled `agentDevices` public key.
|
|
541
689
|
*
|
|
542
|
-
* Every session is processed independently, so **partial success is normal**: one forged or stale session never fails the others in the batch. `clientSessionId` is the idempotency key — replaying a batch that already committed returns the original per-session results and writes nothing. A session that fails verification is *quarantined* with a reason and retained as evidence, never silently dropped and never silently accepted.
|
|
690
|
+
* Every session is processed independently, so **partial success is normal**: one forged or stale session never fails the others in the batch. `clientSessionId` is the idempotency key — replaying a batch that already committed returns the original per-session results and writes nothing. A session that fails verification is *quarantined* with a reason and retained as evidence, never silently dropped and never silently accepted.
|
|
543
691
|
*/
|
|
544
692
|
post: operations["syncOfflineCaptures"];
|
|
545
693
|
delete?: never;
|
|
@@ -561,7 +709,7 @@ export interface paths {
|
|
|
561
709
|
* Raise an asynchronous consent request from a POS terminal (docs/specs/offline-consent-capture.md 6.4).
|
|
562
710
|
* @description Called by a till when a phone number is keyed in. Returns immediately with a token the receipt can render as a short link or QR code; the customer reviews the notice and confirms on their own device afterwards at `/consent/{token}`.
|
|
563
711
|
*
|
|
564
|
-
* **The response is not a consent.** No `consents` row exists until the principal affirmatively confirms — processing must not begin on the strength of a raised request. Unanswered requests expire after 72 hours into the fiduciary's DPO queue. The submitted `phone` is HMAC'd per-organization before storage and is never persisted in the clear.
|
|
712
|
+
* **The response is not a consent.** No `consents` row exists until the principal affirmatively confirms — processing must not begin on the strength of a raised request. Unanswered requests expire after 72 hours into the fiduciary's DPO queue. The submitted `phone` is HMAC'd per-organization before storage and is never persisted in the clear.
|
|
565
713
|
*/
|
|
566
714
|
post: operations["createPosConsentRequest"];
|
|
567
715
|
delete?: never;
|
|
@@ -583,7 +731,7 @@ export interface paths {
|
|
|
583
731
|
* Submit the artefact of a completed IVR consent call (docs/specs/offline-consent-capture.md 6.3).
|
|
584
732
|
* @description dpdpbot defines this adapter contract but does not build telephony. A partner gateway posts what a completed call produced; the **audio recording is the affirmative-action evidence**, so `audioRecordingUri` is required — a DTMF digit alone proves a key was pressed, not that a notice was read out first.
|
|
585
733
|
*
|
|
586
|
-
* A `dtmfSequence` beginning with `1` is treated as acceptance and materialises an audited `consents` row with `source: offline_ivr`; anything else records the artefact without creating a consent, so a refusal is retained as evidence rather than discarded. `partnerSignature` is stored verbatim as an assertion of origin — dpdpbot cannot verify a key it does not hold and does not claim to.
|
|
734
|
+
* A `dtmfSequence` beginning with `1` is treated as acceptance and materialises an audited `consents` row with `source: offline_ivr`; anything else records the artefact without creating a consent, so a refusal is retained as evidence rather than discarded. `partnerSignature` is stored verbatim as an assertion of origin — dpdpbot cannot verify a key it does not hold and does not claim to.
|
|
587
735
|
*/
|
|
588
736
|
post: operations["recordIvrConsentArtifact"];
|
|
589
737
|
delete?: never;
|
|
@@ -592,6 +740,28 @@ export interface paths {
|
|
|
592
740
|
patch?: never;
|
|
593
741
|
trace?: never;
|
|
594
742
|
};
|
|
743
|
+
"/api/v1/offline/sms-withdraw": {
|
|
744
|
+
parameters: {
|
|
745
|
+
query?: never;
|
|
746
|
+
header?: never;
|
|
747
|
+
path?: never;
|
|
748
|
+
cookie?: never;
|
|
749
|
+
};
|
|
750
|
+
get?: never;
|
|
751
|
+
put?: never;
|
|
752
|
+
/**
|
|
753
|
+
* SMS/WhatsApp reply-keyword consent withdrawal (docs/specs/offline-consent-capture.md §5).
|
|
754
|
+
* @description A fiduciary points their SMS/WhatsApp gateway's inbound webhook at this URL; every inbound reply is posted here, and only ones matching a withdrawal keyword (`stop`, `unsubscribe`, `withdraw`, `revoke`, `cancel`, matched case-insensitively against the whole trimmed message) act.
|
|
755
|
+
*
|
|
756
|
+
* Always returns `200` on a well-formed, authenticated request — including "no keyword matched" and "no receipt found for this number" — because the caller is a gateway relaying arbitrary inbound text, not a client that can act on a 4xx. `matched`/`withdrawn` in the response let an integration log the outcome without needing a status-code-as-enum.
|
|
757
|
+
*/
|
|
758
|
+
post: operations["smsWhatsappWithdraw"];
|
|
759
|
+
delete?: never;
|
|
760
|
+
options?: never;
|
|
761
|
+
head?: never;
|
|
762
|
+
patch?: never;
|
|
763
|
+
trace?: never;
|
|
764
|
+
};
|
|
595
765
|
"/api/v1/staff/dsr": {
|
|
596
766
|
parameters: {
|
|
597
767
|
query?: never;
|
|
@@ -672,10 +842,7 @@ export interface paths {
|
|
|
672
842
|
};
|
|
673
843
|
get?: never;
|
|
674
844
|
put?: never;
|
|
675
|
-
/**
|
|
676
|
-
* Deny an erasure request on a documented statutory basis.
|
|
677
|
-
* @description Requires the `dpdp_dsr_statutory_denial_enabled` flag.
|
|
678
|
-
*/
|
|
845
|
+
/** Deny an erasure request on a documented statutory basis. */
|
|
679
846
|
post: operations["staffRejectDsrWithStatutoryBasis"];
|
|
680
847
|
delete?: never;
|
|
681
848
|
options?: never;
|
|
@@ -717,6 +884,86 @@ export interface paths {
|
|
|
717
884
|
patch?: never;
|
|
718
885
|
trace?: never;
|
|
719
886
|
};
|
|
887
|
+
"/api/v1/observatory/observations": {
|
|
888
|
+
parameters: {
|
|
889
|
+
query?: never;
|
|
890
|
+
header?: never;
|
|
891
|
+
path?: never;
|
|
892
|
+
cookie?: never;
|
|
893
|
+
};
|
|
894
|
+
get?: never;
|
|
895
|
+
put?: never;
|
|
896
|
+
/**
|
|
897
|
+
* Ingest a batch of Consent Observatory observations (docs/specs/consent-observatory-extension.md §7).
|
|
898
|
+
* @description Unauthenticated by design — requiring an account would collapse contribution rates and would force linking a browsing-derived observation to an identity. Anti-abuse (quorum before publication, outlier rejection) happens downstream of ingest, not here; rate limiting is enforced at the edge, not by this route. Every observation is processed independently, so **partial success is normal**: one malformed observation never fails the batch. `domain` is re-normalized server-side (lowercased, scheme/port/userinfo stripped, reduced toward eTLD+1) — the client's own normalization is never trusted.
|
|
899
|
+
*/
|
|
900
|
+
post: operations["ingestObservatoryObservations"];
|
|
901
|
+
delete?: never;
|
|
902
|
+
options?: never;
|
|
903
|
+
head?: never;
|
|
904
|
+
patch?: never;
|
|
905
|
+
trace?: never;
|
|
906
|
+
};
|
|
907
|
+
"/api/v1/observatory/domains/{domain}": {
|
|
908
|
+
parameters: {
|
|
909
|
+
query?: never;
|
|
910
|
+
header?: never;
|
|
911
|
+
path?: never;
|
|
912
|
+
cookie?: never;
|
|
913
|
+
};
|
|
914
|
+
/**
|
|
915
|
+
* Read a domain's published Consent Observatory verdict (docs/specs/consent-observatory-extension.md §7).
|
|
916
|
+
* @description Unauthenticated public read, so the browser extension (and any third party) can show a registry grade without shipping a Convex client. Returns only a verdict whose `publicationState` is `"published"` — every other state, and any domain with no verdict at all, is a `404`, never a redacted body, so an unpublished verdict's existence is not itself observable from outside. `domain` is re-normalized server-side (lowercased, scheme/path stripped, reduced toward eTLD+1) the same way ingest normalizes it.
|
|
917
|
+
*/
|
|
918
|
+
get: operations["getObservatoryDomainVerdict"];
|
|
919
|
+
put?: never;
|
|
920
|
+
post?: never;
|
|
921
|
+
delete?: never;
|
|
922
|
+
options?: never;
|
|
923
|
+
head?: never;
|
|
924
|
+
patch?: never;
|
|
925
|
+
trace?: never;
|
|
926
|
+
};
|
|
927
|
+
"/api/v1/observatory/sectors/{sector}": {
|
|
928
|
+
parameters: {
|
|
929
|
+
query?: never;
|
|
930
|
+
header?: never;
|
|
931
|
+
path?: never;
|
|
932
|
+
cookie?: never;
|
|
933
|
+
};
|
|
934
|
+
/**
|
|
935
|
+
* Download the aggregate-only sector report (docs/specs/consent-observatory-extension.md §12).
|
|
936
|
+
* @description Unauthenticated public read of a CSV: cohort size, average score, and grade distribution for one closed-enum sector, aggregated only over `publicationState: "published"` verdicts on the current rubric version — never per-domain rows ("Open data (decided, OQ 8): aggregates only"). 404s for a `sector` outside the closed enum.
|
|
937
|
+
*/
|
|
938
|
+
get: operations["getObservatorySectorReport"];
|
|
939
|
+
put?: never;
|
|
940
|
+
post?: never;
|
|
941
|
+
delete?: never;
|
|
942
|
+
options?: never;
|
|
943
|
+
head?: never;
|
|
944
|
+
patch?: never;
|
|
945
|
+
trace?: never;
|
|
946
|
+
};
|
|
947
|
+
"/api/v1/observatory/contributions/{contributorHash}": {
|
|
948
|
+
parameters: {
|
|
949
|
+
query?: never;
|
|
950
|
+
header?: never;
|
|
951
|
+
path?: never;
|
|
952
|
+
cookie?: never;
|
|
953
|
+
};
|
|
954
|
+
get?: never;
|
|
955
|
+
put?: never;
|
|
956
|
+
post?: never;
|
|
957
|
+
/**
|
|
958
|
+
* "Delete my contributions" (docs/specs/consent-observatory-extension.md §18).
|
|
959
|
+
* @description Unauthenticated, same reasoning as ingest — the only identity available is the rotating, salted `contributorHash` itself, never a user or organization id (§9.2). Deletes every `siteObservations` row for that hash. Always responds `{ "deleted": true }`, including for a hash with no observations — deletion is idempotent, and distinguishing "nothing to delete" from "deleted" would let a caller probe whether a given hash ever contributed anything. `contributorHash` rotates monthly with the salt (§9.2), so this only reaches what the current salt epoch can still link to one installation; after rotation, the data is no longer linkable to it. Ships ungated.
|
|
960
|
+
*/
|
|
961
|
+
delete: operations["deleteObservatoryContributions"];
|
|
962
|
+
options?: never;
|
|
963
|
+
head?: never;
|
|
964
|
+
patch?: never;
|
|
965
|
+
trace?: never;
|
|
966
|
+
};
|
|
720
967
|
}
|
|
721
968
|
export type webhooks = Record<string, never>;
|
|
722
969
|
export interface components {
|
|
@@ -779,8 +1026,18 @@ export interface components {
|
|
|
779
1026
|
};
|
|
780
1027
|
/** @description Present only if the domain group has customized banner styling. */
|
|
781
1028
|
bannerSettings?: Record<string, never>;
|
|
782
|
-
|
|
783
|
-
|
|
1029
|
+
/** @description Absolute URL of the org's data-principal portal, or null. */
|
|
1030
|
+
portalUrl?: string | null;
|
|
1031
|
+
/** @description Version of the notice being presented; the widget stores it with the visitor's decision and re-prompts when it changes. */
|
|
1032
|
+
noticeVersion?: number;
|
|
1033
|
+
noticeSourceLanguage?: string;
|
|
1034
|
+
/** @description The grievance contact the notice must name, or null. */
|
|
1035
|
+
grievanceContact?: {
|
|
1036
|
+
name?: string;
|
|
1037
|
+
email?: string;
|
|
1038
|
+
} | null;
|
|
1039
|
+
};
|
|
1040
|
+
/** @description One immutable row of the Consent Gate decision audit log, written by `POST /api/v1/consent/verify`. */
|
|
784
1041
|
ConsentGateDecision: {
|
|
785
1042
|
/** @description Stable id for this decision row — usable as a de-duplication key when tailing the log. */
|
|
786
1043
|
decisionId: string;
|
|
@@ -936,6 +1193,59 @@ export interface components {
|
|
|
936
1193
|
/** @description Free-text message. Not yet a stable machine-readable code — see the "Known gap" note in the top-level description. */
|
|
937
1194
|
error: string;
|
|
938
1195
|
};
|
|
1196
|
+
/** @description One (domain, pageType, phase) snapshot (docs/specs/consent-observatory-extension.md §2.2, §4.1). Trimmed from the spec's full shape — no `pathHash`, `fpApiCalls`, `buttonGraph`, or `discoveredLinks` yet; this endpoint ships ingest and storage only, not rubric evaluation. */
|
|
1197
|
+
ObservatoryObservation: {
|
|
1198
|
+
/** @description Re-normalized server-side on receipt — do not rely on this being echoed back verbatim. */
|
|
1199
|
+
domain: string;
|
|
1200
|
+
/** @enum {string} */
|
|
1201
|
+
pageType: "home" | "listing" | "product" | "article" | "auth" | "checkout" | "account" | "form" | "policy" | "other";
|
|
1202
|
+
/** @enum {string} */
|
|
1203
|
+
phase: "pre_interaction" | "post_accept" | "post_reject" | "no_action";
|
|
1204
|
+
/** @enum {string} */
|
|
1205
|
+
source: "extension" | "probe" | "seed_crawl";
|
|
1206
|
+
/** @description Epoch milliseconds. */
|
|
1207
|
+
observedAt: number;
|
|
1208
|
+
rulesetVersion: string;
|
|
1209
|
+
/** @description Rotating, salted hash of an extension-local install id. Absent for `source: probe`. */
|
|
1210
|
+
contributorHash?: string;
|
|
1211
|
+
cookies?: {
|
|
1212
|
+
name: string;
|
|
1213
|
+
/** @enum {string} */
|
|
1214
|
+
party: "first" | "third";
|
|
1215
|
+
/** @enum {string} */
|
|
1216
|
+
expiryClass: "session" | "lt_24h" | "lt_30d" | "lt_13mo" | "gt_13mo";
|
|
1217
|
+
}[];
|
|
1218
|
+
storageKeys?: string[];
|
|
1219
|
+
requestHosts?: string[];
|
|
1220
|
+
cmp?: string;
|
|
1221
|
+
bannerFingerprint?: string;
|
|
1222
|
+
};
|
|
1223
|
+
/** @description A published Consent Observatory verdict (docs/specs/consent-observatory-extension.md §4.3, §7). Never includes `publicationState`, `noticeSentAt`, `claimedByOrganizationId`, or `sector` — those are internal-only fields on `siteVerdicts`; a `200` from this endpoint is only ever returned for a `"published"` row in the first place. */
|
|
1224
|
+
ObservatoryDomainVerdict: {
|
|
1225
|
+
domain: string;
|
|
1226
|
+
rubricVersion: string;
|
|
1227
|
+
/** @description 0..100, excluding advisory checks. */
|
|
1228
|
+
score: number;
|
|
1229
|
+
/** @enum {string} */
|
|
1230
|
+
grade: "A" | "B" | "C" | "D" | "E" | "insufficient_data";
|
|
1231
|
+
checkResults: {
|
|
1232
|
+
checkKey: string;
|
|
1233
|
+
/** @enum {string} */
|
|
1234
|
+
status: "pass" | "fail" | "insufficient_data";
|
|
1235
|
+
weight: number;
|
|
1236
|
+
confidence: number;
|
|
1237
|
+
}[];
|
|
1238
|
+
/** @description Epoch milliseconds. */
|
|
1239
|
+
computedAt: number;
|
|
1240
|
+
/** @description Epoch milliseconds; past this the verdict is due a recompute. */
|
|
1241
|
+
staleAfter: number;
|
|
1242
|
+
/** @description Whether this domain itself runs dpdpbot's own consent banner (docs/specs/consent-observatory-extension.md §14, "Reciprocal loop"). Always populated, with `verified: false` when it does not; the type stays nullable for backward compatibility. */
|
|
1243
|
+
reciprocalBadge?: {
|
|
1244
|
+
verified?: boolean;
|
|
1245
|
+
/** @description Epoch milliseconds of the most recent observation reporting dpdpbot's own CMP, or null when `verified` is false. */
|
|
1246
|
+
verifiedAt?: number | null;
|
|
1247
|
+
} | null;
|
|
1248
|
+
};
|
|
939
1249
|
};
|
|
940
1250
|
responses: never;
|
|
941
1251
|
parameters: {
|
|
@@ -1000,7 +1310,7 @@ export interface operations {
|
|
|
1000
1310
|
"application/json": components["schemas"]["Error"];
|
|
1001
1311
|
};
|
|
1002
1312
|
};
|
|
1003
|
-
/** @description Notice not found (or belongs to a different organization), or no data principal matches the given email.
|
|
1313
|
+
/** @description Notice not found (or belongs to a different organization), or no data principal matches the given email. */
|
|
1004
1314
|
404: {
|
|
1005
1315
|
headers: {
|
|
1006
1316
|
[name: string]: unknown;
|
|
@@ -1059,7 +1369,7 @@ export interface operations {
|
|
|
1059
1369
|
"application/json": components["schemas"]["Error"];
|
|
1060
1370
|
};
|
|
1061
1371
|
};
|
|
1062
|
-
/** @description No such consent record, or it belongs to a different organization than the API key.
|
|
1372
|
+
/** @description No such consent record, or it belongs to a different organization than the API key. */
|
|
1063
1373
|
404: {
|
|
1064
1374
|
headers: {
|
|
1065
1375
|
[name: string]: unknown;
|
|
@@ -1109,7 +1419,7 @@ export interface operations {
|
|
|
1109
1419
|
"application/json": components["schemas"]["Error"];
|
|
1110
1420
|
};
|
|
1111
1421
|
};
|
|
1112
|
-
/** @description No such consent record, or it belongs to a different organization than the API key.
|
|
1422
|
+
/** @description No such consent record, or it belongs to a different organization than the API key. */
|
|
1113
1423
|
404: {
|
|
1114
1424
|
headers: {
|
|
1115
1425
|
[name: string]: unknown;
|
|
@@ -1149,7 +1459,7 @@ export interface operations {
|
|
|
1149
1459
|
"application/json": components["schemas"]["OrgSummary"];
|
|
1150
1460
|
};
|
|
1151
1461
|
};
|
|
1152
|
-
/** @description No organization matches this slug
|
|
1462
|
+
/** @description No organization matches this slug. */
|
|
1153
1463
|
404: {
|
|
1154
1464
|
headers: {
|
|
1155
1465
|
[name: string]: unknown;
|
|
@@ -1214,7 +1524,7 @@ export interface operations {
|
|
|
1214
1524
|
"application/json": components["schemas"]["Notice"];
|
|
1215
1525
|
};
|
|
1216
1526
|
};
|
|
1217
|
-
/** @description No such notice
|
|
1527
|
+
/** @description No such notice. */
|
|
1218
1528
|
404: {
|
|
1219
1529
|
headers: {
|
|
1220
1530
|
[name: string]: unknown;
|
|
@@ -1252,7 +1562,7 @@ export interface operations {
|
|
|
1252
1562
|
};
|
|
1253
1563
|
};
|
|
1254
1564
|
};
|
|
1255
|
-
/** @description The domain is not registered to this organization
|
|
1565
|
+
/** @description The domain is not registered to this organization. */
|
|
1256
1566
|
404: {
|
|
1257
1567
|
headers: {
|
|
1258
1568
|
[name: string]: unknown;
|
|
@@ -1294,7 +1604,7 @@ export interface operations {
|
|
|
1294
1604
|
"application/json": components["schemas"]["ApiError"];
|
|
1295
1605
|
};
|
|
1296
1606
|
};
|
|
1297
|
-
/** @description No matching domain group, the domain isn't registered to that group's organization, no notice resolves
|
|
1607
|
+
/** @description No matching domain group, the domain isn't registered to that group's organization, or no notice resolves. */
|
|
1298
1608
|
404: {
|
|
1299
1609
|
headers: {
|
|
1300
1610
|
[name: string]: unknown;
|
|
@@ -1353,15 +1663,6 @@ export interface operations {
|
|
|
1353
1663
|
"application/json": components["schemas"]["ApiError"];
|
|
1354
1664
|
};
|
|
1355
1665
|
};
|
|
1356
|
-
/** @description The `dpdp_mobile_api_enabled` flag is off. */
|
|
1357
|
-
404: {
|
|
1358
|
-
headers: {
|
|
1359
|
-
[name: string]: unknown;
|
|
1360
|
-
};
|
|
1361
|
-
content: {
|
|
1362
|
-
"application/json": components["schemas"]["ApiError"];
|
|
1363
|
-
};
|
|
1364
|
-
};
|
|
1365
1666
|
};
|
|
1366
1667
|
};
|
|
1367
1668
|
receiveCmSignal: {
|
|
@@ -1413,15 +1714,6 @@ export interface operations {
|
|
|
1413
1714
|
"application/json": components["schemas"]["Error"];
|
|
1414
1715
|
};
|
|
1415
1716
|
};
|
|
1416
|
-
/** @description The `dpdp_cm_inbound_signals_enabled` flag is off. */
|
|
1417
|
-
404: {
|
|
1418
|
-
headers: {
|
|
1419
|
-
[name: string]: unknown;
|
|
1420
|
-
};
|
|
1421
|
-
content: {
|
|
1422
|
-
"application/json": components["schemas"]["Error"];
|
|
1423
|
-
};
|
|
1424
|
-
};
|
|
1425
1717
|
};
|
|
1426
1718
|
};
|
|
1427
1719
|
linkAnonymousConsent: {
|
|
@@ -1450,6 +1742,7 @@ export interface operations {
|
|
|
1450
1742
|
needsReconsent: {
|
|
1451
1743
|
noticeId: string;
|
|
1452
1744
|
purpose: string;
|
|
1745
|
+
dataTypes: string[];
|
|
1453
1746
|
}[];
|
|
1454
1747
|
};
|
|
1455
1748
|
};
|
|
@@ -1491,6 +1784,12 @@ export interface operations {
|
|
|
1491
1784
|
purpose: string;
|
|
1492
1785
|
dataTypes: string[];
|
|
1493
1786
|
anonymousId: string;
|
|
1787
|
+
/** @description Locale of the notice text the visitor read. */
|
|
1788
|
+
noticeLocale?: string;
|
|
1789
|
+
/** @description SHA-256 of the exact notice text presented, stored in the consent audit trail as evidence of what was shown. */
|
|
1790
|
+
noticeHash?: string;
|
|
1791
|
+
/** @description The domain group the embedded widget loaded for. Used to attribute the consent when the notice itself is org-wide (not scoped to a group); ignored when the notice is scoped, and dropped if it is not a group in this organization. */
|
|
1792
|
+
domainGroupId?: string;
|
|
1494
1793
|
};
|
|
1495
1794
|
};
|
|
1496
1795
|
};
|
|
@@ -1518,38 +1817,91 @@ export interface operations {
|
|
|
1518
1817
|
"application/json": components["schemas"]["ApiError"];
|
|
1519
1818
|
};
|
|
1520
1819
|
};
|
|
1521
|
-
/** @description The `dpdp_mobile_api_enabled` flag is off. */
|
|
1522
|
-
404: {
|
|
1523
|
-
headers: {
|
|
1524
|
-
[name: string]: unknown;
|
|
1525
|
-
};
|
|
1526
|
-
content: {
|
|
1527
|
-
"application/json": components["schemas"]["ApiError"];
|
|
1528
|
-
};
|
|
1529
|
-
};
|
|
1530
1820
|
};
|
|
1531
1821
|
};
|
|
1532
|
-
|
|
1822
|
+
withdrawConsentAnonymous: {
|
|
1533
1823
|
parameters: {
|
|
1534
1824
|
query?: never;
|
|
1535
1825
|
header?: never;
|
|
1536
1826
|
path?: never;
|
|
1537
1827
|
cookie?: never;
|
|
1538
1828
|
};
|
|
1539
|
-
requestBody
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1829
|
+
requestBody: {
|
|
1830
|
+
content: {
|
|
1831
|
+
"application/json": {
|
|
1832
|
+
organizationId: string;
|
|
1833
|
+
anonymousId: string;
|
|
1834
|
+
purposes: string[];
|
|
1835
|
+
};
|
|
1836
|
+
};
|
|
1837
|
+
};
|
|
1838
|
+
responses: {
|
|
1839
|
+
/** @description Withdrawal processed. */
|
|
1840
|
+
200: {
|
|
1841
|
+
headers: {
|
|
1842
|
+
[name: string]: unknown;
|
|
1545
1843
|
};
|
|
1546
1844
|
content: {
|
|
1547
1845
|
"application/json": {
|
|
1548
|
-
|
|
1846
|
+
withdrawn: number;
|
|
1847
|
+
purposes: string[];
|
|
1848
|
+
withdrawnAt: number;
|
|
1549
1849
|
};
|
|
1550
1850
|
};
|
|
1551
1851
|
};
|
|
1552
|
-
/** @description Missing
|
|
1852
|
+
/** @description Missing/invalid fields or rate limited. */
|
|
1853
|
+
400: {
|
|
1854
|
+
headers: {
|
|
1855
|
+
[name: string]: unknown;
|
|
1856
|
+
};
|
|
1857
|
+
content: {
|
|
1858
|
+
"application/json": components["schemas"]["ApiError"];
|
|
1859
|
+
};
|
|
1860
|
+
};
|
|
1861
|
+
};
|
|
1862
|
+
};
|
|
1863
|
+
acknowledgeConsentWithdrawal: {
|
|
1864
|
+
parameters: {
|
|
1865
|
+
query?: never;
|
|
1866
|
+
header?: never;
|
|
1867
|
+
path: {
|
|
1868
|
+
/** @description Convex document id of the `consents` row. */
|
|
1869
|
+
consentId: components["parameters"]["ConsentId"];
|
|
1870
|
+
};
|
|
1871
|
+
cookie?: never;
|
|
1872
|
+
};
|
|
1873
|
+
requestBody: {
|
|
1874
|
+
content: {
|
|
1875
|
+
"application/json": {
|
|
1876
|
+
processorName: string;
|
|
1877
|
+
/** @enum {string} */
|
|
1878
|
+
outcome: "completed" | "partial" | "failed";
|
|
1879
|
+
note?: string;
|
|
1880
|
+
};
|
|
1881
|
+
};
|
|
1882
|
+
};
|
|
1883
|
+
responses: {
|
|
1884
|
+
/** @description Acknowledgement recorded. */
|
|
1885
|
+
201: {
|
|
1886
|
+
headers: {
|
|
1887
|
+
[name: string]: unknown;
|
|
1888
|
+
};
|
|
1889
|
+
content: {
|
|
1890
|
+
"application/json": {
|
|
1891
|
+
ok: boolean;
|
|
1892
|
+
};
|
|
1893
|
+
};
|
|
1894
|
+
};
|
|
1895
|
+
/** @description Missing/invalid fields, invalid consent id, or the consent has not been withdrawn. */
|
|
1896
|
+
400: {
|
|
1897
|
+
headers: {
|
|
1898
|
+
[name: string]: unknown;
|
|
1899
|
+
};
|
|
1900
|
+
content: {
|
|
1901
|
+
"application/json": components["schemas"]["ApiError"];
|
|
1902
|
+
};
|
|
1903
|
+
};
|
|
1904
|
+
/** @description Missing or invalid API key. */
|
|
1553
1905
|
401: {
|
|
1554
1906
|
headers: {
|
|
1555
1907
|
[name: string]: unknown;
|
|
@@ -1558,7 +1910,7 @@ export interface operations {
|
|
|
1558
1910
|
"application/json": components["schemas"]["ApiError"];
|
|
1559
1911
|
};
|
|
1560
1912
|
};
|
|
1561
|
-
/** @description The
|
|
1913
|
+
/** @description The consent does not belong to the calling key's organization. */
|
|
1562
1914
|
404: {
|
|
1563
1915
|
headers: {
|
|
1564
1916
|
[name: string]: unknown;
|
|
@@ -1569,6 +1921,37 @@ export interface operations {
|
|
|
1569
1921
|
};
|
|
1570
1922
|
};
|
|
1571
1923
|
};
|
|
1924
|
+
listDsrRequestsForCurrentUser: {
|
|
1925
|
+
parameters: {
|
|
1926
|
+
query?: never;
|
|
1927
|
+
header?: never;
|
|
1928
|
+
path?: never;
|
|
1929
|
+
cookie?: never;
|
|
1930
|
+
};
|
|
1931
|
+
requestBody?: never;
|
|
1932
|
+
responses: {
|
|
1933
|
+
/** @description The caller's own requests. */
|
|
1934
|
+
200: {
|
|
1935
|
+
headers: {
|
|
1936
|
+
[name: string]: unknown;
|
|
1937
|
+
};
|
|
1938
|
+
content: {
|
|
1939
|
+
"application/json": {
|
|
1940
|
+
requests: components["schemas"]["DsrRequest"][];
|
|
1941
|
+
};
|
|
1942
|
+
};
|
|
1943
|
+
};
|
|
1944
|
+
/** @description Missing, invalid, or expired access token. */
|
|
1945
|
+
401: {
|
|
1946
|
+
headers: {
|
|
1947
|
+
[name: string]: unknown;
|
|
1948
|
+
};
|
|
1949
|
+
content: {
|
|
1950
|
+
"application/json": components["schemas"]["ApiError"];
|
|
1951
|
+
};
|
|
1952
|
+
};
|
|
1953
|
+
};
|
|
1954
|
+
};
|
|
1572
1955
|
createDsrRequest: {
|
|
1573
1956
|
parameters: {
|
|
1574
1957
|
query?: never;
|
|
@@ -1616,15 +1999,6 @@ export interface operations {
|
|
|
1616
1999
|
"application/json": components["schemas"]["ApiError"];
|
|
1617
2000
|
};
|
|
1618
2001
|
};
|
|
1619
|
-
/** @description The `dpdp_mobile_api_enabled` flag is off. */
|
|
1620
|
-
404: {
|
|
1621
|
-
headers: {
|
|
1622
|
-
[name: string]: unknown;
|
|
1623
|
-
};
|
|
1624
|
-
content: {
|
|
1625
|
-
"application/json": components["schemas"]["ApiError"];
|
|
1626
|
-
};
|
|
1627
|
-
};
|
|
1628
2002
|
};
|
|
1629
2003
|
};
|
|
1630
2004
|
listGrievancesForCurrentUser: {
|
|
@@ -1656,15 +2030,6 @@ export interface operations {
|
|
|
1656
2030
|
"application/json": components["schemas"]["ApiError"];
|
|
1657
2031
|
};
|
|
1658
2032
|
};
|
|
1659
|
-
/** @description The `dpdp_mobile_api_enabled` flag is off. */
|
|
1660
|
-
404: {
|
|
1661
|
-
headers: {
|
|
1662
|
-
[name: string]: unknown;
|
|
1663
|
-
};
|
|
1664
|
-
content: {
|
|
1665
|
-
"application/json": components["schemas"]["ApiError"];
|
|
1666
|
-
};
|
|
1667
|
-
};
|
|
1668
2033
|
};
|
|
1669
2034
|
};
|
|
1670
2035
|
createGrievance: {
|
|
@@ -1713,15 +2078,6 @@ export interface operations {
|
|
|
1713
2078
|
"application/json": components["schemas"]["ApiError"];
|
|
1714
2079
|
};
|
|
1715
2080
|
};
|
|
1716
|
-
/** @description The `dpdp_mobile_api_enabled` flag is off. */
|
|
1717
|
-
404: {
|
|
1718
|
-
headers: {
|
|
1719
|
-
[name: string]: unknown;
|
|
1720
|
-
};
|
|
1721
|
-
content: {
|
|
1722
|
-
"application/json": components["schemas"]["ApiError"];
|
|
1723
|
-
};
|
|
1724
|
-
};
|
|
1725
2081
|
};
|
|
1726
2082
|
};
|
|
1727
2083
|
getNomination: {
|
|
@@ -1751,15 +2107,6 @@ export interface operations {
|
|
|
1751
2107
|
"application/json": components["schemas"]["ApiError"];
|
|
1752
2108
|
};
|
|
1753
2109
|
};
|
|
1754
|
-
/** @description The `dpdp_mobile_api_enabled` flag is off. */
|
|
1755
|
-
404: {
|
|
1756
|
-
headers: {
|
|
1757
|
-
[name: string]: unknown;
|
|
1758
|
-
};
|
|
1759
|
-
content: {
|
|
1760
|
-
"application/json": components["schemas"]["ApiError"];
|
|
1761
|
-
};
|
|
1762
|
-
};
|
|
1763
2110
|
};
|
|
1764
2111
|
};
|
|
1765
2112
|
upsertNomination: {
|
|
@@ -1805,15 +2152,6 @@ export interface operations {
|
|
|
1805
2152
|
"application/json": components["schemas"]["ApiError"];
|
|
1806
2153
|
};
|
|
1807
2154
|
};
|
|
1808
|
-
/** @description The `dpdp_mobile_api_enabled` flag is off. */
|
|
1809
|
-
404: {
|
|
1810
|
-
headers: {
|
|
1811
|
-
[name: string]: unknown;
|
|
1812
|
-
};
|
|
1813
|
-
content: {
|
|
1814
|
-
"application/json": components["schemas"]["ApiError"];
|
|
1815
|
-
};
|
|
1816
|
-
};
|
|
1817
2155
|
};
|
|
1818
2156
|
};
|
|
1819
2157
|
revokeNomination: {
|
|
@@ -1845,15 +2183,6 @@ export interface operations {
|
|
|
1845
2183
|
"application/json": components["schemas"]["ApiError"];
|
|
1846
2184
|
};
|
|
1847
2185
|
};
|
|
1848
|
-
/** @description The `dpdp_mobile_api_enabled` flag is off. */
|
|
1849
|
-
404: {
|
|
1850
|
-
headers: {
|
|
1851
|
-
[name: string]: unknown;
|
|
1852
|
-
};
|
|
1853
|
-
content: {
|
|
1854
|
-
"application/json": components["schemas"]["ApiError"];
|
|
1855
|
-
};
|
|
1856
|
-
};
|
|
1857
2186
|
};
|
|
1858
2187
|
};
|
|
1859
2188
|
verifyParent: {
|
|
@@ -1901,15 +2230,6 @@ export interface operations {
|
|
|
1901
2230
|
"application/json": components["schemas"]["ApiError"];
|
|
1902
2231
|
};
|
|
1903
2232
|
};
|
|
1904
|
-
/** @description The `dpdp_mobile_api_enabled` flag is off. */
|
|
1905
|
-
404: {
|
|
1906
|
-
headers: {
|
|
1907
|
-
[name: string]: unknown;
|
|
1908
|
-
};
|
|
1909
|
-
content: {
|
|
1910
|
-
"application/json": components["schemas"]["ApiError"];
|
|
1911
|
-
};
|
|
1912
|
-
};
|
|
1913
2233
|
};
|
|
1914
2234
|
};
|
|
1915
2235
|
listDueRetentions: {
|
|
@@ -1948,15 +2268,6 @@ export interface operations {
|
|
|
1948
2268
|
"application/json": components["schemas"]["ApiError"];
|
|
1949
2269
|
};
|
|
1950
2270
|
};
|
|
1951
|
-
/** @description The `dpdp_retention_due_api_enabled` flag is off. */
|
|
1952
|
-
404: {
|
|
1953
|
-
headers: {
|
|
1954
|
-
[name: string]: unknown;
|
|
1955
|
-
};
|
|
1956
|
-
content: {
|
|
1957
|
-
"application/json": components["schemas"]["ApiError"];
|
|
1958
|
-
};
|
|
1959
|
-
};
|
|
1960
2271
|
};
|
|
1961
2272
|
};
|
|
1962
2273
|
getConsentStatus: {
|
|
@@ -1989,6 +2300,11 @@ export interface operations {
|
|
|
1989
2300
|
status: "opt_in" | "opt_out";
|
|
1990
2301
|
/** @description Epoch ms this purpose was withdrawn, if any. */
|
|
1991
2302
|
withdrawnAt?: number;
|
|
2303
|
+
/**
|
|
2304
|
+
* @description The reserved, platform-defined purpose this org's own `purposeKey` maps to (docs/specs/ecommerce-cms-plugins.md, §6), when a DPO has set one — so a plugin written once against e.g. `dpdp_reserved.marketing` works across every dpdpbot organization instead of string-matching a per-org label. Omitted when no mapping exists.
|
|
2305
|
+
* @enum {string}
|
|
2306
|
+
*/
|
|
2307
|
+
standardPurpose?: "dpdp_reserved.marketing" | "dpdp_reserved.transactional" | "dpdp_reserved.analytics";
|
|
1992
2308
|
}[];
|
|
1993
2309
|
};
|
|
1994
2310
|
};
|
|
@@ -2011,7 +2327,157 @@ export interface operations {
|
|
|
2011
2327
|
"application/json": components["schemas"]["ApiError"];
|
|
2012
2328
|
};
|
|
2013
2329
|
};
|
|
2014
|
-
|
|
2330
|
+
};
|
|
2331
|
+
};
|
|
2332
|
+
recordDsrProcessorConfirmation: {
|
|
2333
|
+
parameters: {
|
|
2334
|
+
query?: never;
|
|
2335
|
+
header?: never;
|
|
2336
|
+
path: {
|
|
2337
|
+
requestId: string;
|
|
2338
|
+
};
|
|
2339
|
+
cookie?: never;
|
|
2340
|
+
};
|
|
2341
|
+
requestBody: {
|
|
2342
|
+
content: {
|
|
2343
|
+
"application/json": {
|
|
2344
|
+
processorName: string;
|
|
2345
|
+
/** @enum {string} */
|
|
2346
|
+
outcome: "completed" | "partial" | "failed";
|
|
2347
|
+
details: {
|
|
2348
|
+
system: string;
|
|
2349
|
+
action: string;
|
|
2350
|
+
note?: string;
|
|
2351
|
+
}[];
|
|
2352
|
+
};
|
|
2353
|
+
};
|
|
2354
|
+
};
|
|
2355
|
+
responses: {
|
|
2356
|
+
/** @description Confirmation recorded. */
|
|
2357
|
+
201: {
|
|
2358
|
+
headers: {
|
|
2359
|
+
[name: string]: unknown;
|
|
2360
|
+
};
|
|
2361
|
+
content: {
|
|
2362
|
+
"application/json": {
|
|
2363
|
+
ok: boolean;
|
|
2364
|
+
};
|
|
2365
|
+
};
|
|
2366
|
+
};
|
|
2367
|
+
/** @description Malformed request body, or the request id does not identify an erasure request. */
|
|
2368
|
+
400: {
|
|
2369
|
+
headers: {
|
|
2370
|
+
[name: string]: unknown;
|
|
2371
|
+
};
|
|
2372
|
+
content: {
|
|
2373
|
+
"application/json": components["schemas"]["ApiError"];
|
|
2374
|
+
};
|
|
2375
|
+
};
|
|
2376
|
+
/** @description Missing or invalid API key. */
|
|
2377
|
+
401: {
|
|
2378
|
+
headers: {
|
|
2379
|
+
[name: string]: unknown;
|
|
2380
|
+
};
|
|
2381
|
+
content: {
|
|
2382
|
+
"application/json": components["schemas"]["ApiError"];
|
|
2383
|
+
};
|
|
2384
|
+
};
|
|
2385
|
+
/** @description The request id does not belong to the calling key's organization. */
|
|
2386
|
+
404: {
|
|
2387
|
+
headers: {
|
|
2388
|
+
[name: string]: unknown;
|
|
2389
|
+
};
|
|
2390
|
+
content: {
|
|
2391
|
+
"application/json": components["schemas"]["ApiError"];
|
|
2392
|
+
};
|
|
2393
|
+
};
|
|
2394
|
+
};
|
|
2395
|
+
};
|
|
2396
|
+
acknowledgeWithdrawalPropagation: {
|
|
2397
|
+
parameters: {
|
|
2398
|
+
query?: never;
|
|
2399
|
+
header?: never;
|
|
2400
|
+
path: {
|
|
2401
|
+
propagationId: string;
|
|
2402
|
+
};
|
|
2403
|
+
cookie?: never;
|
|
2404
|
+
};
|
|
2405
|
+
requestBody?: never;
|
|
2406
|
+
responses: {
|
|
2407
|
+
/** @description Acknowledged (or already was). */
|
|
2408
|
+
200: {
|
|
2409
|
+
headers: {
|
|
2410
|
+
[name: string]: unknown;
|
|
2411
|
+
};
|
|
2412
|
+
content: {
|
|
2413
|
+
"application/json": {
|
|
2414
|
+
ok: boolean;
|
|
2415
|
+
};
|
|
2416
|
+
};
|
|
2417
|
+
};
|
|
2418
|
+
/** @description Missing or invalid API key. */
|
|
2419
|
+
401: {
|
|
2420
|
+
headers: {
|
|
2421
|
+
[name: string]: unknown;
|
|
2422
|
+
};
|
|
2423
|
+
content: {
|
|
2424
|
+
"application/json": components["schemas"]["ApiError"];
|
|
2425
|
+
};
|
|
2426
|
+
};
|
|
2427
|
+
/** @description The propagation id does not belong to the calling key's organization. */
|
|
2428
|
+
404: {
|
|
2429
|
+
headers: {
|
|
2430
|
+
[name: string]: unknown;
|
|
2431
|
+
};
|
|
2432
|
+
content: {
|
|
2433
|
+
"application/json": components["schemas"]["ApiError"];
|
|
2434
|
+
};
|
|
2435
|
+
};
|
|
2436
|
+
};
|
|
2437
|
+
};
|
|
2438
|
+
getWithdrawalPropagationStatus: {
|
|
2439
|
+
parameters: {
|
|
2440
|
+
query?: never;
|
|
2441
|
+
header?: never;
|
|
2442
|
+
path: {
|
|
2443
|
+
suppressionId: string;
|
|
2444
|
+
};
|
|
2445
|
+
cookie?: never;
|
|
2446
|
+
};
|
|
2447
|
+
requestBody?: never;
|
|
2448
|
+
responses: {
|
|
2449
|
+
/** @description The suppression's fan-out status across destinations. */
|
|
2450
|
+
200: {
|
|
2451
|
+
headers: {
|
|
2452
|
+
[name: string]: unknown;
|
|
2453
|
+
};
|
|
2454
|
+
content: {
|
|
2455
|
+
"application/json": {
|
|
2456
|
+
total: number;
|
|
2457
|
+
acknowledged: number;
|
|
2458
|
+
failed: number;
|
|
2459
|
+
entries: {
|
|
2460
|
+
destinationLabel: string;
|
|
2461
|
+
/** @enum {string} */
|
|
2462
|
+
status: "pending" | "acknowledged" | "overdue" | "failed";
|
|
2463
|
+
dispatchedAt: number;
|
|
2464
|
+
acknowledgedAt?: number;
|
|
2465
|
+
failedAt?: number;
|
|
2466
|
+
failureReason?: string;
|
|
2467
|
+
}[];
|
|
2468
|
+
};
|
|
2469
|
+
};
|
|
2470
|
+
};
|
|
2471
|
+
/** @description Missing or invalid API key. */
|
|
2472
|
+
401: {
|
|
2473
|
+
headers: {
|
|
2474
|
+
[name: string]: unknown;
|
|
2475
|
+
};
|
|
2476
|
+
content: {
|
|
2477
|
+
"application/json": components["schemas"]["ApiError"];
|
|
2478
|
+
};
|
|
2479
|
+
};
|
|
2480
|
+
/** @description The suppression entry does not belong to the calling key's organization. */
|
|
2015
2481
|
404: {
|
|
2016
2482
|
headers: {
|
|
2017
2483
|
[name: string]: unknown;
|
|
@@ -2022,6 +2488,50 @@ export interface operations {
|
|
|
2022
2488
|
};
|
|
2023
2489
|
};
|
|
2024
2490
|
};
|
|
2491
|
+
listSuppressionList: {
|
|
2492
|
+
parameters: {
|
|
2493
|
+
query?: {
|
|
2494
|
+
/** @description Epoch ms; only entries suppressed strictly after this are returned. Omit (or pass 0) to pull the full list. */
|
|
2495
|
+
since?: number;
|
|
2496
|
+
};
|
|
2497
|
+
header?: never;
|
|
2498
|
+
path?: never;
|
|
2499
|
+
cookie?: never;
|
|
2500
|
+
};
|
|
2501
|
+
requestBody?: never;
|
|
2502
|
+
responses: {
|
|
2503
|
+
/** @description The calling key's organization's suppression-list entries after `since`. */
|
|
2504
|
+
200: {
|
|
2505
|
+
headers: {
|
|
2506
|
+
[name: string]: unknown;
|
|
2507
|
+
};
|
|
2508
|
+
content: {
|
|
2509
|
+
"application/json": {
|
|
2510
|
+
entries: {
|
|
2511
|
+
identifier: string;
|
|
2512
|
+
/** @enum {string} */
|
|
2513
|
+
identifierType: "email" | "phone";
|
|
2514
|
+
/** @enum {string} */
|
|
2515
|
+
reason: "consent_withdrawal" | "dsr_erasure" | "manual";
|
|
2516
|
+
suppressedAt: number;
|
|
2517
|
+
liftedAt?: number;
|
|
2518
|
+
}[];
|
|
2519
|
+
/** @description Pass as the next call's `since` to continue the pull; `null` means the response was not truncated. */
|
|
2520
|
+
nextCursor: number | null;
|
|
2521
|
+
};
|
|
2522
|
+
};
|
|
2523
|
+
};
|
|
2524
|
+
/** @description Missing or invalid API key. */
|
|
2525
|
+
401: {
|
|
2526
|
+
headers: {
|
|
2527
|
+
[name: string]: unknown;
|
|
2528
|
+
};
|
|
2529
|
+
content: {
|
|
2530
|
+
"application/json": components["schemas"]["ApiError"];
|
|
2531
|
+
};
|
|
2532
|
+
};
|
|
2533
|
+
};
|
|
2534
|
+
};
|
|
2025
2535
|
listBreaches: {
|
|
2026
2536
|
parameters: {
|
|
2027
2537
|
query?: never;
|
|
@@ -2063,7 +2573,54 @@ export interface operations {
|
|
|
2063
2573
|
"application/json": components["schemas"]["ApiError"];
|
|
2064
2574
|
};
|
|
2065
2575
|
};
|
|
2066
|
-
|
|
2576
|
+
};
|
|
2577
|
+
};
|
|
2578
|
+
getConsentPortabilityManifest: {
|
|
2579
|
+
parameters: {
|
|
2580
|
+
query?: never;
|
|
2581
|
+
header?: never;
|
|
2582
|
+
path: {
|
|
2583
|
+
exportId: string;
|
|
2584
|
+
};
|
|
2585
|
+
cookie?: never;
|
|
2586
|
+
};
|
|
2587
|
+
requestBody?: never;
|
|
2588
|
+
responses: {
|
|
2589
|
+
/** @description The export's signed manifest. */
|
|
2590
|
+
200: {
|
|
2591
|
+
headers: {
|
|
2592
|
+
[name: string]: unknown;
|
|
2593
|
+
};
|
|
2594
|
+
content: {
|
|
2595
|
+
"application/json": {
|
|
2596
|
+
exportId: string;
|
|
2597
|
+
organizationId: string;
|
|
2598
|
+
schemaVersion: string;
|
|
2599
|
+
/** @enum {string} */
|
|
2600
|
+
status: "pending" | "building" | "complete" | "failed";
|
|
2601
|
+
/** @enum {string} */
|
|
2602
|
+
reason: "consent_manager_change" | "solution_replacement" | "regulatory_portability" | "routine_drill";
|
|
2603
|
+
scopeFromMs: number;
|
|
2604
|
+
scopeToMs: number;
|
|
2605
|
+
consentRecordCount: number;
|
|
2606
|
+
runningDigest?: string;
|
|
2607
|
+
manifestSignature?: string;
|
|
2608
|
+
manifestSignatureKeyId?: string;
|
|
2609
|
+
completedAt?: number;
|
|
2610
|
+
verificationRecipe?: string;
|
|
2611
|
+
};
|
|
2612
|
+
};
|
|
2613
|
+
};
|
|
2614
|
+
/** @description Missing or invalid API key. */
|
|
2615
|
+
401: {
|
|
2616
|
+
headers: {
|
|
2617
|
+
[name: string]: unknown;
|
|
2618
|
+
};
|
|
2619
|
+
content: {
|
|
2620
|
+
"application/json": components["schemas"]["ApiError"];
|
|
2621
|
+
};
|
|
2622
|
+
};
|
|
2623
|
+
/** @description The export does not exist or belongs to a different organization. */
|
|
2067
2624
|
404: {
|
|
2068
2625
|
headers: {
|
|
2069
2626
|
[name: string]: unknown;
|
|
@@ -2123,7 +2680,7 @@ export interface operations {
|
|
|
2123
2680
|
"application/json": components["schemas"]["ApiError"];
|
|
2124
2681
|
};
|
|
2125
2682
|
};
|
|
2126
|
-
/** @description The
|
|
2683
|
+
/** @description The consent does not exist or belongs to another organization. */
|
|
2127
2684
|
404: {
|
|
2128
2685
|
headers: {
|
|
2129
2686
|
[name: string]: unknown;
|
|
@@ -2175,15 +2732,6 @@ export interface operations {
|
|
|
2175
2732
|
"application/json": components["schemas"]["ApiError"];
|
|
2176
2733
|
};
|
|
2177
2734
|
};
|
|
2178
|
-
/** @description The `dpdp_consent_gate_audit_api_enabled` flag is off. */
|
|
2179
|
-
404: {
|
|
2180
|
-
headers: {
|
|
2181
|
-
[name: string]: unknown;
|
|
2182
|
-
};
|
|
2183
|
-
content: {
|
|
2184
|
-
"application/json": components["schemas"]["ApiError"];
|
|
2185
|
-
};
|
|
2186
|
-
};
|
|
2187
2735
|
};
|
|
2188
2736
|
};
|
|
2189
2737
|
listConsentGateBypassAlerts: {
|
|
@@ -2206,21 +2754,12 @@ export interface operations {
|
|
|
2206
2754
|
/** @description The rolling window, in milliseconds, a deny still counts toward an alert within. */
|
|
2207
2755
|
windowMs: number;
|
|
2208
2756
|
/** @description In-window denies against one consent that constitute an alert. */
|
|
2209
|
-
denyThreshold: number;
|
|
2210
|
-
};
|
|
2211
|
-
};
|
|
2212
|
-
};
|
|
2213
|
-
/** @description Missing, invalid, or revoked API key. */
|
|
2214
|
-
401: {
|
|
2215
|
-
headers: {
|
|
2216
|
-
[name: string]: unknown;
|
|
2217
|
-
};
|
|
2218
|
-
content: {
|
|
2219
|
-
"application/json": components["schemas"]["ApiError"];
|
|
2757
|
+
denyThreshold: number;
|
|
2758
|
+
};
|
|
2220
2759
|
};
|
|
2221
2760
|
};
|
|
2222
|
-
/** @description
|
|
2223
|
-
|
|
2761
|
+
/** @description Missing, invalid, or revoked API key. */
|
|
2762
|
+
401: {
|
|
2224
2763
|
headers: {
|
|
2225
2764
|
[name: string]: unknown;
|
|
2226
2765
|
};
|
|
@@ -2268,7 +2807,68 @@ export interface operations {
|
|
|
2268
2807
|
"application/json": components["schemas"]["ApiError"];
|
|
2269
2808
|
};
|
|
2270
2809
|
};
|
|
2271
|
-
|
|
2810
|
+
};
|
|
2811
|
+
};
|
|
2812
|
+
ingestDiscoveryManifest: {
|
|
2813
|
+
parameters: {
|
|
2814
|
+
query?: never;
|
|
2815
|
+
header?: never;
|
|
2816
|
+
path?: never;
|
|
2817
|
+
cookie?: never;
|
|
2818
|
+
};
|
|
2819
|
+
requestBody: {
|
|
2820
|
+
content: {
|
|
2821
|
+
"application/json": {
|
|
2822
|
+
/** @description The discovery source to ingest into, as shown in the console. Must belong to the calling key's organization and must not be archived. */
|
|
2823
|
+
sourceId: string;
|
|
2824
|
+
columns: {
|
|
2825
|
+
/** @description e.g. `public.customers`. */
|
|
2826
|
+
tablePath: string;
|
|
2827
|
+
columnName: string;
|
|
2828
|
+
/** @description The database's own type, e.g. `varchar`. */
|
|
2829
|
+
declaredType?: string;
|
|
2830
|
+
/** @description Opt-in only, and never stored. See the description above before sending these. */
|
|
2831
|
+
sampleValues?: string[];
|
|
2832
|
+
}[];
|
|
2833
|
+
/** @description Tables this manifest describes in full. Columns on file under them and absent here are retired. */
|
|
2834
|
+
reconcileTablePaths?: string[];
|
|
2835
|
+
};
|
|
2836
|
+
};
|
|
2837
|
+
};
|
|
2838
|
+
responses: {
|
|
2839
|
+
/** @description What the ingestion classified, added, updated and retired. */
|
|
2840
|
+
200: {
|
|
2841
|
+
headers: {
|
|
2842
|
+
[name: string]: unknown;
|
|
2843
|
+
};
|
|
2844
|
+
content: {
|
|
2845
|
+
"application/json": {
|
|
2846
|
+
fieldsClassified: number;
|
|
2847
|
+
fieldsNew: number;
|
|
2848
|
+
fieldsUpdated: number;
|
|
2849
|
+
fieldsRetired: number;
|
|
2850
|
+
};
|
|
2851
|
+
};
|
|
2852
|
+
};
|
|
2853
|
+
/** @description Malformed body, a manifest over the per-call column limit, sample values for a source that has not opted in, or a reconciled table the manifest does not describe. */
|
|
2854
|
+
400: {
|
|
2855
|
+
headers: {
|
|
2856
|
+
[name: string]: unknown;
|
|
2857
|
+
};
|
|
2858
|
+
content: {
|
|
2859
|
+
"application/json": components["schemas"]["ApiError"];
|
|
2860
|
+
};
|
|
2861
|
+
};
|
|
2862
|
+
/** @description Missing or invalid API key. */
|
|
2863
|
+
401: {
|
|
2864
|
+
headers: {
|
|
2865
|
+
[name: string]: unknown;
|
|
2866
|
+
};
|
|
2867
|
+
content: {
|
|
2868
|
+
"application/json": components["schemas"]["ApiError"];
|
|
2869
|
+
};
|
|
2870
|
+
};
|
|
2871
|
+
/** @description No such source for the calling key's organization. */
|
|
2272
2872
|
404: {
|
|
2273
2873
|
headers: {
|
|
2274
2874
|
[name: string]: unknown;
|
|
@@ -2277,6 +2877,15 @@ export interface operations {
|
|
|
2277
2877
|
"application/json": components["schemas"]["ApiError"];
|
|
2278
2878
|
};
|
|
2279
2879
|
};
|
|
2880
|
+
/** @description The source is archived. */
|
|
2881
|
+
409: {
|
|
2882
|
+
headers: {
|
|
2883
|
+
[name: string]: unknown;
|
|
2884
|
+
};
|
|
2885
|
+
content: {
|
|
2886
|
+
"application/json": components["schemas"]["ApiError"];
|
|
2887
|
+
};
|
|
2888
|
+
};
|
|
2280
2889
|
};
|
|
2281
2890
|
};
|
|
2282
2891
|
createOfflineConsentLink: {
|
|
@@ -2319,7 +2928,7 @@ export interface operations {
|
|
|
2319
2928
|
"application/json": components["schemas"]["ApiError"];
|
|
2320
2929
|
};
|
|
2321
2930
|
};
|
|
2322
|
-
/** @description Notice not found (or belongs to a different organization).
|
|
2931
|
+
/** @description Notice not found (or belongs to a different organization). */
|
|
2323
2932
|
404: {
|
|
2324
2933
|
headers: {
|
|
2325
2934
|
[name: string]: unknown;
|
|
@@ -2383,15 +2992,6 @@ export interface operations {
|
|
|
2383
2992
|
"application/json": components["schemas"]["ApiError"];
|
|
2384
2993
|
};
|
|
2385
2994
|
};
|
|
2386
|
-
/** @description The `dpdp_offline_agent_capture_enabled` flag is off. */
|
|
2387
|
-
404: {
|
|
2388
|
-
headers: {
|
|
2389
|
-
[name: string]: unknown;
|
|
2390
|
-
};
|
|
2391
|
-
content: {
|
|
2392
|
-
"application/json": components["schemas"]["ApiError"];
|
|
2393
|
-
};
|
|
2394
|
-
};
|
|
2395
2995
|
/** @description Per-API-key rate limit exceeded. */
|
|
2396
2996
|
429: {
|
|
2397
2997
|
headers: {
|
|
@@ -2454,7 +3054,7 @@ export interface operations {
|
|
|
2454
3054
|
"application/json": components["schemas"]["ApiError"];
|
|
2455
3055
|
};
|
|
2456
3056
|
};
|
|
2457
|
-
/** @description Notice not found
|
|
3057
|
+
/** @description Notice not found. */
|
|
2458
3058
|
404: {
|
|
2459
3059
|
headers: {
|
|
2460
3060
|
[name: string]: unknown;
|
|
@@ -2518,7 +3118,7 @@ export interface operations {
|
|
|
2518
3118
|
"application/json": components["schemas"]["ApiError"];
|
|
2519
3119
|
};
|
|
2520
3120
|
};
|
|
2521
|
-
/** @description Notice not found
|
|
3121
|
+
/** @description Notice not found. */
|
|
2522
3122
|
404: {
|
|
2523
3123
|
headers: {
|
|
2524
3124
|
[name: string]: unknown;
|
|
@@ -2538,29 +3138,39 @@ export interface operations {
|
|
|
2538
3138
|
};
|
|
2539
3139
|
};
|
|
2540
3140
|
};
|
|
2541
|
-
|
|
3141
|
+
smsWhatsappWithdraw: {
|
|
2542
3142
|
parameters: {
|
|
2543
|
-
query
|
|
2544
|
-
organizationId: string;
|
|
2545
|
-
};
|
|
3143
|
+
query?: never;
|
|
2546
3144
|
header?: never;
|
|
2547
3145
|
path?: never;
|
|
2548
3146
|
cookie?: never;
|
|
2549
3147
|
};
|
|
2550
|
-
requestBody
|
|
3148
|
+
requestBody: {
|
|
3149
|
+
content: {
|
|
3150
|
+
"application/json": {
|
|
3151
|
+
/** @description Raw number as the gateway received it; normalised and HMAC'd per-organization before lookup. Never stored in the clear. */
|
|
3152
|
+
phone: string;
|
|
3153
|
+
/** @description The inbound reply text, verbatim. */
|
|
3154
|
+
message: string;
|
|
3155
|
+
};
|
|
3156
|
+
};
|
|
3157
|
+
};
|
|
2551
3158
|
responses: {
|
|
2552
|
-
/** @description
|
|
3159
|
+
/** @description Request processed (regardless of whether a keyword matched). */
|
|
2553
3160
|
200: {
|
|
2554
3161
|
headers: {
|
|
2555
3162
|
[name: string]: unknown;
|
|
2556
3163
|
};
|
|
2557
3164
|
content: {
|
|
2558
3165
|
"application/json": {
|
|
2559
|
-
|
|
3166
|
+
/** @description Whether the message matched a withdrawal keyword. */
|
|
3167
|
+
matched: boolean;
|
|
3168
|
+
/** @description Whether at least one receipt for this phone number was withdrawn as a result. */
|
|
3169
|
+
withdrawn: boolean;
|
|
2560
3170
|
};
|
|
2561
3171
|
};
|
|
2562
3172
|
};
|
|
2563
|
-
/** @description
|
|
3173
|
+
/** @description Malformed body, or the phone number contains no digits. */
|
|
2564
3174
|
400: {
|
|
2565
3175
|
headers: {
|
|
2566
3176
|
[name: string]: unknown;
|
|
@@ -2569,7 +3179,7 @@ export interface operations {
|
|
|
2569
3179
|
"application/json": components["schemas"]["ApiError"];
|
|
2570
3180
|
};
|
|
2571
3181
|
};
|
|
2572
|
-
/** @description
|
|
3182
|
+
/** @description Missing, invalid, or revoked API key. */
|
|
2573
3183
|
401: {
|
|
2574
3184
|
headers: {
|
|
2575
3185
|
[name: string]: unknown;
|
|
@@ -2578,8 +3188,8 @@ export interface operations {
|
|
|
2578
3188
|
"application/json": components["schemas"]["ApiError"];
|
|
2579
3189
|
};
|
|
2580
3190
|
};
|
|
2581
|
-
/** @description
|
|
2582
|
-
|
|
3191
|
+
/** @description Per-API-key rate limit exceeded. */
|
|
3192
|
+
429: {
|
|
2583
3193
|
headers: {
|
|
2584
3194
|
[name: string]: unknown;
|
|
2585
3195
|
};
|
|
@@ -2589,10 +3199,10 @@ export interface operations {
|
|
|
2589
3199
|
};
|
|
2590
3200
|
};
|
|
2591
3201
|
};
|
|
2592
|
-
|
|
3202
|
+
staffListDsrRequests: {
|
|
2593
3203
|
parameters: {
|
|
2594
|
-
query
|
|
2595
|
-
|
|
3204
|
+
query: {
|
|
3205
|
+
organizationId: string;
|
|
2596
3206
|
};
|
|
2597
3207
|
header?: never;
|
|
2598
3208
|
path?: never;
|
|
@@ -2600,17 +3210,26 @@ export interface operations {
|
|
|
2600
3210
|
};
|
|
2601
3211
|
requestBody?: never;
|
|
2602
3212
|
responses: {
|
|
2603
|
-
/** @description
|
|
3213
|
+
/** @description The organization's DSR requests. */
|
|
2604
3214
|
200: {
|
|
2605
3215
|
headers: {
|
|
2606
3216
|
[name: string]: unknown;
|
|
2607
3217
|
};
|
|
2608
3218
|
content: {
|
|
2609
3219
|
"application/json": {
|
|
2610
|
-
|
|
3220
|
+
requests: Record<string, never>[];
|
|
2611
3221
|
};
|
|
2612
3222
|
};
|
|
2613
3223
|
};
|
|
3224
|
+
/** @description Missing organizationId, or the caller isn't staff at that org. */
|
|
3225
|
+
400: {
|
|
3226
|
+
headers: {
|
|
3227
|
+
[name: string]: unknown;
|
|
3228
|
+
};
|
|
3229
|
+
content: {
|
|
3230
|
+
"application/json": components["schemas"]["ApiError"];
|
|
3231
|
+
};
|
|
3232
|
+
};
|
|
2614
3233
|
/** @description Not authenticated. */
|
|
2615
3234
|
401: {
|
|
2616
3235
|
headers: {
|
|
@@ -2620,8 +3239,32 @@ export interface operations {
|
|
|
2620
3239
|
"application/json": components["schemas"]["ApiError"];
|
|
2621
3240
|
};
|
|
2622
3241
|
};
|
|
2623
|
-
|
|
2624
|
-
|
|
3242
|
+
};
|
|
3243
|
+
};
|
|
3244
|
+
staffListStatutoryBasisSuggestions: {
|
|
3245
|
+
parameters: {
|
|
3246
|
+
query?: {
|
|
3247
|
+
sector?: string;
|
|
3248
|
+
};
|
|
3249
|
+
header?: never;
|
|
3250
|
+
path?: never;
|
|
3251
|
+
cookie?: never;
|
|
3252
|
+
};
|
|
3253
|
+
requestBody?: never;
|
|
3254
|
+
responses: {
|
|
3255
|
+
/** @description Suggestions. */
|
|
3256
|
+
200: {
|
|
3257
|
+
headers: {
|
|
3258
|
+
[name: string]: unknown;
|
|
3259
|
+
};
|
|
3260
|
+
content: {
|
|
3261
|
+
"application/json": {
|
|
3262
|
+
suggestions: Record<string, never>[];
|
|
3263
|
+
};
|
|
3264
|
+
};
|
|
3265
|
+
};
|
|
3266
|
+
/** @description Not authenticated. */
|
|
3267
|
+
401: {
|
|
2625
3268
|
headers: {
|
|
2626
3269
|
[name: string]: unknown;
|
|
2627
3270
|
};
|
|
@@ -2753,7 +3396,7 @@ export interface operations {
|
|
|
2753
3396
|
};
|
|
2754
3397
|
};
|
|
2755
3398
|
};
|
|
2756
|
-
/** @description Missing fields,
|
|
3399
|
+
/** @description Missing fields, wrong request type, invalid transition, or the caller isn't staff at that org. */
|
|
2757
3400
|
400: {
|
|
2758
3401
|
headers: {
|
|
2759
3402
|
[name: string]: unknown;
|
|
@@ -2813,15 +3456,6 @@ export interface operations {
|
|
|
2813
3456
|
"application/json": components["schemas"]["ApiError"];
|
|
2814
3457
|
};
|
|
2815
3458
|
};
|
|
2816
|
-
/** @description The `dpdp_mobile_api_enabled` flag is off. */
|
|
2817
|
-
404: {
|
|
2818
|
-
headers: {
|
|
2819
|
-
[name: string]: unknown;
|
|
2820
|
-
};
|
|
2821
|
-
content: {
|
|
2822
|
-
"application/json": components["schemas"]["ApiError"];
|
|
2823
|
-
};
|
|
2824
|
-
};
|
|
2825
3459
|
};
|
|
2826
3460
|
};
|
|
2827
3461
|
staffRespondToGrievance: {
|
|
@@ -2874,4 +3508,151 @@ export interface operations {
|
|
|
2874
3508
|
};
|
|
2875
3509
|
};
|
|
2876
3510
|
};
|
|
3511
|
+
ingestObservatoryObservations: {
|
|
3512
|
+
parameters: {
|
|
3513
|
+
query?: never;
|
|
3514
|
+
header?: never;
|
|
3515
|
+
path?: never;
|
|
3516
|
+
cookie?: never;
|
|
3517
|
+
};
|
|
3518
|
+
requestBody: {
|
|
3519
|
+
content: {
|
|
3520
|
+
"application/json": {
|
|
3521
|
+
batch: components["schemas"]["ObservatoryObservation"][];
|
|
3522
|
+
};
|
|
3523
|
+
};
|
|
3524
|
+
};
|
|
3525
|
+
responses: {
|
|
3526
|
+
/** @description Per-observation results. A 202 does **not** mean every observation was accepted — inspect `rejected`. */
|
|
3527
|
+
202: {
|
|
3528
|
+
headers: {
|
|
3529
|
+
[name: string]: unknown;
|
|
3530
|
+
};
|
|
3531
|
+
content: {
|
|
3532
|
+
"application/json": {
|
|
3533
|
+
accepted: number;
|
|
3534
|
+
rejected: {
|
|
3535
|
+
index: number;
|
|
3536
|
+
reason: string;
|
|
3537
|
+
}[];
|
|
3538
|
+
};
|
|
3539
|
+
};
|
|
3540
|
+
};
|
|
3541
|
+
/** @description Malformed body, missing `batch`, or an empty batch. */
|
|
3542
|
+
400: {
|
|
3543
|
+
headers: {
|
|
3544
|
+
[name: string]: unknown;
|
|
3545
|
+
};
|
|
3546
|
+
content: {
|
|
3547
|
+
"application/json": components["schemas"]["ApiError"];
|
|
3548
|
+
};
|
|
3549
|
+
};
|
|
3550
|
+
/** @description More than 50 observations, or the body exceeds 256KB. */
|
|
3551
|
+
413: {
|
|
3552
|
+
headers: {
|
|
3553
|
+
[name: string]: unknown;
|
|
3554
|
+
};
|
|
3555
|
+
content: {
|
|
3556
|
+
"application/json": components["schemas"]["ApiError"];
|
|
3557
|
+
};
|
|
3558
|
+
};
|
|
3559
|
+
};
|
|
3560
|
+
};
|
|
3561
|
+
getObservatoryDomainVerdict: {
|
|
3562
|
+
parameters: {
|
|
3563
|
+
query?: never;
|
|
3564
|
+
header?: never;
|
|
3565
|
+
path: {
|
|
3566
|
+
/** @description The domain to look up, e.g. `example.com`. */
|
|
3567
|
+
domain: string;
|
|
3568
|
+
};
|
|
3569
|
+
cookie?: never;
|
|
3570
|
+
};
|
|
3571
|
+
requestBody?: never;
|
|
3572
|
+
responses: {
|
|
3573
|
+
/** @description The domain's published verdict. */
|
|
3574
|
+
200: {
|
|
3575
|
+
headers: {
|
|
3576
|
+
[name: string]: unknown;
|
|
3577
|
+
};
|
|
3578
|
+
content: {
|
|
3579
|
+
"application/json": components["schemas"]["ObservatoryDomainVerdict"];
|
|
3580
|
+
};
|
|
3581
|
+
};
|
|
3582
|
+
/** @description No published verdict for this domain, or the `domain` path segment is missing. */
|
|
3583
|
+
404: {
|
|
3584
|
+
headers: {
|
|
3585
|
+
[name: string]: unknown;
|
|
3586
|
+
};
|
|
3587
|
+
content: {
|
|
3588
|
+
"application/json": components["schemas"]["ApiError"];
|
|
3589
|
+
};
|
|
3590
|
+
};
|
|
3591
|
+
};
|
|
3592
|
+
};
|
|
3593
|
+
getObservatorySectorReport: {
|
|
3594
|
+
parameters: {
|
|
3595
|
+
query?: never;
|
|
3596
|
+
header?: never;
|
|
3597
|
+
path: {
|
|
3598
|
+
sector: "ecommerce" | "bfsi" | "healthtech" | "edtech" | "travel" | "media" | "gov_adjacent";
|
|
3599
|
+
};
|
|
3600
|
+
cookie?: never;
|
|
3601
|
+
};
|
|
3602
|
+
requestBody?: never;
|
|
3603
|
+
responses: {
|
|
3604
|
+
/** @description CSV with header `sector,cohortSize,averageScore,grade,count` — one row per grade in the sector's distribution. */
|
|
3605
|
+
200: {
|
|
3606
|
+
headers: {
|
|
3607
|
+
[name: string]: unknown;
|
|
3608
|
+
};
|
|
3609
|
+
content: {
|
|
3610
|
+
"text/csv": string;
|
|
3611
|
+
};
|
|
3612
|
+
};
|
|
3613
|
+
/** @description `sector` is not a recognized sector. */
|
|
3614
|
+
404: {
|
|
3615
|
+
headers: {
|
|
3616
|
+
[name: string]: unknown;
|
|
3617
|
+
};
|
|
3618
|
+
content: {
|
|
3619
|
+
"application/json": components["schemas"]["ApiError"];
|
|
3620
|
+
};
|
|
3621
|
+
};
|
|
3622
|
+
};
|
|
3623
|
+
};
|
|
3624
|
+
deleteObservatoryContributions: {
|
|
3625
|
+
parameters: {
|
|
3626
|
+
query?: never;
|
|
3627
|
+
header?: never;
|
|
3628
|
+
path: {
|
|
3629
|
+
/** @description The extension-local, salted contributor hash to erase. */
|
|
3630
|
+
contributorHash: string;
|
|
3631
|
+
};
|
|
3632
|
+
cookie?: never;
|
|
3633
|
+
};
|
|
3634
|
+
requestBody?: never;
|
|
3635
|
+
responses: {
|
|
3636
|
+
/** @description Every observation for this hash has been deleted (or there were none). */
|
|
3637
|
+
200: {
|
|
3638
|
+
headers: {
|
|
3639
|
+
[name: string]: unknown;
|
|
3640
|
+
};
|
|
3641
|
+
content: {
|
|
3642
|
+
"application/json": {
|
|
3643
|
+
deleted: boolean;
|
|
3644
|
+
};
|
|
3645
|
+
};
|
|
3646
|
+
};
|
|
3647
|
+
/** @description The `contributorHash` path segment is missing or malformed. */
|
|
3648
|
+
404: {
|
|
3649
|
+
headers: {
|
|
3650
|
+
[name: string]: unknown;
|
|
3651
|
+
};
|
|
3652
|
+
content: {
|
|
3653
|
+
"application/json": components["schemas"]["ApiError"];
|
|
3654
|
+
};
|
|
3655
|
+
};
|
|
3656
|
+
};
|
|
3657
|
+
};
|
|
2877
3658
|
}
|