@dossier-wiki/os-sdk 0.7.0 → 1.4.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/types.d.ts CHANGED
@@ -17,14 +17,71 @@ export interface TagValueInput {
17
17
  label: string;
18
18
  value?: string;
19
19
  }
20
- /** The eight catalogue-governed tag field-keys. */
21
- export type TagFieldKey = 'customer.tags' | 'customer.riskTags' | 'counterparty.tags' | 'counterparty.riskTags' | 'alert.dispositionTags' | 'address.tags' | 'rule.tags' | 'identificationDocument.tags';
22
- export type TagCatalogueEnforcement = 'open' | 'strict';
20
+ /** The catalogue-governed tag field-keys. */
21
+ export type TagFieldKey = 'customer.tags' | 'customer.riskTags' | 'counterparty.tags' | 'counterparty.riskTags' | 'alert.dispositionTags' | 'product.tags' | 'address.tags' | 'rule.tags' | 'identificationDocument.tags' | 'customScreeningList.tags' | 'team.tags' | 'channelEndpoint.tags' | 'channelEndpoint.riskTags' | 'institution.riskTags';
22
+ /** How many tags from one group a single record may carry. */
23
+ export type TagGroupCardinality = 'SINGLE' | 'MULTI';
24
+ /**
25
+ * A tag group — the facet ("Occupation", "Primary Branch") that owns a slice of
26
+ * one field-key's vocabulary. Its `value` is the namespace its member tags
27
+ * carry: `primary-branch:kandy`.
28
+ */
29
+ export interface TagGroup {
30
+ id: string;
31
+ fieldKey: TagFieldKey;
32
+ /** Namespace slug. Never contains ':'. */
33
+ value: string;
34
+ label: string;
35
+ description?: string | null;
36
+ color?: string | null;
37
+ cardinality: TagGroupCardinality;
38
+ sortOrder: number;
39
+ archivedAt?: string | null;
40
+ createdAt: string;
41
+ updatedAt: string;
42
+ }
43
+ export interface TagGroupInput {
44
+ fieldKey: TagFieldKey;
45
+ label: string;
46
+ /** Namespace slug. Derived from label when omitted. May not contain ':'. */
47
+ value?: string;
48
+ description?: string;
49
+ color?: string;
50
+ cardinality?: TagGroupCardinality;
51
+ sortOrder?: number;
52
+ }
53
+ /** `fieldKey`/`value` are absent by design — see `regroup` for why. */
54
+ export interface UpdateTagGroupInput {
55
+ label?: string;
56
+ description?: string;
57
+ color?: string;
58
+ /** Tightening to SINGLE is rejected while records hold more than one member tag. */
59
+ cardinality?: TagGroupCardinality;
60
+ sortOrder?: number;
61
+ }
62
+ /** What a regroup did, or (dryRun) exactly what it would do. */
63
+ export interface RegroupReport {
64
+ dryRun: boolean;
65
+ entriesMoved: number;
66
+ assignmentsRewritten: number;
67
+ rulesRewritten: number;
68
+ assignmentPoliciesRewritten: number;
69
+ moves: {
70
+ label: string;
71
+ from: string;
72
+ to: string;
73
+ }[];
74
+ }
23
75
  export interface TagCatalogueEntry {
24
76
  id: string;
25
77
  fieldKey: TagFieldKey;
78
+ /** Namespaced (`primary-branch:kandy`) when the entry belongs to a group. */
26
79
  value: string;
27
80
  label: string;
81
+ /** Owning group id, or null when ungrouped. */
82
+ groupId?: string | null;
83
+ /** Namespace prefix of `value` — the owning group's slug, or null. */
84
+ groupValue?: string | null;
28
85
  color?: string | null;
29
86
  description?: string | null;
30
87
  archivedAt?: string | null;
@@ -34,7 +91,10 @@ export interface TagCatalogueEntry {
34
91
  export interface TagCatalogueEntryInput {
35
92
  fieldKey: TagFieldKey;
36
93
  label: string;
94
+ /** Unqualified slug. May not contain ':' — join a group via `groupId`. */
37
95
  value?: string;
96
+ /** Owning group. The server composes the namespaced stored value. */
97
+ groupId?: string;
38
98
  color?: string;
39
99
  description?: string;
40
100
  }
@@ -43,20 +103,16 @@ export interface UpdateTagCatalogueEntryInput {
43
103
  color?: string;
44
104
  description?: string;
45
105
  }
46
- export interface TagFieldEnforcement {
47
- fieldKey: TagFieldKey;
48
- enforcement: TagCatalogueEnforcement;
49
- }
50
- export interface SetTagEnforcementInput {
51
- fieldKey: TagFieldKey;
52
- enforcement: TagCatalogueEnforcement;
53
- }
54
- export type TypedFieldType = 'TEXT' | 'NUMBER' | 'BOOLEAN' | 'DATE' | 'SET' | 'CURRENCY' | 'MONETARY';
55
- /** Schema declaration carried on a parent resource (e.g. `Product.typedAccountFieldConfig`). */
106
+ export type TypedFieldType = 'TEXT' | 'NUMBER' | 'BOOLEAN' | 'DATE' | 'LIST' | 'SINGLE_SELECT' | 'MULTI_SELECT'
107
+ /** @deprecated Use LIST, SINGLE_SELECT, or MULTI_SELECT. */
108
+ | 'SET' | 'CURRENCY' | 'MONETARY';
109
+ /** Schema declaration carried on a parent resource (e.g. `Product.accountFieldConfig`). */
56
110
  export interface TypedFieldDefinition {
57
111
  key: string;
58
112
  displayName: string;
59
113
  type: TypedFieldType;
114
+ /** Required closed vocabulary for SINGLE_SELECT and MULTI_SELECT. */
115
+ options?: string[] | null;
60
116
  required: boolean;
61
117
  /** Default applied at write time when the caller omits the key. Raw value, validated against `type`. */
62
118
  defaultValue?: unknown;
@@ -68,7 +124,8 @@ export interface TypedFieldDefinition {
68
124
  * - TEXT / DATE / CURRENCY → string
69
125
  * - NUMBER → finite JS number
70
126
  * - BOOLEAN → boolean
71
- * - SET → string[]
127
+ * - LIST / MULTI_SELECT / legacy SET → string[]
128
+ * - SINGLE_SELECT → one string from the definition's options
72
129
  * - MONETARY → denominated literal `"<amount>@<TYPE:CODE>"`, e.g. `"50000.00@FIAT:USD"`
73
130
  */
74
131
  export interface TypedFieldValueInput {
@@ -102,6 +159,20 @@ export type TypedFieldStored = {
102
159
  type: 'date';
103
160
  value: string;
104
161
  } | {
162
+ key: string;
163
+ type: 'list';
164
+ value: string[];
165
+ } | {
166
+ key: string;
167
+ type: 'single_select';
168
+ value: string;
169
+ } | {
170
+ key: string;
171
+ type: 'multi_select';
172
+ value: string[];
173
+ }
174
+ /** @deprecated Legacy open list. */
175
+ | {
105
176
  key: string;
106
177
  type: 'set';
107
178
  value: string[];
@@ -127,8 +198,9 @@ export interface AccountResponseDto {
127
198
  productId?: string;
128
199
  label: string;
129
200
  accountCategory: 'DEPOSIT' | 'CREDIT' | 'LOAN' | 'WALLET' | 'SECURITIES' | 'OTHER';
201
+ /** @deprecated Retained for API compatibility. Prefer product tags for classification. */
130
202
  accountType: 'CHECKING' | 'SAVINGS' | 'OPERATING' | 'TRUST' | 'INVESTMENT' | 'ESCROW' | 'CREDIT_CARD' | 'LINE_OF_CREDIT' | 'PERSONAL_LOAN' | 'MORTGAGE' | 'AUTO_LOAN' | 'BUSINESS_LOAN' | 'CRYPTO_WALLET' | 'MOBILE_WALLET' | 'PREPAID_CARD' | 'E_WALLET' | 'BROKERAGE' | 'FUND' | 'OTHER';
131
- status: 'ACTIVE' | 'FROZEN' | 'CLOSED' | 'DORMANT';
203
+ status: 'PENDING' | 'ACTIVE' | 'FROZEN' | 'CLOSED' | 'DORMANT';
132
204
  currency?: string;
133
205
  /** Typed Field bag (Tier A). Validated against `Product.typedAccountFieldConfig`. */
134
206
  fields?: TypedFieldStored[];
@@ -156,8 +228,32 @@ export type AddressCategory = 'HOME' | 'MAILING' | 'BILLING' | 'WORK' | 'REGISTE
156
228
  export type Iso20022AddressType = 'BIZZ' | 'DLVY' | 'HOME' | 'MLTO' | 'PBOX' | 'ADDR';
157
229
  export type AddressVerificationStatus = 'PENDING' | 'VERIFIED' | 'REJECTED' | 'EXPIRED';
158
230
  export type Lifecycle = 'LIVE' | 'ARCHIVED' | 'TOMBSTONED';
231
+ /**
232
+ * A geographic point — the platform's one coordinate shape.
233
+ *
234
+ * A latitude without its longitude is not half a location. Everywhere the API
235
+ * carries a point it carries this: one value, one field.
236
+ */
237
+ export interface CoordinatesDto {
238
+ latitude: number;
239
+ longitude: number;
240
+ /** @deprecated The original spelling. Same number as `latitude`. */
241
+ lat?: number;
242
+ /** @deprecated The original spelling. Same number as `longitude`. */
243
+ lng?: number;
244
+ }
159
245
  export interface AddressCoordinatesDto {
246
+ /**
247
+ * The point.
248
+ *
249
+ * On a write this is the only accepted shape — a caller cannot send half a
250
+ * coordinate. On a read, `lat`/`lng` are still returned alongside it for
251
+ * consumers written against the original spelling.
252
+ */
253
+ point?: CoordinatesDto;
254
+ /** @deprecated Read-only. Use `point.latitude`. */
160
255
  lat?: number;
256
+ /** @deprecated Read-only. Use `point.longitude`. */
161
257
  lng?: number;
162
258
  /** Provenance, e.g. 'manual', 'google.geocode'. */
163
259
  source?: string;
@@ -167,8 +263,7 @@ export interface AddressCoordinatesDto {
167
263
  /**
168
264
  * Operational postal address. Lives in the polymorphic `addresses` table on the
169
265
  * server (owner = CUSTOMER / COUNTERPARTY / INSTITUTION). Exposed on the Customer
170
- * subtypes as `Individual.addresses` and `Entity.locations` — same shape, different
171
- * semantic field name.
266
+ * subtypes as `Individual.addresses` and `Entity.addresses` — same shape.
172
267
  *
173
268
  * Categories (semantic) and `iso20022Type` (wire-protocol) are parallel
174
269
  * discriminators; customer rows use `category`, counterparty/institution rows
@@ -318,10 +413,30 @@ export interface CashDetailsDto {
318
413
  export interface ChannelDto {
319
414
  /** Channel type (WEB, MOBILE_APP, BRANCH, ATM, POS, API). */
320
415
  type: string;
416
+ /** Stable identifier for the concrete endpoint, such as a POS terminal, ATM, API client, or web page. */
417
+ identifier?: string;
418
+ /** Integration/provider namespace. Identical identifiers from different providers resolve independently. */
419
+ provider?: string;
420
+ /** Human-readable endpoint name used when it is first observed. */
421
+ displayName?: string;
321
422
  /** Session identifier. */
322
423
  sessionId?: string;
323
424
  /** Embedded session events (auth, copy-paste, form-fill, etc.). */
324
425
  events?: ChannelEventDto[];
426
+ /** Physical endpoint location, distinct from the device location. */
427
+ physicalLocation?: LocationObservationDto;
428
+ /** Bounded integration-defined values. Credential-like keys are rejected by the API. */
429
+ context?: Record<string, string | number | boolean | null>;
430
+ }
431
+ export interface LocationObservationDto {
432
+ latitude: number;
433
+ longitude: number;
434
+ accuracyMeters?: number;
435
+ confidence?: number;
436
+ source?: string;
437
+ method?: string;
438
+ isEstimated?: boolean;
439
+ observedAt?: string;
325
440
  }
326
441
  export interface ChannelEventDto {
327
442
  /** Event type (e.g. session.auth, session.copy_paste). */
@@ -413,6 +528,8 @@ export interface CounterpartyPayloadDto {
413
528
  }
414
529
  export interface CounterpartyResponseDto {
415
530
  id: string;
531
+ /** Set when this counterparty was merged away; the id of the survivor. */
532
+ mergedIntoId?: string | null;
416
533
  externalId?: string;
417
534
  name: string;
418
535
  description?: string;
@@ -446,8 +563,9 @@ export interface CreateAccountDto {
446
563
  externalId?: string;
447
564
  /**
448
565
  * Product this account is instantiated from. Determines `accountCategory`
449
- * / `accountType` and the required typed-field schema — those are NOT
450
- * accepted from the caller (Phase 3b).
566
+ * and the required typed-field schema. The deprecated `accountType`
567
+ * compatibility field is still derived from the product and is not
568
+ * accepted from the caller.
451
569
  */
452
570
  productId?: string;
453
571
  label: string;
@@ -469,14 +587,12 @@ export interface CreateApiKeyDto {
469
587
  scope: 'full_access' | 'evaluate_only';
470
588
  /** Expiration in seconds (default: 1 year) */
471
589
  expiresInSeconds?: number;
472
- /** Organization ID to scope this key to (defaults to active org) */
473
- organizationId?: string;
474
590
  }
475
591
  export interface CreateConstantDto {
476
592
  /** Constant name (e.g. $global.highRiskCountries). */
477
593
  name: string;
478
594
  /** Scope (derived from name if omitted). */
479
- scope?: 'global' | 'product' | 'customer' | 'account' | 'counterparty' | 'instrument' | 'device';
595
+ scope?: 'global' | 'product' | 'customer' | 'account' | 'counterparty' | 'paymentInstrument' | 'device';
480
596
  /** Constant type. Determines the required shape of `value`. */
481
597
  type: 'scalar' | 'monetary' | 'set' | 'range' | 'text' | 'number' | 'boolean' | 'date' | 'currency' | 'regex';
482
598
  /** Payload shape depends on the constant's `type`. Pick the matching variant below. Validated at write time. */
@@ -495,6 +611,65 @@ export interface CreateConstantDto {
495
611
  description?: string;
496
612
  /** Sync key for config-as-code management. */
497
613
  syncKey?: string;
614
+ /** Product id for a product-bound `$account.*` definition. */
615
+ productId?: string;
616
+ }
617
+ export type StateScope = 'customer' | 'account' | 'counterparty' | 'product' | 'paymentInstrument' | 'device';
618
+ export type StateResourceType = 'CUSTOMER' | 'ACCOUNT' | 'COUNTERPARTY' | 'PRODUCT' | 'PAYMENT_INSTRUMENT' | 'DEVICE';
619
+ export type StateType = 'text' | 'number' | 'boolean' | 'date' | 'currency' | 'monetary' | 'set';
620
+ export type StateOperation = 'SET' | 'INCREMENT' | 'DECREMENT';
621
+ export interface CreateStateDefinitionInput {
622
+ name: string;
623
+ scope: StateScope;
624
+ type: StateType;
625
+ initialValue?: unknown;
626
+ description?: string;
627
+ /** Only valid for account-scoped definitions. */
628
+ productId?: string;
629
+ }
630
+ export interface StateDefinitionDto extends Omit<CreateStateDefinitionInput, 'productId'> {
631
+ id: string;
632
+ productId: string | null;
633
+ createdAt: string;
634
+ updatedAt: string;
635
+ }
636
+ export interface ChangeResourceStateInput {
637
+ resourceType: StateResourceType;
638
+ resourceId: string;
639
+ name: string;
640
+ operation: StateOperation;
641
+ /** Replacement value for SET; magnitude for INCREMENT or DECREMENT. */
642
+ value: unknown;
643
+ reason?: string;
644
+ }
645
+ export interface ResourceStateDto {
646
+ id: string;
647
+ resourceType: StateResourceType;
648
+ resourceId: string;
649
+ name: string;
650
+ type: StateType;
651
+ value: unknown;
652
+ updatedByActorType: string;
653
+ updatedByActorId: string;
654
+ reason: string | null;
655
+ createdAt: string;
656
+ updatedAt: string;
657
+ }
658
+ export interface ResourceStateHistoryDto {
659
+ id: string;
660
+ resourceStateId: string;
661
+ resourceType: StateResourceType;
662
+ resourceId: string;
663
+ name: string;
664
+ type: StateType;
665
+ operation: StateOperation;
666
+ operand: unknown | null;
667
+ previousValue: unknown | null;
668
+ newValue: unknown;
669
+ actorType: string;
670
+ actorId: string;
671
+ reason: string | null;
672
+ changedAt: string;
498
673
  }
499
674
  export interface CreateCounterpartyDto {
500
675
  externalId?: string;
@@ -504,33 +679,152 @@ export interface CreateCounterpartyDto {
504
679
  classification: 'BANK_ACCOUNT' | 'WALLET' | 'MERCHANT' | 'FINANCIAL_INSTITUTION' | 'PAYMENT_NETWORK' | 'UNKNOWN';
505
680
  /** ISO 3166-1 alpha-3 country code */
506
681
  country?: string;
682
+ /**
683
+ * Catalogue-governed tags (e.g. operating branch), stamped at creation so
684
+ * the INITIAL screening run — and any assignment-policy tag routing —
685
+ * sees them. Values not in the catalogue are rejected.
686
+ */
687
+ tags?: TagValueInput[];
507
688
  bankAccount?: BankAccountDetailsDto;
508
689
  wallet?: CryptoWalletDetailsDto;
509
690
  merchant?: MerchantDetailsDto;
510
691
  institution?: InstitutionDetailsDto;
511
692
  }
512
- /** OpenAPI schema is empty; treated as an opaque key/value bag — narrow on the caller side. */
513
- export type CreateCurrencyInput = Record<string, unknown>;
514
- export interface CreateEntityDto {
693
+ /** Currency classification. Mirrors the backend `CurrencyType` enum. */
694
+ export type CurrencyType = 'FIAT' | 'CRYPTO' | 'OTHER';
695
+ /** Product/account category. Mirrors the backend `AccountCategory` enum. */
696
+ export type AccountCategory = 'DEPOSIT' | 'CREDIT' | 'LOAN' | 'WALLET' | 'SECURITIES' | 'OTHER';
697
+ /** Base account type. Mirrors the backend `AccountType` enum. */
698
+ export type AccountType = 'CHECKING' | 'SAVINGS' | 'OPERATING' | 'TRUST' | 'INVESTMENT' | 'ESCROW' | 'CREDIT_CARD' | 'LINE_OF_CREDIT' | 'PERSONAL_LOAN' | 'MORTGAGE' | 'AUTO_LOAN' | 'BUSINESS_LOAN' | 'CRYPTO_WALLET' | 'MOBILE_WALLET' | 'PREPAID_CARD' | 'E_WALLET' | 'BROKERAGE' | 'FUND' | 'OTHER';
699
+ /** Product lifecycle status. Mirrors the backend `ProductStatus` enum. */
700
+ export type ProductStatus = 'ACTIVE' | 'DISCONTINUED';
701
+ export interface CreateCurrencyInput {
702
+ type: CurrencyType;
703
+ code: string;
704
+ /** Number of minor-unit decimal places (0–18). */
705
+ precision: number;
706
+ name: string;
707
+ symbol?: string;
708
+ }
709
+ export interface ContactEntryInput {
710
+ value: string;
711
+ primary: boolean;
712
+ }
713
+ /** Identification document embedded in an individual-create request. */
714
+ export interface InlineIdentificationDocumentInput {
715
+ id?: string;
716
+ type: string;
717
+ number: string;
718
+ /** ISO 3166-1 alpha-3 country code. */
719
+ country: string;
720
+ /** @deprecated Alias for `country`, honoured only when `country` is absent. */
721
+ issuingCountry?: string;
722
+ expiryDate?: string;
723
+ dateOfIssue?: string;
724
+ fullNameEn?: string;
725
+ transliterationNames?: string[];
726
+ addresses?: RichAddressInputDto[];
727
+ dateOfBirth?: string;
728
+ sex?: string;
729
+ other?: Record<string, unknown>;
730
+ notes?: string;
731
+ attachments?: IdDocFileAttachmentInput[];
732
+ /** @deprecated Use `attachments` instead. */
733
+ fileIds?: string[];
734
+ }
735
+ /** Canonical REST/GraphQL entity-create request. */
736
+ export interface CreateEntityInput {
515
737
  /** Your external identifier for this entity. Must be unique within the organization. */
516
738
  externalId: string;
517
739
  legalName: string;
740
+ status?: CustomerStatus;
518
741
  tradingNames?: string[];
519
742
  registrationNumber?: string;
743
+ /** Tax Identification Number (TIN). */
744
+ taxId?: string;
520
745
  /** ISO 3166-1 alpha-3 country code */
521
746
  countryOfIncorporation?: string;
522
747
  dateOfIncorporation?: string;
523
748
  entityType?: string;
524
- /** Parent entity ID for subsidiaries */
525
- parentEntityId?: string;
526
- email?: string;
527
- phone?: string;
749
+ websites?: string[];
750
+ stakeholders?: StakeholderInput[];
528
751
  /** Inline fan-out into the polymorphic `addresses` table. Same shape as
529
- * Individual.addresses; field is named `locations` to match the read-side
530
- * GraphQL field for entities. */
752
+ * Individual.addresses; named `locations` on entities. */
531
753
  locations?: AddressInputDto[];
532
- /** Override creation timestamp (ISO 8601). Used by data-loading tools to backfill historical entities. */
754
+ /**
755
+ * Catalogue-governed tags (e.g. operating branch), stamped at creation so
756
+ * the INITIAL screening run — and any assignment-policy tag routing —
757
+ * sees them. Values not in the catalogue are rejected.
758
+ */
759
+ tags?: TagValueInput[];
760
+ /**
761
+ * Standing assignment (user ids), stamped at creation so INITIAL screening
762
+ * and CUSTOMER_ASSIGNEE routing see it. Post-create edits via
763
+ * `customers.assignment.assign`.
764
+ */
765
+ assignedToUserIds?: string[];
766
+ /**
767
+ * Standing assignment (team ids), stamped at creation so INITIAL screening
768
+ * and CUSTOMER_ASSIGNEE routing see it. Post-create edits via
769
+ * `customers.assignment.assign`.
770
+ */
771
+ assignedToTeamIds?: string[];
772
+ /** @deprecated Use `emails`. Honoured only when `emails` is absent. */
773
+ email?: string;
774
+ /** @deprecated Use `phones`. Honoured only when `phones` is absent. */
775
+ phone?: string;
776
+ /** Override the creation timestamp (ISO 8601). For data-loading tools backfilling historical records. */
533
777
  createdAt?: string;
778
+ /** @deprecated Alias for `locations`, honoured only when `locations` is absent. */
779
+ addresses?: AddressInputDto[];
780
+ /** Parent entity for subsidiaries. */
781
+ parentEntityId?: string;
782
+ }
783
+ /** @deprecated Use `CreateEntityInput`. */
784
+ export type CreateEntityDto = CreateEntityInput;
785
+ /**
786
+ * A Risk Signal to emit on every valid occurrence of an event.
787
+ *
788
+ * Tenant configuration: an integration pushing an event cannot add, change, or
789
+ * suppress an effect. `weight` and `halfLife` are snapshotted onto each emitted
790
+ * signal, so editing the definition later never rewrites signals already
791
+ * recorded.
792
+ */
793
+ export interface RiskSignalEffect {
794
+ /** Dotted signal type to emit, e.g. `authentication.password_change_attempt`. */
795
+ type: string;
796
+ /** Strength at the event timestamp. Must be greater than zero. */
797
+ weight: number;
798
+ /**
799
+ * Positive ISO 8601 duration, e.g. `P3D`. Calendar units (Y/M) are
800
+ * rejected — they have no fixed length.
801
+ */
802
+ halfLife: string;
803
+ /**
804
+ * Defaults to `EVENT_RESOURCE` — the signal attaches to the event's own
805
+ * primary resource.
806
+ */
807
+ target?: 'EVENT_RESOURCE';
808
+ }
809
+ /** What a declared resource is to the event. */
810
+ export type EventResourceRole = 'SUBJECT' | 'CONTEXT';
811
+ /** Every resource an Event Definition can name, in either role. */
812
+ export type EventDeclaredResource = 'CUSTOMER' | 'ACCOUNT' | 'COUNTERPARTY' | 'EMPLOYEE' | 'BRANCH' | 'PAYMENT_INSTRUMENT' | 'DEVICE' | 'SESSION' | 'TRANSACTION';
813
+ /**
814
+ * One resource an Event Definition names.
815
+ *
816
+ * `SUBJECT` entries enumerate the kinds an occurrence may be *about*; an
817
+ * occurrence names exactly one, so `required` carries no meaning there and the
818
+ * API normalises it to true. `CONTEXT` entries are the further resources it
819
+ * references, where `required` decides whether ingestion accepts an occurrence
820
+ * without one.
821
+ *
822
+ * `DEVICE`, `SESSION` and `TRANSACTION` are declarable as `CONTEXT` only.
823
+ */
824
+ export interface EventResourceDeclarationDto {
825
+ resource: EventDeclaredResource;
826
+ role: EventResourceRole;
827
+ required: boolean;
534
828
  }
535
829
  export interface CreateEventDefinitionDto {
536
830
  /** Unique event name (used as key). */
@@ -541,29 +835,67 @@ export interface CreateEventDefinitionDto {
541
835
  description?: string;
542
836
  /** Event category. */
543
837
  category?: string;
544
- /** Event properties schema. */
545
- properties?: Record<string, unknown>[];
838
+ /**
839
+ * Resources this event names, each as SUBJECT (what an occurrence is
840
+ * about) or CONTEXT (what it also references). Omit to accept any
841
+ * attachable subject and expect no context.
842
+ */
843
+ resources?: EventResourceDeclarationDto[];
844
+ /** Event property schema. Same shape as `TypedFieldDefinition` (including `options` for select types). */
845
+ properties?: TypedFieldDefinition[];
846
+ /** Risk Signals to emit on every valid occurrence of this event. */
847
+ riskSignalEffects?: RiskSignalEffect[];
546
848
  /** Sync key for config-as-code management. */
547
849
  syncKey?: string;
548
850
  }
549
- export interface CreateIndividualDto {
851
+ /** Canonical REST/GraphQL individual-create request. */
852
+ export interface CreateIndividualInput {
550
853
  /** Your external identifier for this customer. Must be unique within the organization. */
551
854
  externalId: string;
552
855
  fullName: string;
856
+ status?: CustomerStatus;
553
857
  preferredName?: string;
858
+ aliases?: string[];
554
859
  dateOfBirth?: string;
555
860
  /** ISO 3166-1 alpha-3 country codes */
556
861
  nationality?: string[];
557
862
  /** ISO 3166-1 alpha-3 country codes */
558
863
  countryOfResidence?: string[];
559
- email?: string;
560
- phone?: string;
561
- identificationDocuments?: IdentificationDocumentDto[];
864
+ /** Tax Identification Number (TIN). */
865
+ taxId?: string;
866
+ emails?: ContactEntryInput[];
867
+ phones?: ContactEntryInput[];
868
+ identificationDocuments?: InlineIdentificationDocumentInput[];
869
+ faceImageFileIds?: string[];
562
870
  /** Inline fan-out into the polymorphic `addresses` table. */
563
871
  addresses?: AddressInputDto[];
564
- /** Override creation timestamp (ISO 8601). Used by data-loading tools to backfill historical customers. */
872
+ /**
873
+ * Catalogue-governed tags (e.g. operating branch), stamped at creation so
874
+ * the INITIAL screening run — and any assignment-policy tag routing —
875
+ * sees them. Values not in the catalogue are rejected.
876
+ */
877
+ tags?: TagValueInput[];
878
+ /**
879
+ * Standing assignment (user ids), stamped at creation so INITIAL screening
880
+ * and CUSTOMER_ASSIGNEE routing see it. Post-create edits via
881
+ * `customers.assignment.assign`.
882
+ */
883
+ assignedToUserIds?: string[];
884
+ /**
885
+ * Standing assignment (team ids), stamped at creation so INITIAL screening
886
+ * and CUSTOMER_ASSIGNEE routing see it. Post-create edits via
887
+ * `customers.assignment.assign`.
888
+ */
889
+ assignedToTeamIds?: string[];
890
+ /** @deprecated Use `emails`. Honoured only when `emails` is absent. */
891
+ email?: string;
892
+ /** @deprecated Use `phones`. Honoured only when `phones` is absent. */
893
+ phone?: string;
894
+ /** Override the creation timestamp (ISO 8601). For data-loading tools backfilling historical records. */
565
895
  createdAt?: string;
566
896
  }
897
+ /** @deprecated Use `CreateIndividualInput`. */
898
+ export type CreateIndividualDto = CreateIndividualInput;
567
899
  export interface CreateNoteDto {
568
900
  /** Note text content */
569
901
  text: string;
@@ -576,19 +908,20 @@ export interface CreateProductDto {
576
908
  /** Product description. */
577
909
  description?: string;
578
910
  /** Account category. */
579
- category: string;
580
- /** Base account type. */
581
- baseType: string;
911
+ category: AccountCategory;
912
+ /** Preferred product classification, governed by the `product.tags` catalogue. */
913
+ tags?: TagValueInput[];
914
+ /** @deprecated Use `tags`. Omitted values are stored as `OTHER`. */
915
+ baseType?: AccountType;
582
916
  /** Default currency in TYPE:CODE format. */
583
917
  defaultCurrency: string;
584
- /** ISO 3166-1 alpha-3 country code. */
918
+ /** @deprecated Use `tags` when product classification is needed. */
585
919
  country?: string;
586
920
  /** Supported transaction method IDs. */
587
921
  supportedMethodIds: string[];
588
- /**
589
- * Typed Field schema for accounts of this product (Tier A). Each entry is
590
- * a `TypedFieldDefinition`; validates `Account.fields` writes.
591
- */
922
+ /** Account field template for accounts created from this product. */
923
+ accountFieldConfig?: TypedFieldDefinition[];
924
+ /** @deprecated Use `accountFieldConfig`. */
592
925
  typedAccountFieldConfig?: TypedFieldDefinition[];
593
926
  /** Product-level typed bag (Tier B, self-declaring). */
594
927
  fields?: TypedFieldValueInput[];
@@ -597,6 +930,14 @@ export interface CreateProductDto {
597
930
  /** Sync key for config-as-code management. */
598
931
  syncKey?: string;
599
932
  }
933
+ /** Attachment metadata for a file already uploaded via the file-upload flow. */
934
+ export interface RiskAssessmentFileDto {
935
+ /** Uploaded file id (customer file id, or fileKey for platform uploads) */
936
+ id: string;
937
+ name: string;
938
+ /** File size in bytes */
939
+ size: number;
940
+ }
600
941
  export interface CreateRiskAssessmentDto {
601
942
  answers: RiskAssessmentAnswerDto[];
602
943
  resultingRiskRating: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
@@ -605,20 +946,87 @@ export interface CreateRiskAssessmentDto {
605
946
  overrideJustification?: string;
606
947
  narrative?: string;
607
948
  riskTags?: TagValueInput[];
949
+ files?: RiskAssessmentFileDto[];
608
950
  }
609
951
  export interface CreateCustomerRiskAssessmentDto {
610
952
  answers: CustomerRiskAssessmentAnswerDto[];
611
953
  /** Optional narrative summary */
612
954
  narrative?: string;
955
+ files?: RiskAssessmentFileDto[];
956
+ }
957
+ /**
958
+ * One action executed when a rule fires (spec v0 rules §8).
959
+ * `CREATE_ALERT` accepts an optional `severity` override
960
+ * (CRITICAL/HIGH/MEDIUM/LOW) plus `assignToTeamIds` / `assignToUserIds`;
961
+ * `SEND_WEBHOOK` references a configured webhook destination by `webhookId`;
962
+ * `FLAG_ENTITY` requires `entityType` + `flagType`; `TAG_CUSTOMER` requires
963
+ * `tag`; `ESCALATE` accepts an optional raising `severity` (HIGH/CRITICAL);
964
+ * `ADD_RISK_SIGNAL` requires `signalType`, `weight`, `halfLife` and `target`.
965
+ * Non-webhook types may appear at most once per rule — duplicates are
966
+ * rejected with 400. `ADD_RISK_SIGNAL` is exempt (one rule may legitimately
967
+ * record several kinds of evidence, or the same evidence against several
968
+ * resources); what it rejects is the same `signalType` on the same
969
+ * `target.resource` twice, which would double-count in every aggregate.
970
+ */
971
+ export interface RuleAction {
972
+ type: 'CREATE_ALERT' | 'SEND_WEBHOOK' | 'FLAG_ENTITY' | 'TAG_CUSTOMER' | 'BLOCK_TRANSACTION' | 'FREEZE_ACCOUNT' | 'ADD_RISK_SIGNAL' | 'ASSIGN_FOR_REVIEW' | 'ESCALATE';
973
+ /** CREATE_ALERT: alert risk level override (defaults to the rule
974
+ * severity). ESCALATE: HIGH or CRITICAL only. */
975
+ severity?: 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW';
976
+ /** CREATE_ALERT: better-auth team ids assigned to the alert on creation. */
977
+ assignToTeamIds?: string[];
978
+ /** CREATE_ALERT: user ids assigned to the alert on creation. */
979
+ assignToUserIds?: string[];
980
+ /** SEND_WEBHOOK: configured webhook destination id. */
981
+ webhookId?: string;
982
+ /** FLAG_ENTITY: which entity the flag lands on (required). */
983
+ entityType?: 'TRANSACTION' | 'CUSTOMER' | 'ACCOUNT';
984
+ /** FLAG_ENTITY: tenant-meaningful flag label, e.g. REVIEW_REQUIRED (required). */
985
+ flagType?: string;
986
+ /** TAG_CUSTOMER: tag appended to the customer record (required). */
987
+ tag?: string;
988
+ /**
989
+ * ADD_RISK_SIGNAL: dotted signal type to record (required). Tenant
990
+ * vocabulary — not a fixed platform enum.
991
+ */
992
+ signalType?: string;
993
+ /**
994
+ * ADD_RISK_SIGNAL: strength at the moment the rule fires (required, > 0).
995
+ * Snapshotted onto every signal the action emits.
996
+ */
997
+ weight?: number;
998
+ /**
999
+ * ADD_RISK_SIGNAL: positive ISO 8601 duration (required), e.g. `P7D`.
1000
+ * Calendar units (Y/M) are rejected — they have no fixed length.
1001
+ */
1002
+ halfLife?: string;
1003
+ /**
1004
+ * ADD_RISK_SIGNAL: which resource in the evaluation the signal attaches to
1005
+ * (required). A closed selector, never a field expression.
1006
+ *
1007
+ * `employee` and `branch` are **not** valid selectors: no evaluation
1008
+ * envelope resolves either slot yet, so a rule targeting one could never
1009
+ * fire. Both are rejected at save time with a 400 explaining why.
1010
+ */
1011
+ target?: {
1012
+ resource: 'customer' | 'account' | 'counterparty' | 'paymentInstrument';
1013
+ };
1014
+ [key: string]: unknown;
613
1015
  }
614
1016
  export interface CreateRuleDto {
615
1017
  /** Rule name. */
616
1018
  name: string;
617
1019
  /** Rule description. */
618
1020
  description?: string;
619
- /** Rule subject. */
1021
+ /** Rule subject: 'TRANSACTION' | 'EVENT' | 'CUSTOMER' | 'ALL'. */
620
1022
  subject: string;
621
- /** Rule trigger. */
1023
+ /**
1024
+ * Rule trigger — the event type that causes evaluation. Core triggers:
1025
+ * `transaction.*` (subject TRANSACTION), `customer.*` / `account.*`
1026
+ * (subject EVENT). Custom triggers use `custom.{slug}` and must name an
1027
+ * ACTIVE event definition (Event Definitions API). `'*'` fires on all
1028
+ * events in the subject's scope. Invalid pairs are rejected with 400.
1029
+ */
622
1030
  trigger?: string;
623
1031
  /** Rule severity. */
624
1032
  severity: 'HIGH' | 'MEDIUM' | 'LOW';
@@ -627,15 +1035,19 @@ export interface CreateRuleDto {
627
1035
  /** Condition tree (AND/OR logic with leaf conditions). */
628
1036
  conditionTree?: Record<string, unknown>;
629
1037
  /** Actions to execute when the rule triggers. */
630
- actions?: string[];
1038
+ actions?: RuleAction[];
631
1039
  /** Window period for aggregate conditions. */
632
1040
  windowPeriod?: string;
633
1041
  /** Initial status for the rule. */
634
1042
  initialStatus?: 'DRAFT' | 'ACTIVE' | 'DISABLED';
635
1043
  /** Sync key for config-as-code management. */
636
1044
  syncKey?: string;
1045
+ /** Product applicability. Omit or empty products = unscoped. */
1046
+ scope?: {
1047
+ products?: string[];
1048
+ };
637
1049
  }
638
- export interface CreateStakeholderDto {
1050
+ export interface StakeholderInput {
639
1051
  name: string;
640
1052
  role: 'SHAREHOLDER' | 'UBO' | 'DIRECTOR';
641
1053
  /** Ownership percentage (0–100) */
@@ -648,6 +1060,8 @@ export interface CreateStakeholderDto {
648
1060
  /** Link to an existing Entity customer */
649
1061
  entityId?: string;
650
1062
  }
1063
+ /** @deprecated Use `StakeholderInput`. */
1064
+ export type CreateStakeholderDto = StakeholderInput;
651
1065
  export interface CreateWebhookDto {
652
1066
  /** Webhook destination name. */
653
1067
  name: string;
@@ -732,15 +1146,25 @@ export interface EntityResponseDto {
732
1146
  countryOfIncorporation?: string;
733
1147
  dateOfIncorporation?: string;
734
1148
  entityType?: string;
1149
+ /** Tax Identification Number (TIN). */
1150
+ taxId?: string;
735
1151
  parentEntityId?: string;
736
1152
  email?: string;
737
1153
  phone?: string;
738
1154
  riskRating: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
739
1155
  kycTier?: 'NO_KYC' | 'SDD' | 'CDD' | 'EDD' | 'ONGOING';
1156
+ /**
1157
+ * Standing assignment — the users/teams responsible for compliance work on
1158
+ * this customer. NOT ownership ("owner" here means UBO or account owner).
1159
+ * Read by the CUSTOMER_ASSIGNEE routing block, so a new alert can go to
1160
+ * whoever holds the customer.
1161
+ */
1162
+ assignedToUserIds?: string[];
1163
+ assignedToTeamIds?: string[];
740
1164
  alertCount: number;
741
1165
  /** Operational footprint (REGISTERED office, BRANCH, WAREHOUSE, …). Read-only here;
742
1166
  * use granular add/update/remove/verify/reject mutations on the addresses endpoint. */
743
- locations: AddressDto[];
1167
+ addresses: AddressDto[];
744
1168
  createdAt: string;
745
1169
  updatedAt: string;
746
1170
  }
@@ -779,14 +1203,28 @@ export interface IPSessionDto {
779
1203
  country?: string;
780
1204
  isVPN?: boolean;
781
1205
  vpnProvider?: string;
1206
+ asn?: string;
1207
+ networkName?: string;
1208
+ confidence?: number;
782
1209
  }
783
1210
  export interface IdentificationDocumentDto {
1211
+ id?: string;
784
1212
  /** Document type */
785
1213
  type: string;
786
1214
  number: string;
787
1215
  /** ISO 3166-1 alpha-3 country code */
788
- issuingCountry: string;
1216
+ country: string;
1217
+ /**
1218
+ * @deprecated Accepted on write as an alias for `country`, but never
1219
+ * returned — responses have always carried `country`. Read `country`.
1220
+ */
1221
+ issuingCountry?: string;
789
1222
  expiryDate?: string;
1223
+ dateOfIssue?: string;
1224
+ notes?: string;
1225
+ attachments?: AttachmentDto[];
1226
+ /** @deprecated Use `attachments`. */
1227
+ fileIds?: string[];
790
1228
  }
791
1229
  export type IdentificationDocumentStatus = 'PENDING' | 'APPROVED' | 'REJECTED';
792
1230
  /** Computed status — also reflects expiry and archive state. */
@@ -950,7 +1388,7 @@ export interface DeleteIdentificationDocumentResponse {
950
1388
  deletedId: string;
951
1389
  }
952
1390
  /** Resource types that can carry platform comments. */
953
- export type CommentResourceType = 'CUSTOMER' | 'ACCOUNT' | 'TRANSACTION' | 'TASK' | 'ALERT' | 'COMMENT' | 'COUNTERPARTY' | 'DEVICE' | 'RULE' | 'PRODUCT' | 'INSTRUMENT' | 'IDENTIFICATION_DOCUMENT';
1391
+ export type CommentResourceType = 'CUSTOMER' | 'ACCOUNT' | 'TRANSACTION' | 'TASK' | 'ALERT' | 'COMMENT' | 'COUNTERPARTY' | 'DEVICE' | 'RULE' | 'PRODUCT' | 'PAYMENT_INSTRUMENT' | 'IDENTIFICATION_DOCUMENT';
954
1392
  export interface PlatformCommentAttachmentInput {
955
1393
  /** fileId returned by /platform/v1/files/upload-url */
956
1394
  fileId: string;
@@ -962,7 +1400,12 @@ export interface PlatformCommentAttachment extends PlatformCommentAttachmentInpu
962
1400
  /** Short-lived presigned download URL (when resolved by the server). */
963
1401
  downloadUrl?: string;
964
1402
  }
1403
+ export interface CommentLinksInput {
1404
+ /** Screening matches attached to this comment. Empty removes all attachments; omitting links on update preserves them. */
1405
+ matchIds?: string[];
1406
+ }
965
1407
  export interface PlatformCreateCommentDto {
1408
+ links?: CommentLinksInput;
966
1409
  resourceType: CommentResourceType;
967
1410
  resourceId: string;
968
1411
  /** Markdown body (GFM tables supported). */
@@ -972,6 +1415,7 @@ export interface PlatformCreateCommentDto {
972
1415
  externalRequestId?: string;
973
1416
  }
974
1417
  export interface PlatformUpdateCommentDto {
1418
+ links?: CommentLinksInput;
975
1419
  /** Markdown body (GFM tables supported). */
976
1420
  body: string;
977
1421
  }
@@ -980,7 +1424,15 @@ export interface ListPlatformCommentsQuery {
980
1424
  resourceId: string;
981
1425
  }
982
1426
  /** Comment response shape — the OpenAPI spec does not document a full schema, so callers should narrow as needed. */
1427
+ /** Stable references to screening results, with labels retained after a rescreen. */
1428
+ export interface PlatformCommentMatchReference {
1429
+ matchId: string;
1430
+ name: string;
1431
+ category: 'WATCHLIST' | 'HIGH_RISK' | 'CUSTOM_LIST';
1432
+ }
983
1433
  export interface PlatformComment {
1434
+ /** Always present; empty when the comment references no screening result. */
1435
+ matchReferences: PlatformCommentMatchReference[];
984
1436
  id: string;
985
1437
  resourceType: CommentResourceType;
986
1438
  resourceId: string;
@@ -1038,10 +1490,20 @@ export interface IndividualResponseDto {
1038
1490
  dateOfBirth?: string;
1039
1491
  nationality?: string[];
1040
1492
  countryOfResidence?: string[];
1493
+ /** Tax Identification Number (TIN). */
1494
+ taxId?: string;
1041
1495
  email?: string;
1042
1496
  phone?: string;
1043
1497
  riskRating: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
1044
1498
  kycTier?: 'NO_KYC' | 'SDD' | 'CDD' | 'EDD' | 'ONGOING';
1499
+ /**
1500
+ * Standing assignment — the users/teams responsible for compliance work on
1501
+ * this customer. NOT ownership ("owner" here means UBO or account owner).
1502
+ * Read by the CUSTOMER_ASSIGNEE routing block, so a new alert can go to
1503
+ * whoever holds the customer.
1504
+ */
1505
+ assignedToUserIds?: string[];
1506
+ assignedToTeamIds?: string[];
1045
1507
  alertCount: number;
1046
1508
  identificationDocuments: IdentificationDocumentDto[];
1047
1509
  /** Postal addresses (HOME / MAILING / BILLING / WORK). Read-only here;
@@ -1066,14 +1528,54 @@ export interface IngestDevicePayloadDto {
1066
1528
  botProbability?: number;
1067
1529
  /** Detection confidence score (0-1). */
1068
1530
  confidence?: number;
1531
+ /** Device location observation. Multiple observations are retained over time. */
1532
+ location?: LocationObservationDto;
1533
+ }
1534
+ /** Resource an Event occurrence attaches to as its single primary subject. */
1535
+ export type EventResourceType = 'CUSTOMER' | 'ACCOUNT' | 'COUNTERPARTY' | 'EMPLOYEE' | 'BRANCH' | 'PAYMENT_INSTRUMENT';
1536
+ /** Resource a Risk Signal attaches to. */
1537
+ export type RiskSignalResourceType = 'CUSTOMER' | 'ACCOUNT' | 'COUNTERPARTY' | 'EMPLOYEE' | 'BRANCH' | 'PAYMENT_INSTRUMENT';
1538
+ /** The single resource an Event is about. Exactly one, always. */
1539
+ export interface EventResourceRef {
1540
+ type: EventResourceType;
1541
+ /** Id of the resource, which must already exist in your organization. */
1542
+ id: string;
1069
1543
  }
1070
1544
  export interface IngestEventDto {
1545
+ /**
1546
+ * Your unique identifier for this event (max 255 chars). Used for
1547
+ * idempotency: resubmitting the same eventId returns the original
1548
+ * stored event (`cached: true`) instead of creating a duplicate — safe
1549
+ * for client retries. Omit to skip deduplication.
1550
+ */
1551
+ eventId?: string;
1071
1552
  /** Event type (core or custom). Core types: customer.failed_login, customer.profile_updated. Custom types match event definitions. */
1072
1553
  type: string;
1073
1554
  /** When the event occurred. */
1074
1555
  timestamp: string;
1075
- /** Customer ID this event is associated with. */
1076
- customerId: string;
1556
+ /**
1557
+ * The single resource this event is about. Supply either `resource` or the
1558
+ * legacy top-level `customerId` — `resource` wins when both are present.
1559
+ * An event that names neither is rejected with 400.
1560
+ *
1561
+ * `deviceId` and `sessionId` may qualify an event but never substitute for
1562
+ * its primary resource.
1563
+ */
1564
+ resource?: EventResourceRef;
1565
+ /**
1566
+ * Customer this event relates to.
1567
+ *
1568
+ * Two roles: as the legacy attachment field it is exactly equivalent to
1569
+ * `resource: { type: 'CUSTOMER', id }`, and alongside a non-customer
1570
+ * `resource` it is context that customer-scoped event aggregates read.
1571
+ *
1572
+ * @deprecated `resource` is the contract. A bare `customerId` is still
1573
+ * accepted as the legacy spelling of `resource: { type: 'CUSTOMER', id }`,
1574
+ * but new integrations should send `resource` — it is the only way to
1575
+ * attach an event to an account, counterparty, employee, branch, or
1576
+ * payment instrument.
1577
+ */
1578
+ customerId?: string;
1077
1579
  /** Account ID if the event is account-scoped. */
1078
1580
  accountId?: string;
1079
1581
  /** Device identifier for device-context rules. */
@@ -1093,8 +1595,8 @@ export interface IngestTransactionDto {
1093
1595
  timestamp: string;
1094
1596
  /** The transaction payload. */
1095
1597
  transaction: TransactionBodyDto;
1096
- /** Payment instrument used for this transaction. */
1097
- instrument?: InstrumentPayloadDto;
1598
+ /** Canonical Payment Instrument identity or protected credential for deterministic create-on-miss resolution. */
1599
+ paymentInstrument?: PaymentInstrumentPayloadDto;
1098
1600
  /** Intermediary banks/institutions in the payment chain. */
1099
1601
  intermediaries?: IntermediaryDto[];
1100
1602
  /** Device / fingerprint data used for device-based rules and device-trust resolution. */
@@ -1102,6 +1604,169 @@ export interface IngestTransactionDto {
1102
1604
  /** Set to true for async processing. Returns 202 Accepted immediately; results delivered via webhook. */
1103
1605
  async?: boolean;
1104
1606
  }
1607
+ /** Why a payment operation failed to become a transaction in the source system. */
1608
+ export type TransactionAttemptOutcome = 'FAILED' | 'BLOCKED' | 'UNKNOWN';
1609
+ export interface TransactionAttemptOutcomeDto {
1610
+ type: TransactionAttemptOutcome;
1611
+ code?: string;
1612
+ reason?: string;
1613
+ /** System or provider that supplied the outcome. */
1614
+ source?: string;
1615
+ retryable?: boolean;
1616
+ /** Whether the integration considers this the final outcome for the operation. */
1617
+ final?: boolean;
1618
+ }
1619
+ export interface AttemptedAmountDto {
1620
+ /** Attempted value in the supplied currency's minor units. */
1621
+ amountMinor: number;
1622
+ /** Structured currency code, for example `FIAT:USD`. */
1623
+ currency: string;
1624
+ precision: number;
1625
+ }
1626
+ /**
1627
+ * Durable behavioural record for an operation that did not become a source
1628
+ * transaction. Snapshot objects must contain safe descriptors only—never PANs,
1629
+ * raw payment tokens, API keys, or unprotected device fingerprints.
1630
+ */
1631
+ export interface IngestTransactionAttemptDto {
1632
+ /** Tenant-scoped idempotency key. */
1633
+ attemptId: string;
1634
+ /** When the source system observed the attempt. */
1635
+ timestamp: string;
1636
+ /** Integration-defined payment operation, for example `CARD_AUTHORIZATION`. */
1637
+ operation: string;
1638
+ outcome: TransactionAttemptOutcomeDto;
1639
+ amount?: AttemptedAmountDto;
1640
+ direction?: 'IN' | 'OUT';
1641
+ mode?: Record<string, unknown>;
1642
+ channel?: Record<string, unknown>;
1643
+ authentication?: Record<string, unknown>;
1644
+ principalParty?: Record<string, unknown>;
1645
+ counterparty?: Record<string, unknown>;
1646
+ /** Lookup-only Payment Instrument reference. A miss never creates a Payment Instrument. */
1647
+ paymentInstrument?: AttemptPaymentInstrumentDto;
1648
+ device?: Record<string, unknown>;
1649
+ context?: Record<string, unknown>;
1650
+ }
1651
+ export interface IngestTransactionAttemptResponse {
1652
+ attemptId: string;
1653
+ /** Database record ID. */
1654
+ id: string;
1655
+ /** True when an identical tenant-scoped replay returned the existing record. */
1656
+ cached: boolean;
1657
+ observedAt: string;
1658
+ expiresAt: string;
1659
+ }
1660
+ export type AttemptCoverage = 'ALL' | 'SELECTIVE';
1661
+ /**
1662
+ * What event ingestion does with a type that has no Event Definition.
1663
+ * `ACCEPT` (the default) records it as history that links to no Definition and
1664
+ * emits no Risk Signals; `REJECT` fails the request instead.
1665
+ */
1666
+ export type UnknownEventTypePolicy = 'ACCEPT' | 'REJECT';
1667
+ export interface TenantBehaviorSettings {
1668
+ attemptRetentionDays: number;
1669
+ attemptCoverage: AttemptCoverage;
1670
+ unknownEventTypes: UnknownEventTypePolicy;
1671
+ }
1672
+ export interface UpdateTenantBehaviorSettingsInput {
1673
+ attemptRetentionDays?: number;
1674
+ attemptCoverage?: AttemptCoverage;
1675
+ unknownEventTypes?: UnknownEventTypePolicy;
1676
+ }
1677
+ export interface ListTransactionAttemptsInput {
1678
+ limit?: number;
1679
+ cursor?: string;
1680
+ outcomes?: TransactionAttemptOutcome[];
1681
+ operation?: string;
1682
+ observedFrom?: string;
1683
+ observedTo?: string;
1684
+ customerId?: string;
1685
+ accountId?: string;
1686
+ counterpartyId?: string;
1687
+ paymentInstrumentId?: string;
1688
+ deviceId?: string;
1689
+ sessionId?: string;
1690
+ channelEndpointId?: string;
1691
+ iin?: string;
1692
+ }
1693
+ /** Safe read projection. Protected request/fingerprint/IP hashes are never returned. */
1694
+ export interface TransactionAttemptDto {
1695
+ id: string;
1696
+ attemptId: string;
1697
+ observedAt: string;
1698
+ outcome: TransactionAttemptOutcome;
1699
+ outcomeCode?: string | null;
1700
+ outcomeReason?: string | null;
1701
+ outcomeSource?: string | null;
1702
+ retryable?: boolean | null;
1703
+ final: boolean;
1704
+ operation: string;
1705
+ mode?: Record<string, unknown> | null;
1706
+ channel?: Record<string, unknown> | null;
1707
+ authentication?: Record<string, unknown> | null;
1708
+ direction?: 'IN' | 'OUT' | null;
1709
+ originAmountMinor?: number | null;
1710
+ originCurrency?: string | null;
1711
+ originPrecision?: number | null;
1712
+ baseAmountMinor?: number | null;
1713
+ baseCurrency?: string | null;
1714
+ basePrecision?: number | null;
1715
+ customerId?: string | null;
1716
+ accountId?: string | null;
1717
+ counterpartyId?: string | null;
1718
+ paymentInstrumentId?: string | null;
1719
+ deviceId?: string | null;
1720
+ sessionId?: string | null;
1721
+ channelEndpointId?: string | null;
1722
+ iin?: string | null;
1723
+ countryCode?: string | null;
1724
+ principalParty?: Record<string, unknown> | null;
1725
+ counterparty?: Record<string, unknown> | null;
1726
+ paymentInstrument?: Record<string, unknown> | null;
1727
+ device?: Record<string, unknown> | null;
1728
+ context?: Record<string, unknown> | null;
1729
+ expiresAt: string;
1730
+ createdAt: string;
1731
+ }
1732
+ export interface TransactionAttemptPage {
1733
+ items: TransactionAttemptDto[];
1734
+ nextCursor?: string | null;
1735
+ }
1736
+ export interface ContributingAttemptFact {
1737
+ attemptId: string;
1738
+ observedAt: string;
1739
+ outcome?: string;
1740
+ operation?: string;
1741
+ customerId?: string | null;
1742
+ accountId?: string | null;
1743
+ counterpartyId?: string | null;
1744
+ paymentInstrumentId?: string | null;
1745
+ deviceId?: string | null;
1746
+ sessionId?: string | null;
1747
+ channelEndpointId?: string | null;
1748
+ originAmountMinor?: number | null;
1749
+ originCurrency?: string | null;
1750
+ originPrecision?: number | null;
1751
+ baseAmountMinor?: number | null;
1752
+ baseCurrency?: string | null;
1753
+ basePrecision?: number | null;
1754
+ iin?: string | null;
1755
+ countryCode?: string | null;
1756
+ ipLookupHash?: string | null;
1757
+ }
1758
+ export interface AlertAttemptEvidence {
1759
+ id: string;
1760
+ alertId: string;
1761
+ ruleId: string;
1762
+ ruleVersion?: number | null;
1763
+ attempts: ContributingAttemptFact[];
1764
+ contributingAttemptCount: number;
1765
+ capturedAttemptCount: number;
1766
+ truncated: boolean;
1767
+ capturedAt: string;
1768
+ retainedUntil?: string | null;
1769
+ }
1105
1770
  export interface InitializeSetupDto {
1106
1771
  /** Admin user full name */
1107
1772
  name: string;
@@ -1113,6 +1778,8 @@ export interface InitializeSetupDto {
1113
1778
  organizationName: string;
1114
1779
  /** Organization slug (URL-friendly identifier) */
1115
1780
  organizationSlug: string;
1781
+ /** Definition of the tenant base currency. Created as the only currency at setup. Defaults to FIAT USD. */
1782
+ baseCurrency?: CreateCurrencyInput;
1116
1783
  /** Enable Transaction Intelligence product */
1117
1784
  transactionIntelligence?: boolean;
1118
1785
  /** Enable KYC vendor integration (within Customer Monitoring) */
@@ -1123,18 +1790,6 @@ export interface InstitutionDetailsDto {
1123
1790
  lei?: string;
1124
1791
  regulatoryStatus?: string;
1125
1792
  }
1126
- export interface InstrumentPayloadDto {
1127
- /** Instrument identifier. */
1128
- id: string;
1129
- /** Human-readable name persisted as instruments.displayName (e.g. "Personal Visa", "Travel Card"). */
1130
- name?: string;
1131
- /** Instrument type (CARD, VIRTUAL_CARD, WALLET_TOKEN, etc.). */
1132
- type?: string;
1133
- /** Instrument status (ACTIVE, BLOCKED, EXPIRED, etc.). */
1134
- status?: string;
1135
- /** Token or masked identifier. */
1136
- token?: string;
1137
- }
1138
1793
  export interface IntermediaryDto {
1139
1794
  /** Role of the intermediary (e.g. CORRESPONDENT, CLEARING_BANK). */
1140
1795
  role: string;
@@ -1149,6 +1804,19 @@ export interface IntermediaryDto {
1149
1804
  /** Payment instrument details. */
1150
1805
  paymentDetails?: Record<string, unknown>;
1151
1806
  }
1807
+ export type MergeableCounterpartyField = 'NAME' | 'DESCRIPTION' | 'COUNTRY' | 'CLASSIFICATION' | 'RISK_RATING' | 'NOTES' | 'LIFECYCLE_STATUS' | 'IDENTITY';
1808
+ export interface MergeFieldChoiceDto {
1809
+ field: MergeableCounterpartyField;
1810
+ /** Which record's value survives on the merged counterparty. */
1811
+ use: 'SOURCE' | 'TARGET';
1812
+ }
1813
+ export interface MergeCounterpartiesDto {
1814
+ /** Counterparty to merge away. It becomes a MERGED tombstone. */
1815
+ sourceId: string;
1816
+ /** Fields not listed keep the target's value. */
1817
+ fieldChoices?: MergeFieldChoiceDto[];
1818
+ reason?: string;
1819
+ }
1152
1820
  export interface LinkCounterpartyDto {
1153
1821
  /** Customer ID to link */
1154
1822
  customerId: string;
@@ -1228,7 +1896,11 @@ export interface OtherPaymentDetailsDto {
1228
1896
  }
1229
1897
  export interface PaginationMeta {
1230
1898
  /** Cursor to fetch the next page, null if no more results */
1231
- nextCursor: Record<string, unknown> | null;
1899
+ /**
1900
+ * Opaque cursor for the next page — the last row's id — or `null` on the
1901
+ * final page. Pass it straight back as `cursor`.
1902
+ */
1903
+ nextCursor: string | null;
1232
1904
  /** Total number of items matching the query */
1233
1905
  totalCount: number;
1234
1906
  }
@@ -1244,8 +1916,79 @@ export interface PatchTransactionStatusDto {
1244
1916
  /** Human-readable reason for terminal transitions (REJECTED, REVERSED, BLOCKED). Stored in statusHistory for audit. */
1245
1917
  terminalReason?: string;
1246
1918
  }
1919
+ /** Integer minor-unit amount with the currency and precision needed to display it. */
1920
+ export interface MonetaryAmountDto {
1921
+ /** Integer amount in minor units (cents, satoshi, …). */
1922
+ amountMinor: number;
1923
+ /** Currency in `TYPE:CODE` form, e.g. `FIAT:USD`. */
1924
+ currency: string;
1925
+ /** Decimal places: `major = amountMinor / 10^precision`. */
1926
+ precision: number;
1927
+ }
1928
+ export interface TransactionStatusHistoryEntryDto {
1929
+ from?: string;
1930
+ to: string;
1931
+ /** ISO 8601 — when the change occurred in the caller's system. */
1932
+ changedAt: string;
1933
+ reason?: string;
1934
+ }
1935
+ /**
1936
+ * A stored transaction as the platform holds it after ingestion: the caller's
1937
+ * payload plus what resolution and normalisation added. Returned by
1938
+ * `GET /v1/transactions/{transactionId}`.
1939
+ */
1940
+ export interface TransactionResponseDto {
1941
+ /** Internal transaction UUID (the `id` returned by `POST /transactions`). */
1942
+ id: string;
1943
+ /** Caller-supplied reference (the `transactionId` sent on ingest). */
1944
+ transactionId: string;
1945
+ kind: 'TRANSFER' | 'ACCOUNT_ENTRY' | (string & {});
1946
+ status: 'PENDING' | 'PROCESSING' | 'COMPLETE' | 'REJECTED' | 'REVERSED' | 'BLOCKED' | (string & {});
1947
+ statusChangedAt?: string | null;
1948
+ statusHistory?: TransactionStatusHistoryEntryDto[];
1949
+ /** Immutable window anchor. */
1950
+ executedAt: string;
1951
+ settledAt?: string | null;
1952
+ direction?: 'IN' | 'OUT' | null;
1953
+ entryType?: string | null;
1954
+ mode?: Record<string, unknown> | null;
1955
+ channel?: Record<string, unknown> | null;
1956
+ memo?: string | null;
1957
+ /** Amount as ingested. */
1958
+ origin: MonetaryAmountDto;
1959
+ /** Amount normalised to the tenant base currency. */
1960
+ base?: MonetaryAmountDto | null;
1961
+ destination?: MonetaryAmountDto | null;
1962
+ baseExchangeRate?: number | null;
1963
+ fees?: unknown[] | null;
1964
+ baseFeeTotalMinor?: number | null;
1965
+ paymentInfo?: Record<string, unknown> | null;
1966
+ principalParty?: Record<string, unknown> | null;
1967
+ counterparty?: Record<string, unknown> | null;
1968
+ customerId?: string | null;
1969
+ accountId?: string | null;
1970
+ counterpartyId?: string | null;
1971
+ counterpartyPaymentMethodId?: string | null;
1972
+ counterpartyResolutionStatus?: string | null;
1973
+ /** @deprecated Mirrors `paymentInstrumentId`. */
1974
+ instrumentId?: string | null;
1975
+ paymentInstrumentId?: string | null;
1976
+ channelEndpointId?: string | null;
1977
+ deviceId?: string | null;
1978
+ sessionId?: string | null;
1979
+ isInternalTxn?: boolean | null;
1980
+ isSelfTransfer?: boolean | null;
1981
+ internalCounterpartyCustomerId?: string | null;
1982
+ internalCounterpartyAccountId?: string | null;
1983
+ relatedTransactions?: unknown[] | null;
1984
+ isFlagged: boolean;
1985
+ flaggedAlertIds: string[];
1986
+ metadata?: Record<string, unknown> | null;
1987
+ createdAt: string;
1988
+ updatedAt: string;
1989
+ }
1247
1990
  export interface PaymentDetailsDto {
1248
- /** Discriminator selecting which payment subtype block to populate. NOTE: card-on-file (the instrument the principal customer paid with) is modelled separately on the transaction `instrument` field — counterparty payment details describe how the OTHER party receives money. */
1991
+ /** Discriminator selecting which payment subtype block to populate. NOTE: the Payment Instrument used by the principal customer is modelled separately on the transaction `paymentInstrument` field — counterparty payment details describe how the counterparty receives money. */
1249
1992
  type: 'BANK_ACCOUNT' | 'CRYPTO_WALLET' | 'DIGITAL_WALLET' | 'MERCHANT' | 'PROCESSOR' | 'CASH' | 'CHECK' | 'ATM' | 'OTHER';
1250
1993
  bankAccount?: BankAccountDetailsDto;
1251
1994
  cryptoWallet?: CryptoWalletDetailsDto;
@@ -1291,11 +2034,20 @@ export interface PaymentLocationAddressDto {
1291
2034
  /** ISO 3166-1 alpha-3 country code. */
1292
2035
  country?: string;
1293
2036
  }
1294
- export interface PaymentLocationCoordinatesDto {
1295
- /** Latitude (WGS84). */
1296
- lat: number;
2037
+ /**
2038
+ * A point on an ingested payment location.
2039
+ *
2040
+ * Both spellings are accepted; send either. Exactly one point is stored.
2041
+ */
2042
+ export interface PaymentLocationCoordinatesDto {
2043
+ /** Latitude (WGS84). */
2044
+ latitude?: number;
1297
2045
  /** Longitude (WGS84). */
1298
- lng: number;
2046
+ longitude?: number;
2047
+ /** Latitude (WGS84). Prefer `latitude`. */
2048
+ lat?: number;
2049
+ /** Longitude (WGS84). Prefer `longitude`. */
2050
+ lng?: number;
1299
2051
  }
1300
2052
  export interface PlaceOfBirthDto {
1301
2053
  cityOfBirth?: string;
@@ -1356,13 +2108,22 @@ export interface RegisterDeviceBrowserDetailsDto {
1356
2108
  userAgent?: string;
1357
2109
  }
1358
2110
  export interface RegisterDeviceDto {
1359
- /** Fingerprint provider identifier for the device */
1360
- fingerprint: string;
1361
- browserDetails: RegisterDeviceBrowserDetailsDto;
1362
- /** IP sessions observed for the device */
1363
- ipSessions?: unknown[];
2111
+ /** Raw identities used only for tenant-bound protected resolution; values are never persisted or returned. */
2112
+ fingerprints: RegisterDeviceFingerprintDto[];
2113
+ browserDetails?: RegisterDeviceBrowserDetailsDto;
1364
2114
  botProbability?: number;
1365
2115
  confidence?: number;
2116
+ /** ISO 8601 observation time. Defaults to server receipt time. */
2117
+ observedAt?: string;
2118
+ }
2119
+ export interface RegisterDeviceFingerprintDto {
2120
+ /** Raw identity value used in memory only. */
2121
+ value: string;
2122
+ /** Provider namespace. Defaults to INGEST to converge with transaction ingestion. */
2123
+ provider?: string;
2124
+ /** Provider-qualified identity type. Defaults to DEVICE. */
2125
+ type?: string;
2126
+ confidence?: number;
1366
2127
  }
1367
2128
  export interface RelatedTransactionDto {
1368
2129
  /** Transaction ID of the related transaction. Use the same identifier format as `transactionId` (your external reference). */
@@ -1406,9 +2167,23 @@ export interface TaxIdentificationDto {
1406
2167
  /** YYYY-MM-DD */
1407
2168
  registrationDate?: string;
1408
2169
  }
2170
+ /**
2171
+ * Ledger-line classification for an `ACCOUNT_ENTRY` transaction — a fee, an
2172
+ * interest movement, a payment, or an adjustment.
2173
+ */
2174
+ export type AccountEntryType = 'MONTHLY_FEE' | 'WIRE_FEE' | 'OVERDRAFT_FEE' | 'LATE_PAYMENT_FEE' | 'ANNUAL_FEE' | 'ATM_FEE' | 'FOREIGN_TRANSACTION_FEE' | 'INTEREST_CHARGE' | 'INTEREST_PAYMENT' | 'PRINCIPAL_PAYMENT' | 'ESCROW_PAYMENT' | 'MINIMUM_PAYMENT' | 'STATEMENT_PAYMENT' | 'REWARD_REDEMPTION' | 'CASHBACK' | 'ADJUSTMENT' | 'CHARGEBACK' | 'PROMOTIONAL_CREDIT' | 'PENALTY' | 'REFUND';
1409
2175
  export interface TransactionBodyDto {
1410
2176
  /** Transaction kind discriminator. */
1411
2177
  kind: 'TRANSFER' | 'ACCOUNT_ENTRY';
2178
+ /**
2179
+ * What kind of ledger line an `ACCOUNT_ENTRY` is — a fee, an interest
2180
+ * credit, an adjustment, and so on.
2181
+ *
2182
+ * Required when `kind` is `'ACCOUNT_ENTRY'`, ignored for `'TRANSFER'`. The
2183
+ * read model exposes it as non-nullable, so an account entry ingested
2184
+ * without one cannot be rendered.
2185
+ */
2186
+ entryType?: AccountEntryType;
1412
2187
  /** Two-level payment classification: closed category enum + open method string. */
1413
2188
  mode: Record<string, unknown>;
1414
2189
  /** Channel and session context for the transaction. */
@@ -1427,6 +2202,8 @@ export interface TransactionBodyDto {
1427
2202
  reference?: string;
1428
2203
  /** Free-text memo or note. */
1429
2204
  memo?: string;
2205
+ /** Resource tags for this transaction, as catalogue values (slugs) or labels from the `txn.tags` tag catalogue (Settings → Tags). Stored on `transactions.tags`, read by rules as the `txn.tags` set field, and filterable inside aggregate brackets — e.g. `account.txn(24h).sum(amount)[tags IN (top-up)]`. Values not in the catalogue are rejected (HTTP 400). Tags are written at ingest only; status updates leave them unchanged. */
2206
+ tags?: string[];
1430
2207
  /** IDs of related transactions (e.g. funding legs, reversals, fees). Useful when multiple transactions form a single logical transfer. */
1431
2208
  relatedTransactions?: RelatedTransactionDto[];
1432
2209
  /** Open per-transaction key/value bag stored on `transactions.metadata` and exposed to the rules engine as `txn.metadata.{key}`. Each value is either a **bare primitive** (string / number / boolean — coerced to `text` at ingest) or a **typed wrapper** `{ "type": "...", "value": ... }` so the evaluator can run typed comparisons. See spec evaluation/02 §1.M.
@@ -1483,10 +2260,30 @@ export interface UpdateCounterpartyDto {
1483
2260
  institution?: InstitutionDetailsDto;
1484
2261
  }
1485
2262
  /** OpenAPI schema is empty; treated as an opaque key/value bag — narrow on the caller side. */
1486
- export type UpdateCurrencyInput = Record<string, unknown>;
2263
+ export interface UpdateCurrencyInput {
2264
+ name?: string;
2265
+ symbol?: string;
2266
+ /** Number of minor-unit decimal places (0–18). */
2267
+ precision?: number;
2268
+ isEnabled?: boolean;
2269
+ }
1487
2270
  export interface UpdateDeviceTrustDto {
1488
2271
  trustLevel: 'KNOWN' | 'NEW' | 'SUSPICIOUS';
1489
2272
  }
2273
+ export interface MergeDeviceDto {
2274
+ sourceDeviceId: string;
2275
+ reason: string;
2276
+ }
2277
+ export interface DeviceMergeResponseDto {
2278
+ id: string;
2279
+ organizationId: string;
2280
+ sourceDeviceId: string;
2281
+ targetDeviceId: string;
2282
+ canonicalDeviceId: string;
2283
+ reason: string;
2284
+ mergedBy: Record<string, unknown>;
2285
+ mergedAt: string;
2286
+ }
1490
2287
  export interface UpdateEntityDto {
1491
2288
  legalName?: string;
1492
2289
  tradingNames?: string[];
@@ -1495,6 +2292,8 @@ export interface UpdateEntityDto {
1495
2292
  countryOfIncorporation?: string;
1496
2293
  dateOfIncorporation?: string;
1497
2294
  entityType?: string;
2295
+ /** Tax Identification Number (TIN). */
2296
+ taxId?: string;
1498
2297
  /** Parent entity ID for subsidiaries */
1499
2298
  parentEntityId?: string;
1500
2299
  email?: string;
@@ -1520,8 +2319,22 @@ export interface UpdateEventDefinitionDto {
1520
2319
  description?: string;
1521
2320
  /** Event category. */
1522
2321
  category?: string;
1523
- /** Event properties schema. */
1524
- properties?: Record<string, unknown>[];
2322
+ /** Event definition status. */
2323
+ status?: 'ACTIVE' | 'DEPRECATED' | 'DRAFT';
2324
+ /**
2325
+ * Resources this event names, each as SUBJECT (what an occurrence is
2326
+ * about) or CONTEXT (what it also references). Omit to accept any
2327
+ * attachable subject and expect no context.
2328
+ */
2329
+ resources?: EventResourceDeclarationDto[];
2330
+ /** Event property schema. Same shape as `TypedFieldDefinition` (including `options` for select types). */
2331
+ properties?: TypedFieldDefinition[];
2332
+ /**
2333
+ * Risk Signals to emit on every valid occurrence of this event. Supplying
2334
+ * the array replaces the declared effects; signals already recorded keep
2335
+ * the weight and half-life snapshotted when they were created.
2336
+ */
2337
+ riskSignalEffects?: RiskSignalEffect[];
1525
2338
  }
1526
2339
  export interface UpdateExpectedActivityDto {
1527
2340
  expectedMonthlyTransactionCount: number;
@@ -1553,6 +2366,8 @@ export interface UpdateIndividualDto {
1553
2366
  countryOfResidence?: string[];
1554
2367
  /** Additional name variants the customer is known by. */
1555
2368
  aliases?: string[];
2369
+ /** Tax Identification Number (TIN). */
2370
+ taxId?: string;
1556
2371
  email?: string;
1557
2372
  phone?: string;
1558
2373
  identificationDocuments?: IdentificationDocumentDto[];
@@ -1616,10 +2431,14 @@ export interface UpdateProductDto {
1616
2431
  /** Product description. */
1617
2432
  description?: string;
1618
2433
  /** Product status. */
1619
- status?: string;
2434
+ status?: ProductStatus;
2435
+ /** Preferred product classification, governed by the `product.tags` catalogue. */
2436
+ tags?: TagValueInput[];
1620
2437
  /** Supported transaction method IDs. */
1621
2438
  supportedMethodIds?: string[];
1622
- /** Typed Field schema for accounts of this product (Tier A). */
2439
+ /** Account field template for accounts created from this product. */
2440
+ accountFieldConfig?: TypedFieldDefinition[];
2441
+ /** @deprecated Use `accountFieldConfig`. */
1623
2442
  typedAccountFieldConfig?: TypedFieldDefinition[];
1624
2443
  /** Product-level typed bag (Tier B, self-declaring). */
1625
2444
  fields?: TypedFieldValueInput[];
@@ -1645,14 +2464,31 @@ export interface UpdateCustomerStatusResponse {
1645
2464
  statusReason: string | null;
1646
2465
  updatedAt: string;
1647
2466
  }
2467
+ /** Body for archiving a customer (admin-only, irreversible). */
2468
+ export interface ArchiveCustomerDto {
2469
+ /** Audit reason for archiving the customer. */
2470
+ reason?: string;
2471
+ }
2472
+ export interface ArchiveCustomerResponse {
2473
+ customerId: string;
2474
+ /** When the customer was archived (ISO 8601). */
2475
+ archivedAt: string | null;
2476
+ /** The original (clean) external ID, preserved for audit. The live external ID is freed for reuse. */
2477
+ archivedExternalId: string | null;
2478
+ archivedReason: string | null;
2479
+ }
1648
2480
  export interface UpdateRuleDto {
1649
2481
  /** Rule name. */
1650
2482
  name?: string;
1651
2483
  /** Rule description. */
1652
2484
  description?: string;
1653
- /** Rule subject. */
2485
+ /** Rule subject: 'TRANSACTION' | 'EVENT' | 'CUSTOMER' | 'ALL'. */
1654
2486
  subject?: string;
1655
- /** Rule trigger. */
2487
+ /**
2488
+ * Rule trigger — see CreateRuleDto.trigger. The post-update
2489
+ * subject/trigger pair is validated, so patching only the trigger must
2490
+ * still be compatible with the rule's existing subject.
2491
+ */
1656
2492
  trigger?: string;
1657
2493
  /** Rule severity. */
1658
2494
  severity?: 'HIGH' | 'MEDIUM' | 'LOW';
@@ -1663,9 +2499,18 @@ export interface UpdateRuleDto {
1663
2499
  /** Condition tree. */
1664
2500
  conditionTree?: Record<string, unknown>;
1665
2501
  /** Actions to execute. */
1666
- actions?: string[];
2502
+ actions?: RuleAction[];
1667
2503
  /** Window period. */
1668
2504
  windowPeriod?: string;
2505
+ /**
2506
+ * Optional note recorded against the version this edit mints (audit trail).
2507
+ * Ignored if the edit changes no definitional field.
2508
+ */
2509
+ changeNote?: string;
2510
+ /** Product applicability. Pass null or empty products to unscope. */
2511
+ scope?: {
2512
+ products?: string[];
2513
+ } | null;
1669
2514
  }
1670
2515
  export interface UpdateStakeholderDto {
1671
2516
  name?: string;
@@ -1719,6 +2564,8 @@ export interface IngestTransactionResponse {
1719
2564
  matches: IngestTransactionMatch[];
1720
2565
  /** Server-side evaluation time in milliseconds. */
1721
2566
  executionTimeMs: number;
2567
+ /** The stored transaction after resolution and evaluation — the same shape `transactions.get()` returns. */
2568
+ transaction?: TransactionResponseDto;
1722
2569
  }
1723
2570
  /** Async response (202) from POST /v1/transactions when accepted for background processing. */
1724
2571
  export interface IngestTransactionAsyncResponse {
@@ -1726,12 +2573,44 @@ export interface IngestTransactionAsyncResponse {
1726
2573
  id: string;
1727
2574
  async: true;
1728
2575
  status: 'ACCEPTED' | string;
2576
+ /** The stored transaction after resolution; evaluation has not run yet, so flags are not set. */
2577
+ transaction?: TransactionResponseDto;
1729
2578
  }
1730
2579
  export interface IngestEventResponse {
1731
- /** Database record ID for the ingested event. */
2580
+ /**
2581
+ * Echo of the request `eventId`; the database record ID when the
2582
+ * request carried none.
2583
+ */
1732
2584
  eventId: string;
2585
+ /** Database record ID for the ingested event. */
2586
+ id: string;
1733
2587
  /** Echoed event type. */
1734
2588
  type: string;
2589
+ /**
2590
+ * The Event Definition the type resolved to. `null` means the type has no
2591
+ * Definition: the occurrence is recorded, but nothing described it and no
2592
+ * Risk Signal fired for it — catch a typo here rather than by noticing the
2593
+ * absence of signals days later. A tenant that would rather the request
2594
+ * fail sets the `unknownEventTypes` behaviour setting to `REJECT`.
2595
+ */
2596
+ definitionId: string | null;
2597
+ /**
2598
+ * The resolved primary resource the event was attached to. Echoed back
2599
+ * resolved, so a request that used the legacy `customerId` spelling reads
2600
+ * back as `{ type: 'CUSTOMER', id }`.
2601
+ */
2602
+ resource: EventResourceRef;
2603
+ /**
2604
+ * Ids of the Risk Signals the event definition's `riskSignalEffects`
2605
+ * emitted for this occurrence. Empty when the definition declares none.
2606
+ *
2607
+ * The Event and its signals are written in one transaction, and a replay
2608
+ * echoes the signals the original ingestion produced — the event's
2609
+ * idempotency covers its Risk Signals too.
2610
+ */
2611
+ riskSignalIds: string[];
2612
+ /** Present (true) when this request deduplicated against an already-stored event. */
2613
+ cached?: boolean;
1735
2614
  }
1736
2615
  export interface CursorPaginationQuery {
1737
2616
  cursor?: string;
@@ -1745,6 +2624,10 @@ export interface ListCurrenciesQuery {
1745
2624
  export interface SyncKeyQuery {
1746
2625
  syncKey?: string;
1747
2626
  }
2627
+ export interface ListConstantsQuery extends SyncKeyQuery {
2628
+ /** Restrict to product-bound `$account.*` definitions for this product. */
2629
+ productId?: string;
2630
+ }
1748
2631
  export interface DeleteConstantQuery {
1749
2632
  force?: boolean;
1750
2633
  reason?: string;
@@ -1799,17 +2682,496 @@ export interface PlatformUploadUrlResponseDto {
1799
2682
  /** Response shape for `POST /v1/platform/v1/files/confirm` — typically `{ fileId, downloadUrl, ... }`. */
1800
2683
  export type PlatformConfirmUploadResponseDto = OpaqueResponse;
1801
2684
  export type StakeholderResponseDto = OpaqueResponse;
1802
- export type DeviceResponseDto = OpaqueResponse;
1803
- export type DeviceSummaryDto = OpaqueResponse;
2685
+ export interface DevicePublicBrowserDetailsDto {
2686
+ browserName: string;
2687
+ browserMajorVersion: string;
2688
+ browserFullVersion: string;
2689
+ os: 'WINDOWS' | 'MACOS' | 'LINUX' | 'IOS' | 'ANDROID' | 'OTHER';
2690
+ osVersion: string;
2691
+ device: 'DESKTOP' | 'MOBILE' | 'TABLET' | 'UNKNOWN';
2692
+ userAgent: string;
2693
+ }
2694
+ export interface DeviceGeolocationDto {
2695
+ country: string;
2696
+ city: string;
2697
+ /** The observed point. Same numbers as `latitude`/`longitude`, kept paired. */
2698
+ coordinates: CoordinatesDto;
2699
+ latitude: number;
2700
+ longitude: number;
2701
+ timezone: string;
2702
+ accuracyRadius: number;
2703
+ continent?: string;
2704
+ postalCode?: string;
2705
+ }
2706
+ export interface DeviceVpnDetectionMethodsDto {
2707
+ timezoneMismatch: boolean;
2708
+ publicVPN: boolean;
2709
+ auxiliaryMobile: boolean;
2710
+ relay: boolean;
2711
+ }
2712
+ export interface DeviceVpnDetectionDto {
2713
+ result: boolean;
2714
+ confidence: number;
2715
+ originTimezone: string;
2716
+ originCountry: string;
2717
+ methods: DeviceVpnDetectionMethodsDto;
2718
+ }
2719
+ export interface DeviceIpSessionDto {
2720
+ geolocation: DeviceGeolocationDto;
2721
+ vpn: DeviceVpnDetectionDto;
2722
+ isProxy: boolean;
2723
+ isTor: boolean;
2724
+ incognito: boolean;
2725
+ seenAt: string;
2726
+ }
2727
+ /**
2728
+ * A customer linked to a device.
2729
+ *
2730
+ * The dates are the link's own, not the device's: on a device used by more than
2731
+ * one customer they say who had it when.
2732
+ */
2733
+ export interface DeviceCustomerLinkDto {
2734
+ customerId: string;
2735
+ name?: string | null;
2736
+ /** INDIVIDUAL or ENTITY. */
2737
+ type?: string | null;
2738
+ status?: string | null;
2739
+ riskRating?: string | null;
2740
+ externalId?: string | null;
2741
+ firstSeenAt: string;
2742
+ lastSeenAt: string;
2743
+ }
2744
+ /** Safe canonical Device response. It never contains raw fingerprint or IP identity values. */
2745
+ export interface DeviceResponseDto {
2746
+ id: string;
2747
+ requestId?: string | null;
2748
+ browserDetails: DevicePublicBrowserDetailsDto;
2749
+ ipSessions: DeviceIpSessionDto[];
2750
+ botProbability: number;
2751
+ confidence: number;
2752
+ trustLevel: 'KNOWN' | 'NEW' | 'SUSPICIOUS';
2753
+ firstSeenAt: string;
2754
+ lastSeenAt: string;
2755
+ /**
2756
+ * Every customer linked to this device. Returned by `GET /devices/{id}`;
2757
+ * absent on endpoints that list devices in bulk.
2758
+ */
2759
+ customers?: DeviceCustomerLinkDto[];
2760
+ }
2761
+ /** @deprecated Customer Device endpoints now return the canonical Device response. */
2762
+ export type DeviceSummaryDto = DeviceResponseDto;
1804
2763
  export type CustomerRiskAssessmentResponseDto = OpaqueResponse;
1805
2764
  export type RiskAssessmentResponseDto = OpaqueResponse;
1806
2765
  export type ExpectedActivityResponseDto = OpaqueResponse;
1807
2766
  export type ScreeningResultDto = OpaqueResponse;
1808
2767
  export type ConfirmedMatchDto = OpaqueResponse;
1809
- export type RuleResponseDto = OpaqueResponse;
2768
+ /**
2769
+ * The screening provider's automated false-positive assessment of a weak
2770
+ * match — why the match is, or is not, the customer, decided from date of
2771
+ * birth, geography, role timeline and entity kind rather than from the name.
2772
+ *
2773
+ * Present only where the provider ran it: the customer record carried
2774
+ * attributes to compare against. Absence is not an implied `retain`.
2775
+ *
2776
+ * A `decision` of `discard` sets the match's `disposition` to
2777
+ * `FALSE_POSITIVE` with no human involved — so whenever you see a disposition
2778
+ * none of your users set, `rationale` is the reason.
2779
+ */
2780
+ export interface MatchDisambiguationDto {
2781
+ /**
2782
+ * `discard` where an attribute positively contradicts identity — this is
2783
+ * what auto-dispositions the match. `retain` is the default and is not a
2784
+ * confirmation, only the absence of grounds to eliminate.
2785
+ */
2786
+ decision?: 'discard' | 'retain';
2787
+ /**
2788
+ * How to queue the match. `likely_false_positive` means the evidence
2789
+ * pointed that way but did not clear the provider's confidence floor —
2790
+ * deprioritise, do not dismiss.
2791
+ */
2792
+ dispositionHint?: 'false_positive' | 'likely_false_positive' | 'needs_review' | 'possible_match';
2793
+ /** Confidence in the verdict. A `discard` is only ever emitted at `high`. */
2794
+ confidence?: 'high' | 'medium' | 'low';
2795
+ /**
2796
+ * `hard` for a date-of-birth contradiction, an entity-type mismatch, an
2797
+ * implausible age for the role timeline, or a nationality conflict;
2798
+ * `soft` for jurisdiction or residence geography and gender. A sanctions
2799
+ * listing is never discarded on soft evidence alone.
2800
+ */
2801
+ contradictionStrength?: 'hard' | 'soft' | 'none';
2802
+ /**
2803
+ * The rules that fired, from the provider's closed vocabulary — e.g.
2804
+ * `DOB_CONTRADICTION`, `AGE_IMPLAUSIBLE_FOR_ROLE_TIMELINE`,
2805
+ * `ENTITY_TYPE_MISMATCH`, `NATIONALITY_CONFLICT`, `INSUFFICIENT_DATA_TO_ELIMINATE`.
2806
+ */
2807
+ reasonCodes?: string[];
2808
+ /**
2809
+ * One to three sentences naming the field values compared — the audit
2810
+ * answer to "why was this match eliminated".
2811
+ */
2812
+ rationale?: string;
2813
+ }
2814
+ /**
2815
+ * A single screening match for a customer, read live with its current
2816
+ * disposition. Returned by `GET /v1/customers/{customerId}/screening-results`
2817
+ * — the full true-positive (`CONFIRMED`) / false-positive (`FALSE_POSITIVE`) /
2818
+ * unresolved (`PENDING`) picture. Confirmed and false-positive matches persist
2819
+ * across re-screens.
2820
+ */
2821
+ export interface ScreeningMatchResultDto {
2822
+ /** Match record ID. */
2823
+ id: string;
2824
+ matchType: 'WATCHLIST' | 'HIGH_RISK' | 'CUSTOM_LIST';
2825
+ disposition: 'PENDING' | 'CONFIRMED' | 'FALSE_POSITIVE';
2826
+ /** Matched entity name. */
2827
+ matchedName: string;
2828
+ /** List/source label, e.g. `OFAC SDN` (high-risk → `High Risk`, custom list → list name). */
2829
+ source?: string;
2830
+ /** For CUSTOM_LIST matches: the list's current tags. */
2831
+ listTags?: Array<{
2832
+ value: string;
2833
+ label: string;
2834
+ }>;
2835
+ /**
2836
+ * Short role/bio line. Populated for `HIGH_RISK` (PEP) matches when the
2837
+ * provider supplies one; always present and `""` otherwise — never omitted
2838
+ * or null, so it can be read without a presence check.
2839
+ */
2840
+ tagline: string;
2841
+ /** General free-text profile summary (composed by the screening provider). */
2842
+ summary?: string;
2843
+ /** Provider match confidence, 0–1. */
2844
+ matchConfidence?: number;
2845
+ /** ISO-8601 timestamp the disposition was set. */
2846
+ resolvedAt?: string;
2847
+ /** Who set the disposition. */
2848
+ resolvedBy?: Record<string, unknown>;
2849
+ /**
2850
+ * The provider's automated false-positive assessment, where it ran. When
2851
+ * `disposition` is `FALSE_POSITIVE` and `resolvedBy` is the screening
2852
+ * service rather than one of your users, this is why.
2853
+ */
2854
+ disambiguation?: MatchDisambiguationDto;
2855
+ }
2856
+ /**
2857
+ * A single screening run from
2858
+ * `GET /v1/customers/{customerId}/screening-history[/latest]`. One entry per
2859
+ * time the customer was screened (initial, ongoing, manual, event-triggered).
2860
+ */
2861
+ export interface ScreeningHistoryEntryDto {
2862
+ /** Screening log entry ID. */
2863
+ id: string;
2864
+ customerId: string;
2865
+ customerName: string;
2866
+ /** What triggered the screening, e.g. `INITIAL` | `ONGOING` | `MANUAL` | `EVENT_TRIGGERED`. */
2867
+ screeningType: string;
2868
+ /** Run status, e.g. `COMPLETED` | `PENDING` | `FAILED`. */
2869
+ status: string;
2870
+ /** Total matches surfaced across all sources. */
2871
+ matchesFound: number;
2872
+ /** Number of alerts raised from this screening. */
2873
+ alertsGenerated: number;
2874
+ /** Watchlist matches suppressed by whitelisting/dispositions. */
2875
+ suppressedWatchlistCount: number;
2876
+ /** High-risk/PEP matches suppressed by whitelisting/dispositions. */
2877
+ suppressedHighRiskCount: number;
2878
+ /** Custom-list matches suppressed by prior false-positive dispositions. */
2879
+ suppressedCustomListCount: number;
2880
+ /** Which checks were run, e.g. `['WATCHLIST', 'HIGH_RISK', 'CUSTOM_LIST']`. */
2881
+ checksRun: string[];
2882
+ /** ISO-8601 timestamp the screening was initiated. */
2883
+ createdAt: string;
2884
+ /** ISO-8601 timestamp the screening finished, if completed. */
2885
+ completedAt?: string;
2886
+ [key: string]: unknown;
2887
+ }
2888
+ /**
2889
+ * Options for `individuals.create` / `entities.create`.
2890
+ */
2891
+ export interface CreateCustomerOptions {
2892
+ /**
2893
+ * How the INITIAL screening runs. `async` (default) queues it and the
2894
+ * call returns at once — poll `customers.screening.history` /
2895
+ * `listResults`, or listen for the screening webhooks. `sync` runs it
2896
+ * before responding and returns the run and its matches under
2897
+ * `screening` on the response.
2898
+ */
2899
+ screening?: 'async' | 'sync';
2900
+ }
2901
+ /**
2902
+ * Outcome of the INITIAL screening run performed inline by
2903
+ * `individuals.create(input, { screening: 'sync' })` and the entities twin.
2904
+ */
2905
+ export interface InitialScreeningResultDto {
2906
+ /** Screening log entry ID — the same id `screening.history` returns. */
2907
+ id: string;
2908
+ /** Always `INITIAL` for a create-time run. */
2909
+ screeningType: string;
2910
+ /**
2911
+ * `COMPLETED` when every configured check ran. `FAILED` when no provider
2912
+ * is configured or every provider failed — the customer still exists;
2913
+ * rerun with `customers.screening.trigger(customerId)`.
2914
+ */
2915
+ status: 'COMPLETED' | 'FAILED';
2916
+ /** Why the run FAILED, e.g. `no_providers_configured`, `all_providers_failed`. */
2917
+ statusReason?: string;
2918
+ /** Which checks actually ran, e.g. `['WATCHLIST', 'HIGH_RISK', 'CUSTOM_LIST']`. */
2919
+ checksRun: string[];
2920
+ /** Total matches surfaced across all sources, including auto-dismissed ones. */
2921
+ matchesFound: number;
2922
+ /** Number of alerts raised from this screening (0 or 1). */
2923
+ alertsGenerated: number;
2924
+ /** The screening alert holding these matches, when any were found. Absent on a clear run. */
2925
+ alertId?: string;
2926
+ /**
2927
+ * Matches the provider's attribute assessment eliminated as false
2928
+ * positives. Still counted in `matchesFound` and listed in `matches`
2929
+ * with disposition `FALSE_POSITIVE`.
2930
+ */
2931
+ autoDismissedMatchCount: number;
2932
+ /** True when every match was auto-dismissed and the alert closed itself. */
2933
+ alertAutoClosed: boolean;
2934
+ /** ISO-8601 timestamp the screening was initiated. */
2935
+ createdAt: string;
2936
+ /** ISO-8601 timestamp the screening finished. */
2937
+ completedAt?: string;
2938
+ /**
2939
+ * Every match this run surfaced, with its disposition — the same shape
2940
+ * as `customers.screening.listResults`. Empty on a clear or FAILED run.
2941
+ */
2942
+ matches: ScreeningMatchResultDto[];
2943
+ }
2944
+ /**
2945
+ * `individuals.create` response. Identical to `IndividualResponseDto` unless
2946
+ * the call used `{ screening: 'sync' }`, in which case `screening` carries
2947
+ * the INITIAL run's outcome and matches.
2948
+ */
2949
+ export interface IndividualCreatedResponseDto extends IndividualResponseDto {
2950
+ screening?: InitialScreeningResultDto;
2951
+ }
2952
+ /** `entities.create` response — see `IndividualCreatedResponseDto`. */
2953
+ export interface EntityCreatedResponseDto extends EntityResponseDto {
2954
+ screening?: InitialScreeningResultDto;
2955
+ }
2956
+ /** KYC verification status, mirroring the backend `KYCVerificationStatus` enum. */
2957
+ export type KycVerificationStatus = 'VERIFIED' | 'FAILED' | 'PENDING' | 'EXPIRED';
2958
+ /**
2959
+ * Result of starting a KYC session
2960
+ * (`POST /v1/customers/{customerId}/kyc/sessions`). Hand `sessionUrl` to the
2961
+ * customer to complete verification.
2962
+ */
2963
+ export interface StartKycSessionResponseDto {
2964
+ /** Local KYC session id. */
2965
+ sessionId: string;
2966
+ /** The provider's own session id. */
2967
+ providerSessionId: string;
2968
+ /** Hosted URL the customer visits to complete verification. */
2969
+ sessionUrl: string;
2970
+ status: KycVerificationStatus;
2971
+ /** ISO-8601 expiry, or null. */
2972
+ expiresAt?: string | null;
2973
+ /** ISO-8601 creation time. */
2974
+ createdAt: string;
2975
+ }
2976
+ /**
2977
+ * A persisted KYC session, returned by
2978
+ * `GET /v1/customers/{customerId}/kyc/sessions` and the refresh endpoint.
2979
+ */
2980
+ export interface KycSessionDto {
2981
+ id: string;
2982
+ customerId: string;
2983
+ status: KycVerificationStatus;
2984
+ /** Which provider ran the session, e.g. `dossiers`. */
2985
+ provider?: string | null;
2986
+ /** Hosted URL the customer visits to complete verification. */
2987
+ sessionUrl?: string | null;
2988
+ /** Per-step verification progress (provider-normalized). */
2989
+ steps: Record<string, unknown>[];
2990
+ /** Verified identity documents (provider-normalized). */
2991
+ documents: Record<string, unknown>[];
2992
+ overallResult?: string | null;
2993
+ /** ISO-8601 expiry, or null. */
2994
+ expiresAt?: string | null;
2995
+ /** ISO-8601 creation time. */
2996
+ createdAt: string;
2997
+ /** ISO-8601 completion time, if completed. */
2998
+ completedAt?: string | null;
2999
+ [key: string]: unknown;
3000
+ }
3001
+ /**
3002
+ * A saved rule as returned by the Config — Rules API
3003
+ * (`POST`/`GET`/`PATCH /v1/config/rules[/:id]`). Mirrors the backend
3004
+ * `RULE_SCHEMA`.
3005
+ */
3006
+ export interface RuleResponseDto {
3007
+ id: string;
3008
+ name: string;
3009
+ description?: string;
3010
+ /** Rule subject: 'TRANSACTION' | 'EVENT' | 'CUSTOMER' | 'ALL'. */
3011
+ subject: string;
3012
+ /** Rule trigger — see CreateRuleDto.trigger. */
3013
+ trigger: string;
3014
+ severity: 'HIGH' | 'MEDIUM' | 'LOW';
3015
+ status: 'DRAFT' | 'ACTIVE' | 'DISABLED';
3016
+ tags: string[];
3017
+ /** Condition tree (AND/OR logic with leaf conditions). */
3018
+ conditionTree: Record<string, unknown>;
3019
+ /** Actions to execute when the rule triggers. */
3020
+ actions: Record<string, unknown>[];
3021
+ /** Window period for aggregate conditions. */
3022
+ windowPeriod?: string;
3023
+ /** Sync key for config-as-code management. */
3024
+ syncKey?: string;
3025
+ isSystemRule: boolean;
3026
+ /** Product applicability. Null / empty products = unscoped. */
3027
+ scope?: {
3028
+ products?: string[];
3029
+ } | null;
3030
+ createdAt: string;
3031
+ updatedAt: string;
3032
+ }
3033
+ /**
3034
+ * A single immutable rule version snapshot from
3035
+ * GET /v1/config/rules/{id}/versions[/{version}]. Carries the definitional
3036
+ * fields plus audit metadata (version, changeKind, changeNote, actor, createdAt).
3037
+ */
3038
+ export type RuleVersionResponseDto = OpaqueResponse;
3039
+ /** Response from GET /v1/config/rules/:id/analytics — disposition breakdown + precision (#42). */
3040
+ export type RuleAnalyticsResponseDto = OpaqueResponse;
3041
+ /** Input for POST /v1/config/rules/backtest (spec v0 rules §11 + synthetic source). */
3042
+ export interface SimulateRulesDto {
3043
+ /** Default HISTORICAL. */
3044
+ source?: 'HISTORICAL' | 'SYNTHETIC';
3045
+ /** Existing rules to simulate; conditionTreeOverride A/B-tests changes without saving. */
3046
+ rules?: Array<{
3047
+ ruleId: string;
3048
+ conditionTreeOverride?: Record<string, unknown>;
3049
+ }>;
3050
+ /** Inline unsaved rules — evaluated only for this run. */
3051
+ adHocRules?: Array<{
3052
+ name: string;
3053
+ severity: string;
3054
+ conditionTree: Record<string, unknown>;
3055
+ }>;
3056
+ period: {
3057
+ from: string;
3058
+ to: string;
3059
+ };
3060
+ filters?: {
3061
+ customerIds?: string[];
3062
+ accountIds?: string[];
3063
+ modeCategories?: string[];
3064
+ minAmountMinor?: number;
3065
+ };
3066
+ /** Cap on transactions evaluated (default 5000, max 100000). */
3067
+ maxTransactions?: number;
3068
+ /** Generator parameters (SYNTHETIC source only). */
3069
+ synthetic?: {
3070
+ count?: number;
3071
+ customerIds?: string[];
3072
+ minAmountMinor?: number;
3073
+ maxAmountMinor?: number;
3074
+ modeCategories?: string[];
3075
+ directions?: string[];
3076
+ /**
3077
+ * Event occurrences to generate across the period (default one per 20
3078
+ * transactions, max 500). Events that typically precede activity pull a
3079
+ * run of transactions in behind them.
3080
+ */
3081
+ eventCount?: number;
3082
+ /** Event Definition names to draw from. Default: the org's active definitions. */
3083
+ eventTypes?: string[];
3084
+ };
3085
+ includeMatches?: boolean;
3086
+ }
3087
+ /** Dry-run simulation report — nothing was persisted, no actions executed. */
3088
+ export interface SimulationReportDto {
3089
+ simulationId: string;
3090
+ source: 'HISTORICAL' | 'SYNTHETIC';
3091
+ dryRun: true;
3092
+ periodFrom: string;
3093
+ periodTo: string;
3094
+ transactionsEvaluated: number;
3095
+ totalMatches: number;
3096
+ executionTimeMs: number;
3097
+ /** Tenant base currency (TYPE:CODE) that per-rule matched volumes are denominated in. */
3098
+ baseCurrency: string;
3099
+ byRule: Array<{
3100
+ ruleId: string;
3101
+ ruleName: string;
3102
+ severity: string;
3103
+ matchCount: number;
3104
+ distinctCustomers: number;
3105
+ distinctAccounts: number;
3106
+ totalMatchedVolumeMinor: number;
3107
+ matches: Array<{
3108
+ transactionId: string;
3109
+ /** Internal transactions.id — null for synthetic rows (nothing stored). */
3110
+ transactionDbId: string | null;
3111
+ customerId: string | null;
3112
+ bookedAt: string;
3113
+ baseAmountMinor: number | null;
3114
+ /** Currency of `baseAmountMinor` (TYPE:CODE) — pair these when formatting. */
3115
+ baseCurrency: string | null;
3116
+ /** Minor-unit precision of `baseCurrency`. */
3117
+ basePrecision: number | null;
3118
+ originCurrency: string | null;
3119
+ flagReasons: string[];
3120
+ wouldHaveExecuted: Array<Record<string, unknown>>;
3121
+ /** Full transaction snapshot (mode, status, monetary legs, parties, metadata). */
3122
+ transactionDetail: Record<string, unknown>;
3123
+ }>;
3124
+ }>;
3125
+ /** Synthetic Events generated for the period, and the activity behind them. */
3126
+ syntheticEvents: Array<{
3127
+ /** Event Definition name the occurrences were generated from. */
3128
+ type: string;
3129
+ count: number;
3130
+ /** Synthetic transactions clustered in the window behind these events. */
3131
+ followedByTransactions: number;
3132
+ }>;
3133
+ coverageGaps: string[];
3134
+ warnings: string[];
3135
+ }
1810
3136
  export type ConstantResponseDto = OpaqueResponse;
1811
- export type ProductResponseDto = OpaqueResponse;
1812
- export type CurrencyResponseDto = OpaqueResponse;
3137
+ export interface ProductResponseDto {
3138
+ id: string;
3139
+ externalId: string;
3140
+ name: string;
3141
+ description?: string | null;
3142
+ category: AccountCategory;
3143
+ tags: TagValue[];
3144
+ /** @deprecated Use `tags`. Retained for API compatibility. */
3145
+ baseType: AccountType;
3146
+ status: ProductStatus;
3147
+ defaultCurrency: string;
3148
+ /** @deprecated Use `tags` when product classification is needed. */
3149
+ country?: string | null;
3150
+ supportedMethodIds: string[];
3151
+ accountFieldConfig?: TypedFieldDefinition[];
3152
+ /** @deprecated Use `accountFieldConfig`. */
3153
+ typedAccountFieldConfig?: TypedFieldDefinition[];
3154
+ fields?: TypedFieldValueInput[];
3155
+ otherProperties?: UntypedKeyValueInput[];
3156
+ syncKey?: string | null;
3157
+ createdAt: string;
3158
+ updatedAt: string;
3159
+ }
3160
+ export interface CurrencyResponseDto {
3161
+ id: string;
3162
+ type: CurrencyType;
3163
+ code: string;
3164
+ /** Composite identifier in TYPE:CODE form (e.g. FIAT:USD). */
3165
+ currencyId: string;
3166
+ /** Number of minor-unit decimal places. */
3167
+ precision: number;
3168
+ name: string;
3169
+ symbol: string;
3170
+ isEnabled: boolean;
3171
+ isCustom: boolean;
3172
+ createdAt: string;
3173
+ updatedAt: string;
3174
+ }
1813
3175
  export type EventDefinitionResponseDto = OpaqueResponse;
1814
3176
  export type WebhookResponseDto = OpaqueResponse;
1815
3177
  export interface SyncSnapshotActor {
@@ -1850,9 +3212,84 @@ export interface SyncConfig {
1850
3212
  rules?: Record<string, SyncRuleConfig>;
1851
3213
  /** Keyed by TYPE:CODE (e.g. "FIAT:USD", "CRYPTO:BTC"). */
1852
3214
  currencies?: Record<string, SyncCurrencyConfig>;
3215
+ /**
3216
+ * Tag catalogue vocabulary — keyed by `<fieldKey>:<value>` (e.g.
3217
+ * "rule.tags:high-risk"). Unlike the other sections, an ABSENT section is
3218
+ * "unmanaged", not "empty": omitting it never retires live tags.
3219
+ */
3220
+ tagCatalogue?: Record<string, SyncTagCatalogueEntryConfig>;
3221
+ /**
3222
+ * Tag groups — keyed `<fieldKey>:<groupValue>` (e.g.
3223
+ * "customer.tags:primary-branch"). Same "absent means unmanaged" rule as
3224
+ * `tagCatalogue`, and applied BEFORE it so a namespaced tag can resolve
3225
+ * the group that owns it.
3226
+ */
3227
+ tagGroups?: Record<string, SyncTagGroupConfig>;
3228
+ /**
3229
+ * @deprecated Retired. Assignment policies were replaced by alert
3230
+ * workflows; the server rejects a bundle whose `assignmentPolicies`
3231
+ * section is non-empty. Configure stage assignment through
3232
+ * `config.alertWorkflows` instead.
3233
+ */
3234
+ assignmentPolicies?: Record<string, SyncAssignmentPolicyConfig>;
3235
+ /**
3236
+ * Tenant-wide attempt retention/coverage. Absent means unmanaged and
3237
+ * supplied fields update only those values.
3238
+ */
3239
+ behaviorSettings?: SyncBehaviorSettingsConfig;
1853
3240
  customerFieldPolicy?: Record<string, SyncCustomerFieldPolicyConfig>;
1854
3241
  accountStatusPolicy?: SyncAccountStatusPolicyConfig;
1855
3242
  }
3243
+ export interface SyncBehaviorSettingsConfig {
3244
+ attemptRetentionDays?: number;
3245
+ attemptCoverage?: 'ALL' | 'SELECTIVE';
3246
+ unknownEventTypes?: 'ACCEPT' | 'REJECT';
3247
+ }
3248
+ /**
3249
+ * Assignment policy (screening-alert auto-assignment routing). Targets are
3250
+ * org-local better-auth user ids / domain team uuids, validated against
3251
+ * membership on apply.
3252
+ *
3253
+ * @deprecated Retired with `SyncConfig.assignmentPolicies`; the server
3254
+ * rejects a non-empty section. Use `config.alertWorkflows`.
3255
+ */
3256
+ export interface SyncAssignmentPolicyConfig {
3257
+ name: string;
3258
+ description?: string;
3259
+ /** Default true. */
3260
+ enabled?: boolean;
3261
+ /** Evaluation order, ascending. First match wins. Must be unique per config. */
3262
+ priority: number;
3263
+ /** Qualifier tree; `{logic:'AND', conditions:[]}` = catch-all. */
3264
+ conditionTree: AssignmentPolicyConditionGroup;
3265
+ /** STATIC (default): fixed targets. TAG_MAP: route by `tagMap`. */
3266
+ targetMode?: AssignmentTargetMode;
3267
+ tagMap?: AssignmentPolicyTagMap;
3268
+ assignToUserIds?: string[];
3269
+ assignToTeamIds?: string[];
3270
+ }
3271
+ export interface SyncTagCatalogueEntryConfig {
3272
+ /** Human-readable display label. The value slug lives in the section key. */
3273
+ label: string;
3274
+ /** Fixed palette token (e.g. `neutral`, `red`, `blue`), not a hex value. */
3275
+ color?: string;
3276
+ description?: string;
3277
+ /**
3278
+ * Owning group's slug, unqualified (e.g. `primary-branch`). When set, the
3279
+ * section key must already carry the namespace:
3280
+ * `<fieldKey>:<group>:<tag>`.
3281
+ */
3282
+ group?: string;
3283
+ }
3284
+ export interface SyncTagGroupConfig {
3285
+ /** Human-readable display label. The namespace slug lives in the section key. */
3286
+ label: string;
3287
+ description?: string;
3288
+ color?: string;
3289
+ /** `SINGLE` allows one member tag per record. Defaults to `MULTI`. */
3290
+ cardinality?: TagGroupCardinality;
3291
+ sortOrder?: number;
3292
+ }
1856
3293
  export interface SyncCurrencyConfig {
1857
3294
  name: string;
1858
3295
  symbol?: string;
@@ -1872,10 +3309,16 @@ export interface SyncProductDefinitionConfig {
1872
3309
  name: string;
1873
3310
  description?: string;
1874
3311
  category: string;
1875
- baseType: string;
3312
+ /** Plain tag labels governed by the `product.tags` catalogue. */
3313
+ tags?: string[];
3314
+ /** @deprecated Use `tags`. Omitted values are persisted as `OTHER`. */
3315
+ baseType?: string;
1876
3316
  defaultCurrency: string;
3317
+ /** @deprecated Use `tags` when product classification is needed. */
1877
3318
  country?: string;
1878
3319
  supportedMethods: string[];
3320
+ /** Account field template inherited by accounts created from this product. */
3321
+ accountFieldConfig?: TypedFieldDefinition[];
1879
3322
  metadata?: Record<string, unknown>;
1880
3323
  }
1881
3324
  export interface SyncEventDefConfig {
@@ -1897,7 +3340,7 @@ export interface SyncRuleConfig {
1897
3340
  severity: 'HIGH' | 'MEDIUM' | 'LOW';
1898
3341
  tags?: string[];
1899
3342
  conditionTree: unknown;
1900
- actions?: Array<Record<string, unknown>>;
3343
+ actions?: RuleAction[];
1901
3344
  initialStatus?: 'DRAFT' | 'ACTIVE' | 'DISABLED';
1902
3345
  status?: 'DRAFT' | 'ACTIVE' | 'DISABLED';
1903
3346
  }
@@ -1937,6 +3380,10 @@ export interface SyncPlan {
1937
3380
  webhooks: SyncDiffOp[];
1938
3381
  rules: SyncDiffOp[];
1939
3382
  currencies: SyncDiffOp[];
3383
+ tagGroups: SyncDiffOp[];
3384
+ tagCatalogue: SyncDiffOp[];
3385
+ assignmentPolicies: SyncDiffOp[];
3386
+ behaviorSettings: SyncDiffOp[];
1940
3387
  immutableViolations: SyncImmutableViolation[];
1941
3388
  }
1942
3389
  /** `POST /v1/config/sync/validate` response. */
@@ -1968,7 +3415,914 @@ export interface SyncExportQuery {
1968
3415
  }
1969
3416
  export type ResetConfigResponseDto = OpaqueResponse;
1970
3417
  export type PushExchangeRatesResponseDto = OpaqueResponse;
1971
- export type BulkCurrencyStatusResponseDto = OpaqueResponse;
1972
- /** Bulk update body for `PATCH /v1/config/currencies/bulk-status` (schema undocumented). */
1973
- export type BulkCurrencyStatusInput = Record<string, unknown>;
3418
+ export interface BulkCurrencyStatusResponseDto {
3419
+ updatedCount: number;
3420
+ }
3421
+ /** Bulk update body for `PATCH /v1/config/currencies/bulk-status`. */
3422
+ export interface BulkCurrencyStatusInput {
3423
+ ids: string[];
3424
+ enabled: boolean;
3425
+ }
3426
+ /** Catalogue-governed tag: slugified `value` + human-readable `label`. */
3427
+ export interface CustomListTagValue {
3428
+ value: string;
3429
+ label: string;
3430
+ }
3431
+ /** Offset pagination meta returned by the custom-lists list endpoints. */
3432
+ export interface CustomListPageMeta {
3433
+ page: number;
3434
+ pageSize: number;
3435
+ totalItems: number;
3436
+ totalPages: number;
3437
+ hasNextPage: boolean;
3438
+ hasPreviousPage: boolean;
3439
+ }
3440
+ /**
3441
+ * A tenant-managed screening list. Enabled LIVE lists are checked by every
3442
+ * screening run (initial, ongoing, manual, ad-hoc search) alongside external
3443
+ * providers; the list's tags are shown against every match it produces.
3444
+ */
3445
+ export interface CustomScreeningListDto {
3446
+ id: string;
3447
+ name: string;
3448
+ description?: string | null;
3449
+ /** Disabled lists are skipped by screening but stay editable. */
3450
+ enabled: boolean;
3451
+ tags: CustomListTagValue[];
3452
+ entryCount: number;
3453
+ /** `LIVE` | `ARCHIVED`. Archived lists are read-only and never screened. */
3454
+ lifecycle: string;
3455
+ archivedAt?: string | null;
3456
+ createdAt: string;
3457
+ updatedAt: string;
3458
+ }
3459
+ export interface CustomListEntryDto {
3460
+ id: string;
3461
+ listId: string;
3462
+ name: string;
3463
+ entryType: 'INDIVIDUAL' | 'ENTITY';
3464
+ aliases: string[];
3465
+ /** YYYY-MM-DD. */
3466
+ dateOfBirth?: string | null;
3467
+ /** ISO 3166-1 alpha-3 country code. */
3468
+ country?: string | null;
3469
+ idNumber?: string | null;
3470
+ notes?: string | null;
3471
+ /** Caller identifier; bulk imports upsert rows carrying the same externalRef. */
3472
+ externalRef?: string | null;
3473
+ createdAt: string;
3474
+ updatedAt: string;
3475
+ }
3476
+ export interface CreateCustomScreeningListInput {
3477
+ name: string;
3478
+ description?: string;
3479
+ /** Defaults to true. */
3480
+ enabled?: boolean;
3481
+ tags?: CustomListTagValue[];
3482
+ }
3483
+ export interface UpdateCustomScreeningListInput {
3484
+ name?: string;
3485
+ description?: string;
3486
+ enabled?: boolean;
3487
+ tags?: CustomListTagValue[];
3488
+ }
3489
+ export interface CustomListEntryInput {
3490
+ name: string;
3491
+ /** Defaults to INDIVIDUAL. */
3492
+ entryType?: 'INDIVIDUAL' | 'ENTITY';
3493
+ aliases?: string[];
3494
+ /** YYYY-MM-DD. */
3495
+ dateOfBirth?: string;
3496
+ /** ISO 3166-1 alpha-3 country code. */
3497
+ country?: string;
3498
+ idNumber?: string;
3499
+ notes?: string;
3500
+ externalRef?: string;
3501
+ }
3502
+ export type UpdateCustomListEntryInput = Partial<CustomListEntryInput>;
3503
+ /** One rejected row from a bulk import, with the zero-based batch index. */
3504
+ export interface BulkCustomListImportRejectedRow {
3505
+ index: number;
3506
+ reason: string;
3507
+ name?: string | null;
3508
+ }
3509
+ /**
3510
+ * Result of a bulk entry import. The request succeeds even with rejections —
3511
+ * invalid rows are reported per-row instead of failing the batch.
3512
+ */
3513
+ export interface BulkCustomListImportResultDto {
3514
+ createdCount: number;
3515
+ updatedCount: number;
3516
+ rejectedCount: number;
3517
+ rejected: BulkCustomListImportRejectedRow[];
3518
+ }
3519
+ export interface CustomScreeningListListResponse {
3520
+ data: CustomScreeningListDto[];
3521
+ meta: CustomListPageMeta;
3522
+ }
3523
+ export interface CustomListEntryListResponse {
3524
+ data: CustomListEntryDto[];
3525
+ meta: CustomListPageMeta;
3526
+ }
3527
+ export interface AssignmentPolicyConditionLeaf {
3528
+ /** Qualifier field key (e.g. `customer.riskRating`, `screening.type`). */
3529
+ field: string;
3530
+ /** Operator from the rules-engine matrix (e.g. `=`, `IN`, `CONTAINS_ANY`, `>`). */
3531
+ operator: string;
3532
+ /** Comparison value. Omitted for null-aware operators (IS_NULL, IS_EMPTY, …). */
3533
+ value?: string;
3534
+ /** Result when the field resolves null under a non-null-aware operator. Default 'FALSE'. */
3535
+ whenMissing?: 'TRUE' | 'FALSE';
3536
+ }
3537
+ export interface AssignmentPolicyConditionGroup {
3538
+ logic: 'AND' | 'OR' | 'NOT';
3539
+ conditions: (AssignmentPolicyConditionLeaf | AssignmentPolicyConditionGroup)[];
3540
+ }
3541
+ export type AssignmentTargetMode = 'STATIC' | 'TAG_MAP';
3542
+ export interface AssignmentPolicyTagMapEntry {
3543
+ /** Catalogue value slug this entry routes (e.g. "branch-colombo-01"). */
3544
+ tag: string;
3545
+ assignToUserIds?: string[];
3546
+ assignToTeamIds?: string[];
3547
+ }
3548
+ /**
3549
+ * TAG_MAP routing table: routes by the customer's tag values (branch
3550
+ * workflow — one policy covers any number of branch→team mappings).
3551
+ * Entries are ordered; for a customer carrying several mapped values the
3552
+ * FIRST matching entry wins. No entry matching → the policy does not match
3553
+ * and evaluation falls through to the next one.
3554
+ */
3555
+ /** @deprecated Superseded by {@link AssignmentRouting}, which supports several blocks per policy. */
3556
+ export interface AssignmentPolicyTagMap {
3557
+ field: 'customer.tags' | 'customer.activeRiskTags' | 'customer.country';
3558
+ /**
3559
+ * Tag group whose membership this table routes, e.g. `primary-branch`.
3560
+ * When set, every entry's `tag` must be a member of that group — that is,
3561
+ * namespaced as `primary-branch:…` — and the server rejects the write
3562
+ * otherwise. Not consulted at match time; it exists so a row that could
3563
+ * never match is caught on save instead of failing silently forever.
3564
+ *
3565
+ * Null / omitted for a table over ungrouped tags, and required to be null
3566
+ * for `customer.country`, which has no tag catalogue.
3567
+ */
3568
+ groupValue?: string | null;
3569
+ entries: AssignmentPolicyTagMapEntry[];
3570
+ }
3571
+ /**
3572
+ * How a policy resolves its targets, when not the fixed
3573
+ * `assignToUserIds` / `assignToTeamIds`. Exactly ONE of these — anything more
3574
+ * (ordering, cross-field matching) is expressed as additional policies with
3575
+ * their own qualifiers, which is what the policy list already does.
3576
+ *
3577
+ * Supersedes {@link AssignmentPolicyTagMap}. A policy written before this
3578
+ * existed is served here in the current shape, so clients read one thing.
3579
+ */
3580
+ export type AssignmentRouting = {
3581
+ /**
3582
+ * Route to whoever is standing-assigned the customer. Carries no
3583
+ * targets of its own — they come from the customer record, so this
3584
+ * can replace a per-branch routing table entirely.
3585
+ *
3586
+ * Does NOT match an unassigned customer: the alert falls through to
3587
+ * the next policy.
3588
+ */
3589
+ kind: 'CUSTOMER_ASSIGNEE';
3590
+ /** Which side of the assignment to use. Default BOTH. */
3591
+ use?: 'BOTH' | 'TEAMS' | 'USERS' | null;
3592
+ } | {
3593
+ /** Look the customer up in one tag group's table; first match wins. */
3594
+ kind: 'TAG_GROUP';
3595
+ field: 'customer.tags' | 'customer.activeRiskTags' | 'customer.country';
3596
+ /**
3597
+ * Tag group whose membership this table routes. Every entry must be a
3598
+ * member (`primary-branch:…`), or the write is rejected. Null routes
3599
+ * ungrouped values, or country, which has no catalogue.
3600
+ */
3601
+ groupValue?: string | null;
3602
+ entries: AssignmentPolicyTagMapEntry[];
3603
+ };
3604
+ export interface AssignmentPolicyResponseDto {
3605
+ id: string;
3606
+ name: string;
3607
+ description: string | null;
3608
+ enabled: boolean;
3609
+ /** Evaluation order, ascending. First match wins. */
3610
+ priority: number;
3611
+ /** Qualifier tree. `{logic:'AND', conditions:[]}` = catch-all. */
3612
+ conditionTree: AssignmentPolicyConditionGroup;
3613
+ /** STATIC: fixed targets. TAG_MAP: routed via `routing`. */
3614
+ targetMode: AssignmentTargetMode;
3615
+ /** @deprecated Read `routing`. Null on anything saved since blocks landed. */
3616
+ tagMap: AssignmentPolicyTagMap | null;
3617
+ /** TAG_MAP: the ordered routing blocks. Legacy rows are served as one block. */
3618
+ routing: AssignmentRouting | null;
3619
+ assignToUserIds: string[];
3620
+ assignToTeamIds: string[];
3621
+ syncKey: string | null;
3622
+ createdAt: string;
3623
+ updatedAt: string;
3624
+ }
3625
+ export interface CreateAssignmentPolicyDto {
3626
+ name: string;
3627
+ description?: string | null;
3628
+ /** Default true. */
3629
+ enabled?: boolean;
3630
+ /** Omitted = catch-all. */
3631
+ conditionTree?: AssignmentPolicyConditionGroup;
3632
+ /** Default STATIC. TAG_MAP requires `routing` and ignores the static targets. */
3633
+ targetMode?: AssignmentTargetMode;
3634
+ routing?: AssignmentRouting | null;
3635
+ /** STATIC mode: at least one user or team target is required. */
3636
+ assignToUserIds?: string[];
3637
+ assignToTeamIds?: string[];
3638
+ syncKey?: string | null;
3639
+ }
3640
+ export interface UpdateAssignmentPolicyDto {
3641
+ name?: string;
3642
+ description?: string | null;
3643
+ enabled?: boolean;
3644
+ conditionTree?: AssignmentPolicyConditionGroup;
3645
+ targetMode?: AssignmentTargetMode;
3646
+ routing?: AssignmentRouting | null;
3647
+ assignToUserIds?: string[];
3648
+ assignToTeamIds?: string[];
3649
+ }
3650
+ export interface ReorderAssignmentPoliciesDto {
3651
+ /** Complete permutation of the org's policy ids in the desired evaluation order. */
3652
+ orderedIds: string[];
3653
+ }
3654
+ export interface TeamRefDto {
3655
+ teamId: string;
3656
+ name: string;
3657
+ memberCount: number;
3658
+ /** Catalogue-governed tags (`team.tags`). */
3659
+ tags: TagValue[];
3660
+ }
3661
+ export interface TeamMemberDto {
3662
+ userId: string;
3663
+ name: string;
3664
+ email?: string;
3665
+ role?: string;
3666
+ avatar?: string;
3667
+ }
3668
+ export interface TeamDto {
3669
+ id: string;
3670
+ name: string;
3671
+ description?: string | null;
3672
+ archivedAt?: string | null;
3673
+ /** Catalogue-governed tags (`team.tags`). */
3674
+ tags: TagValue[];
3675
+ memberCount: number;
3676
+ members: TeamMemberDto[];
3677
+ createdAt: string;
3678
+ updatedAt: string;
3679
+ }
3680
+ export interface CreateTeamDto {
3681
+ name: string;
3682
+ description?: string | null;
3683
+ /** Initial members (better-auth user ids). Each must be a member of the organization. */
3684
+ memberUserIds?: string[];
3685
+ /**
3686
+ * Catalogue-governed tags (`team.tags`). Every value must already exist in
3687
+ * the org tag catalogue — the catalogue is closed.
3688
+ */
3689
+ tags?: TagValueInput[];
3690
+ }
3691
+ export interface UpdateTeamDto {
3692
+ name?: string;
3693
+ description?: string | null;
3694
+ /**
3695
+ * Replaces the full tag set — send every tag the team should end up with,
3696
+ * not a delta. Omit to leave the tags unchanged; pass `[]` to clear them.
3697
+ */
3698
+ tags?: TagValueInput[];
3699
+ }
3700
+ export interface TeamMemberIdsDto {
3701
+ userIds: string[];
3702
+ }
3703
+ /** An array with at least one item. */
3704
+ export type NonEmptyArray<T> = [T, ...T[]];
3705
+ /**
3706
+ * Assignment targets. The API rejects a request unless at least one target
3707
+ * array is present and non-empty.
3708
+ */
3709
+ export type CustomerAssignmentInput = {
3710
+ userIds: NonEmptyArray<string>;
3711
+ teamIds?: string[];
3712
+ } | {
3713
+ userIds?: string[];
3714
+ teamIds: NonEmptyArray<string>;
3715
+ };
3716
+ /**
3717
+ * Bulk assignment preflight-validates every customer and target before
3718
+ * assignment begins.
3719
+ */
3720
+ export type BulkCustomerAssignmentInput = CustomerAssignmentInput & {
3721
+ customerIds: NonEmptyArray<string>;
3722
+ };
3723
+ export interface CustomerAssignmentResponse {
3724
+ id: string;
3725
+ assignedToUserIds: string[];
3726
+ assignedToTeamIds: string[];
3727
+ }
3728
+ export interface BulkCustomerAssignmentResult {
3729
+ /** How many customers actually changed. Already-assigned targets are skipped. */
3730
+ updated: number;
3731
+ }
3732
+ /** @deprecated Use `CustomerAssignmentInput`. */
3733
+ export type CustomerAssignmentDto = CustomerAssignmentInput;
3734
+ /** @deprecated Use `BulkCustomerAssignmentInput`. */
3735
+ export type BulkCustomerAssignmentDto = BulkCustomerAssignmentInput;
3736
+ /** @deprecated Use `CustomerAssignmentResponse`. */
3737
+ export type CustomerAssignmentResponseDto = CustomerAssignmentResponse;
3738
+ /** @deprecated Use `BulkCustomerAssignmentResult`. */
3739
+ export type BulkAssignResultDto = BulkCustomerAssignmentResult;
3740
+ export type * from './alert-workflow-types';
3741
+ export interface AlertWorkflowSettings {
3742
+ id: string;
3743
+ name: string;
3744
+ alertType: import('./alert-workflow-types').WorkflowAlertType;
3745
+ revision: number;
3746
+ publishedVersion: number;
3747
+ draft: import('./alert-workflow-types').WorkflowDefinition;
3748
+ published: import('./alert-workflow-types').WorkflowPublication | null;
3749
+ }
3750
+ export interface SaveAlertWorkflowInput {
3751
+ id?: string;
3752
+ name: string;
3753
+ expectedRevision: number;
3754
+ definition: import('./alert-workflow-types').WorkflowDefinition;
3755
+ publish: boolean;
3756
+ }
3757
+ /** Organization-wide creation experience. Existing alerts retain their saved behavior. */
3758
+ export type AlertWorkflowExperience = 'SIMPLE' | 'DEFINED';
3759
+ export interface AlertWorkflowExperienceSettings {
3760
+ id: string;
3761
+ experience: AlertWorkflowExperience;
3762
+ revision: number;
3763
+ }
3764
+ export interface SaveAlertWorkflowExperienceInput {
3765
+ experience: AlertWorkflowExperience;
3766
+ expectedRevision: number;
3767
+ }
3768
+ /** Published workflow snapshot. Older entries may lack a recoverable definition. */
3769
+ export interface AlertWorkflowVersion {
3770
+ id: string;
3771
+ version: number;
3772
+ isCurrent: boolean;
3773
+ definition: import('./alert-workflow-types').WorkflowDefinition | null;
3774
+ publishedAt: string | null;
3775
+ publishedBy: string | null;
3776
+ }
3777
+ export interface RestoreAlertWorkflowInput {
3778
+ version: number;
3779
+ expectedRevision: number;
3780
+ }
3781
+ export type PaymentInstrumentType = 'CARD' | 'VIRTUAL_CARD' | 'WALLET_TOKEN' | 'ACH_CREDENTIAL' | 'ONLINE_LOGIN' | 'DIGITAL_TOKEN' | 'CREDIT_CARD' | 'DEBIT_CARD' | 'PAYMENT_TOKEN' | 'API_KEY' | 'CRYPTO_WALLET' | 'OTHER';
3782
+ export type PaymentInstrumentStatus = 'ACTIVE' | 'BLOCKED' | 'EXPIRED' | 'LOST' | 'STOLEN' | 'FROZEN' | 'INACTIVE' | 'REVOKED' | 'COMPROMISED';
3783
+ export type ChannelEndpointStatus = 'ACTIVE' | 'INACTIVE' | 'SUSPENDED' | 'RETIRED' | 'UNKNOWN';
3784
+ export interface SessionDto {
3785
+ id: string;
3786
+ externalSessionId: string;
3787
+ customerId?: string | null;
3788
+ deviceId?: string | null;
3789
+ startedAt: string;
3790
+ lastActivityAt: string;
3791
+ metadata?: Record<string, unknown> | null;
3792
+ createdAt: string;
3793
+ }
3794
+ export interface UpdateSessionDto {
3795
+ customerId?: string | null;
3796
+ deviceId?: string | null;
3797
+ startedAt?: string;
3798
+ lastActivityAt?: string;
3799
+ metadata?: Record<string, unknown> | null;
3800
+ }
3801
+ export interface ChannelEndpointDto {
3802
+ id: string;
3803
+ externalId: string;
3804
+ kind: string;
3805
+ provider: string;
3806
+ displayName?: string | null;
3807
+ status: ChannelEndpointStatus;
3808
+ metadata?: Record<string, unknown> | null;
3809
+ firstSeenAt: string;
3810
+ lastSeenAt: string;
3811
+ createdAt: string;
3812
+ updatedAt: string;
3813
+ /** Catalogue-governed tags (`channelEndpoint.tags`). */
3814
+ tags: TagValue[];
3815
+ /** Set by the latest risk assessment. */
3816
+ riskRating?: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL' | null;
3817
+ }
3818
+ export interface UpdateChannelEndpointDto {
3819
+ displayName?: string | null;
3820
+ status?: ChannelEndpointStatus;
3821
+ metadata?: Record<string, unknown> | null;
3822
+ firstSeenAt?: string;
3823
+ lastSeenAt?: string;
3824
+ }
3825
+ export type PaymentInstrumentRelationshipSource = 'EXPLICIT' | 'TRANSACTION' | 'ANALYST' | 'RESOLUTION';
3826
+ export type PaymentInstrumentFingerprintType = 'CARD_PAN' | 'NETWORK_TOKEN' | 'WALLET_TOKEN' | 'ACH_CREDENTIAL' | 'ONLINE_LOGIN' | 'API_KEY' | 'CRYPTO_ADDRESS' | 'EXTERNAL_ID' | 'OTHER';
3827
+ export interface PaymentInstrumentFingerprintDto {
3828
+ type: PaymentInstrumentFingerprintType;
3829
+ /** Raw credential used only for protected fingerprint resolution; never persisted. */
3830
+ value: string;
3831
+ }
3832
+ export interface PaymentInstrumentPayloadDto {
3833
+ /** Internal Payment Instrument ID. */
3834
+ paymentInstrumentId?: string;
3835
+ /** Integration-owned stable Payment Instrument ID. */
3836
+ externalId?: string;
3837
+ type?: PaymentInstrumentType;
3838
+ fingerprint?: PaymentInstrumentFingerprintDto;
3839
+ }
3840
+ type PaymentInstrumentDecimalDigit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
3841
+ /** A safe masked payment-instrument suffix containing exactly four decimal digits. */
3842
+ export type PaymentInstrumentLast4 = `${PaymentInstrumentDecimalDigit}${PaymentInstrumentDecimalDigit}${PaymentInstrumentDecimalDigit}${PaymentInstrumentDecimalDigit}`;
3843
+ export interface AttemptPaymentInstrumentDto extends PaymentInstrumentPayloadDto {
3844
+ /** Safe issuer identification number for BIN/IIN attack analysis. */
3845
+ iin?: string;
3846
+ /** Safe masked suffix containing exactly four decimal digits. */
3847
+ last4?: PaymentInstrumentLast4;
3848
+ }
3849
+ export interface PaymentInstrumentDto {
3850
+ id: string;
3851
+ organizationId: string;
3852
+ externalId?: string | null;
3853
+ type: PaymentInstrumentType;
3854
+ status: PaymentInstrumentStatus;
3855
+ parentPaymentInstrumentId?: string | null;
3856
+ displayName?: string | null;
3857
+ createdSource: PaymentInstrumentRelationshipSource;
3858
+ managedAt?: string | null;
3859
+ firstSeenAt?: string | null;
3860
+ lastUsedAt?: string | null;
3861
+ issuedAt?: string | null;
3862
+ expiresAt?: string | null;
3863
+ riskFlags: string[];
3864
+ metadata: Record<string, unknown>;
3865
+ createdAt: string;
3866
+ updatedAt: string;
3867
+ }
3868
+ export interface CreatePaymentInstrumentDto {
3869
+ externalId?: string;
3870
+ type: PaymentInstrumentType;
3871
+ status?: PaymentInstrumentStatus;
3872
+ parentPaymentInstrumentId?: string;
3873
+ displayName?: string;
3874
+ createdSource: PaymentInstrumentRelationshipSource;
3875
+ managedAt?: string;
3876
+ firstSeenAt?: string;
3877
+ issuedAt?: string;
3878
+ expiresAt?: string;
3879
+ metadata?: Record<string, unknown>;
3880
+ }
3881
+ export interface UpdatePaymentInstrumentDto {
3882
+ status?: PaymentInstrumentStatus;
3883
+ parentPaymentInstrumentId?: string | null;
3884
+ displayName?: string | null;
3885
+ managedAt?: string | null;
3886
+ issuedAt?: string | null;
3887
+ expiresAt?: string | null;
3888
+ metadata?: Record<string, unknown>;
3889
+ }
3890
+ export interface LinkPaymentInstrumentAccountDto {
3891
+ accountId: string;
3892
+ relationshipType: 'ACCESS_CREDENTIAL' | 'FUNDING_SOURCE' | 'SETTLEMENT_DESTINATION' | 'OTHER';
3893
+ source: PaymentInstrumentRelationshipSource;
3894
+ validFrom?: string;
3895
+ validTo?: string;
3896
+ confidence?: number;
3897
+ }
3898
+ export interface LinkPaymentInstrumentCustomerDto {
3899
+ customerId: string;
3900
+ role: 'PRIMARY_HOLDER' | 'AUTHORIZED_USER' | 'CORPORATE_USER' | 'CUSTODIAN' | 'OBSERVED_USER';
3901
+ source: PaymentInstrumentRelationshipSource;
3902
+ validFrom?: string;
3903
+ validTo?: string;
3904
+ confidence?: number;
3905
+ }
3906
+ export interface PaymentInstrumentAccountRelationshipDto {
3907
+ id: string;
3908
+ accountId: string;
3909
+ paymentInstrumentId: string;
3910
+ relationshipType: 'ACCESS_CREDENTIAL' | 'FUNDING_SOURCE' | 'SETTLEMENT_DESTINATION' | 'OTHER';
3911
+ validFrom: string;
3912
+ validTo?: string | null;
3913
+ source: PaymentInstrumentRelationshipSource;
3914
+ confidence?: number | null;
3915
+ createdAt: string;
3916
+ updatedAt: string;
3917
+ }
3918
+ export interface PaymentInstrumentCustomerRelationshipDto {
3919
+ id: string;
3920
+ customerId: string;
3921
+ paymentInstrumentId: string;
3922
+ role: 'PRIMARY_HOLDER' | 'AUTHORIZED_USER' | 'CORPORATE_USER' | 'CUSTODIAN' | 'OBSERVED_USER';
3923
+ validFrom: string;
3924
+ validTo?: string | null;
3925
+ source: PaymentInstrumentRelationshipSource;
3926
+ confidence?: number | null;
3927
+ createdAt: string;
3928
+ updatedAt: string;
3929
+ }
3930
+ /** @deprecated Use the account- or customer-specific relationship response type. */
3931
+ export type PaymentInstrumentRelationshipDto = PaymentInstrumentAccountRelationshipDto | PaymentInstrumentCustomerRelationshipDto;
3932
+ export interface ConnectionEdge<T> {
3933
+ node: T;
3934
+ /** Opaque offset cursor. */
3935
+ cursor: string;
3936
+ }
3937
+ export interface ConnectionPageInfo {
3938
+ hasNextPage: boolean;
3939
+ hasPreviousPage: boolean;
3940
+ startCursor?: string;
3941
+ endCursor?: string;
3942
+ }
3943
+ export interface ConnectionPageMeta {
3944
+ page: number;
3945
+ pageSize: number;
3946
+ totalItems: number;
3947
+ totalPages: number;
3948
+ hasNextPage: boolean;
3949
+ hasPreviousPage: boolean;
3950
+ }
3951
+ /** Where a Risk Signal came from. Immutable provenance, set by the server. */
3952
+ export type RiskSignalSourceType = 'EVENT' | 'RULE' | 'MANUAL';
3953
+ export interface RiskSignal {
3954
+ id: string;
3955
+ /** Caller-supplied idempotency key, for explicitly created signals. */
3956
+ externalId?: string | null;
3957
+ /** Dotted signal type. Tenant vocabulary — not a fixed platform enum. */
3958
+ type: string;
3959
+ resourceType: RiskSignalResourceType;
3960
+ resourceId: string;
3961
+ /** Strength at `occurredAt`. Immutable. */
3962
+ weight: number;
3963
+ /** Half-life in seconds. Immutable. */
3964
+ halfLifeSeconds: number;
3965
+ /** Half-life as an ISO 8601 duration, e.g. `P7D`. Immutable. */
3966
+ halfLife: string;
3967
+ occurredAt: string;
3968
+ /** Decayed weight at the requested `asOf` time. */
3969
+ effectiveWeight: number;
3970
+ sourceType: RiskSignalSourceType;
3971
+ /** The Event id, evaluation id, or acting user id behind this signal. */
3972
+ sourceId: string;
3973
+ /** Safe audit facts only — never secrets or raw source payloads. */
3974
+ sourceSnapshot: Record<string, unknown>;
3975
+ createdBy: unknown;
3976
+ createdAt: string;
3977
+ }
3978
+ /**
3979
+ * Explicit Risk Signal creation.
3980
+ *
3981
+ * The caller does not choose the source: the server sets `sourceType: 'MANUAL'`
3982
+ * and captures the authenticated actor. There is deliberately no way to claim a
3983
+ * signal came from an Event or a Rule.
3984
+ */
3985
+ export interface CreateRiskSignalInput {
3986
+ /**
3987
+ * Your idempotency key for this signal (max 255 chars). Resubmitting the
3988
+ * same `externalId` returns the original signal rather than adding a
3989
+ * second one.
3990
+ */
3991
+ externalId?: string | null;
3992
+ /** Dotted signal type, e.g. `analyst.concerning_account_behaviour`. */
3993
+ type: string;
3994
+ resourceType: RiskSignalResourceType;
3995
+ resourceId: string;
3996
+ /** Strength at `occurredAt`. Must be greater than zero. */
3997
+ weight: number;
3998
+ /**
3999
+ * Half-life as a positive ISO 8601 duration, e.g. `P14D`. Calendar units
4000
+ * (Y/M) are rejected — they have no fixed length.
4001
+ */
4002
+ halfLife: string;
4003
+ /** When the evidence occurred (ISO 8601). Defaults to now. */
4004
+ occurredAt?: string | null;
4005
+ /** Analyst justification, recorded in the signal's source snapshot (max 2000 chars). */
4006
+ note?: string | null;
4007
+ }
4008
+ export interface ListRiskSignalsQuery {
4009
+ /** Required. Which kind of resource to read signals for. */
4010
+ resourceType: RiskSignalResourceType;
4011
+ /** Required. Id of that resource. */
4012
+ resourceId: string;
4013
+ /**
4014
+ * ISO 8601 timestamp the decay is computed as of. Defaults to server time;
4015
+ * a historical `asOf` returns what the resource looked like at that moment.
4016
+ */
4017
+ asOf?: string;
4018
+ /** Restrict which signal types contribute. Repeatable. */
4019
+ type?: string[];
4020
+ /** Restrict which provenances contribute. Repeatable. */
4021
+ sourceType?: RiskSignalSourceType[];
4022
+ /** 1–200. Defaults to 50. */
4023
+ limit?: number;
4024
+ /** Defaults to 0. */
4025
+ offset?: number;
4026
+ }
4027
+ /**
4028
+ * A resource's Risk Signals with their decayed weights, plus the aggregate.
4029
+ *
4030
+ * `type` / `sourceType` filter which records contribute; they never change how
4031
+ * far a contributing signal has decayed — age is always measured to `asOf`.
4032
+ */
4033
+ export interface RiskSignalListResponse {
4034
+ edges: ConnectionEdge<RiskSignal>[];
4035
+ pageInfo: ConnectionPageInfo;
4036
+ totalCount: number;
4037
+ /** The time the decay was computed as of. */
4038
+ asOf: string;
4039
+ /**
4040
+ * Sum of every contributing signal's effective weight at `asOf`. Computed
4041
+ * on read — not a cached score on the resource.
4042
+ */
4043
+ aggregateEffectiveWeight: number;
4044
+ /** Number of contributing signal records. */
4045
+ contributingCount: number;
4046
+ /** Latest contributing occurrence. */
4047
+ latestAt?: string | null;
4048
+ /** Distinct contributing signal types. */
4049
+ uniqueTypeCount: number;
4050
+ }
4051
+ export type EmployeeStatus = 'ACTIVE' | 'INACTIVE' | 'SUSPENDED' | 'TERMINATED';
4052
+ export type BranchStatus = 'ACTIVE' | 'INACTIVE' | 'CLOSED';
4053
+ export interface Employee {
4054
+ id: string;
4055
+ /** The institution's own staff identifier. */
4056
+ externalEmployeeId?: string | null;
4057
+ fullName: string;
4058
+ email?: string | null;
4059
+ jobTitle?: string | null;
4060
+ department?: string | null;
4061
+ /** Home Branch id. */
4062
+ branchId?: string | null;
4063
+ status: EmployeeStatus;
4064
+ /**
4065
+ * Optional link to the Dossiers organization member who is this same
4066
+ * person. Null for employees without a Dossiers login. Never an identity
4067
+ * substitute — Events and Risk Signals always attach by Employee id.
4068
+ */
4069
+ orgMemberId?: string | null;
4070
+ metadata: Record<string, unknown>;
4071
+ createdAt: string;
4072
+ updatedAt: string;
4073
+ lifecycle: Lifecycle;
4074
+ archivedAt?: string | null;
4075
+ tombstonedAt?: string | null;
4076
+ }
4077
+ export interface CreateEmployeeInput {
4078
+ fullName: string;
4079
+ /**
4080
+ * The institution's own staff identifier. Unique within the organization;
4081
+ * lets ingestion resolve an Employee without a Dossiers UUID round-trip.
4082
+ */
4083
+ externalEmployeeId?: string | null;
4084
+ email?: string | null;
4085
+ jobTitle?: string | null;
4086
+ department?: string | null;
4087
+ /** Home Branch id. Must belong to the same organization. */
4088
+ branchId?: string | null;
4089
+ /** Defaults to `ACTIVE`. */
4090
+ status?: EmployeeStatus;
4091
+ /**
4092
+ * Optional link to the Dossiers organization member who is this same
4093
+ * person. Leave unset for employees without a Dossiers login.
4094
+ */
4095
+ orgMemberId?: string | null;
4096
+ }
4097
+ export interface UpdateEmployeeInput {
4098
+ fullName?: string;
4099
+ email?: string | null;
4100
+ jobTitle?: string | null;
4101
+ department?: string | null;
4102
+ branchId?: string | null;
4103
+ status?: EmployeeStatus;
4104
+ orgMemberId?: string | null;
4105
+ metadata?: Record<string, unknown>;
4106
+ }
4107
+ export interface EmployeeListResponse {
4108
+ data: Employee[];
4109
+ edges: ConnectionEdge<Employee>[];
4110
+ pageInfo: ConnectionPageInfo;
4111
+ meta: ConnectionPageMeta;
4112
+ }
4113
+ export interface Branch {
4114
+ id: string;
4115
+ /** The institution's own branch identifier. */
4116
+ externalBranchId?: string | null;
4117
+ name: string;
4118
+ code?: string | null;
4119
+ country?: string | null;
4120
+ city?: string | null;
4121
+ /**
4122
+ * Owning Institution id, when the tenant models its own legal entities as
4123
+ * Institutions.
4124
+ */
4125
+ institutionId?: string | null;
4126
+ status: BranchStatus;
4127
+ metadata: Record<string, unknown>;
4128
+ createdAt: string;
4129
+ updatedAt: string;
4130
+ lifecycle: Lifecycle;
4131
+ archivedAt?: string | null;
4132
+ tombstonedAt?: string | null;
4133
+ }
4134
+ export interface CreateBranchInput {
4135
+ name: string;
4136
+ /**
4137
+ * The institution's own branch identifier. Unique within the organization;
4138
+ * lets ingestion resolve a Branch without a Dossiers UUID round-trip.
4139
+ */
4140
+ externalBranchId?: string | null;
4141
+ code?: string | null;
4142
+ country?: string | null;
4143
+ city?: string | null;
4144
+ institutionId?: string | null;
4145
+ /** Defaults to `ACTIVE`. */
4146
+ status?: BranchStatus;
4147
+ }
4148
+ export interface UpdateBranchInput {
4149
+ name?: string;
4150
+ code?: string | null;
4151
+ country?: string | null;
4152
+ city?: string | null;
4153
+ institutionId?: string | null;
4154
+ status?: BranchStatus;
4155
+ metadata?: Record<string, unknown>;
4156
+ }
4157
+ export interface BranchListResponse {
4158
+ data: Branch[];
4159
+ edges: ConnectionEdge<Branch>[];
4160
+ pageInfo: ConnectionPageInfo;
4161
+ meta: ConnectionPageMeta;
4162
+ }
4163
+ export type PartyRelationshipDirection = 'DIRECTED' | 'SYMMETRIC';
4164
+ export type PartyRelationshipPartyType = 'CUSTOMER' | 'COUNTERPARTY';
4165
+ export interface PartyRelationshipType {
4166
+ id: string;
4167
+ key: string;
4168
+ label: string;
4169
+ description?: string | null;
4170
+ direction: PartyRelationshipDirection;
4171
+ createdAt: string;
4172
+ updatedAt: string;
4173
+ }
4174
+ export interface CreatePartyRelationshipTypeInput {
4175
+ key: string;
4176
+ label: string;
4177
+ description?: string;
4178
+ direction: PartyRelationshipDirection;
4179
+ }
4180
+ /** One end of a relationship, resolved to something displayable. */
4181
+ export interface PartyRef {
4182
+ type: PartyRelationshipPartyType;
4183
+ id: string;
4184
+ label: string;
4185
+ }
4186
+ export interface PartyRelationship {
4187
+ id: string;
4188
+ typeId: string;
4189
+ relationshipType: PartyRelationshipType;
4190
+ sourceType: PartyRelationshipPartyType;
4191
+ sourceId: string;
4192
+ targetType: PartyRelationshipPartyType;
4193
+ targetId: string;
4194
+ sourceParty?: PartyRef | null;
4195
+ targetParty?: PartyRef | null;
4196
+ description?: string | null;
4197
+ validFrom?: string | null;
4198
+ validTo?: string | null;
4199
+ source?: string | null;
4200
+ confidence?: number | null;
4201
+ createdAt: string;
4202
+ updatedAt: string;
4203
+ }
4204
+ export interface CreatePartyRelationshipInput {
4205
+ typeId: string;
4206
+ sourceType: PartyRelationshipPartyType;
4207
+ sourceId: string;
4208
+ targetType: PartyRelationshipPartyType;
4209
+ targetId: string;
4210
+ description?: string;
4211
+ validFrom?: string;
4212
+ validTo?: string;
4213
+ source?: string;
4214
+ confidence?: number;
4215
+ }
4216
+ export type AlertRiskLevel = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
4217
+ /**
4218
+ * An org-defined alert type. CUSTOM alerts name one of these and carry typed
4219
+ * field values validated against `fields` (Tier A) when raised. Editing the
4220
+ * schema never re-validates existing alerts.
4221
+ */
4222
+ export interface CustomAlertTypeResponseDto {
4223
+ id: string;
4224
+ /** Stable snake_case machine name; integrators raise alerts by it. Immutable. */
4225
+ name: string;
4226
+ displayName: string;
4227
+ description: string | null;
4228
+ fields: TypedFieldDefinition[];
4229
+ /** Applied when the creator does not choose a risk level. */
4230
+ defaultRiskLevel: AlertRiskLevel;
4231
+ lifecycle: 'LIVE' | 'ARCHIVED' | 'TOMBSTONED';
4232
+ createdAt: string;
4233
+ updatedAt: string;
4234
+ archivedAt?: string | null;
4235
+ tombstonedAt?: string | null;
4236
+ }
4237
+ export interface CreateCustomAlertTypeDto {
4238
+ /** snake_case, starts with a letter, max 64 chars. */
4239
+ name: string;
4240
+ displayName: string;
4241
+ description?: string | null;
4242
+ fields?: TypedFieldDefinition[];
4243
+ /** Defaults to MEDIUM. */
4244
+ defaultRiskLevel?: AlertRiskLevel;
4245
+ }
4246
+ export interface UpdateCustomAlertTypeDto {
4247
+ displayName?: string;
4248
+ description?: string | null;
4249
+ /** Replaces the schema. Applies to alerts raised afterwards only. */
4250
+ fields?: TypedFieldDefinition[];
4251
+ defaultRiskLevel?: AlertRiskLevel;
4252
+ }
4253
+ /** A resource to link to an alert. `resourceType` is case-insensitive (`customer` and `CUSTOMER` both work). */
4254
+ export interface AlertResourceRefDto {
4255
+ resourceType: string;
4256
+ resourceId: string;
4257
+ }
4258
+ export interface AlertResourceDto {
4259
+ /** Link id — pass this to `removeResource`, not the target's id. */
4260
+ id: string;
4261
+ resourceType: string;
4262
+ resourceId: string;
4263
+ addedBy: {
4264
+ userId: string;
4265
+ name: string;
4266
+ };
4267
+ createdAt: string;
4268
+ }
4269
+ export interface CreateCustomAlertDto {
4270
+ /**
4271
+ * Optional. Machine name (or id) of a LIVE custom alert type. Omit for a
4272
+ * free-form alert. With a type that declares fields, `fields` are validated
4273
+ * against its schema; otherwise they are self-declaring.
4274
+ */
4275
+ alertType?: string | null;
4276
+ subject: string;
4277
+ /** Defaults to the type's `defaultRiskLevel`. */
4278
+ riskLevel?: AlertRiskLevel;
4279
+ /** Customer the alert is about. Archived customers are allowed. */
4280
+ customerId?: string | null;
4281
+ /** Markdown narrative. */
4282
+ notes?: string | null;
4283
+ /** Structured details. Validated against the type's schema when one is given, self-declaring otherwise. */
4284
+ fields?: TypedFieldValueInput[];
4285
+ /** Org member ids to assign at creation; they are notified. */
4286
+ assignedToUserIds?: string[];
4287
+ /** Team ids to assign at creation; members are notified. */
4288
+ assignedToTeamIds?: string[];
4289
+ resources?: AlertResourceRefDto[];
4290
+ /**
4291
+ * Idempotency key, scoped per **organization** (not per API key): two
4292
+ * keys replaying the same upstream event converge on one alert.
4293
+ */
4294
+ externalRequestId?: string | null;
4295
+ }
4296
+ export interface UpdateAlertNotesDto {
4297
+ /** Markdown. Null or empty clears the notes. */
4298
+ notes?: string | null;
4299
+ }
4300
+ /** Flat REST view of an alert (any type). The GraphQL surface carries the rich per-type shape. */
4301
+ export interface AlertResponseDto {
4302
+ id: string;
4303
+ type: 'SCREENING' | 'RULE_TRIGGER' | 'CUSTOM';
4304
+ customAlertTypeId: string | null;
4305
+ status: 'OPEN' | 'CLOSED';
4306
+ subject: string;
4307
+ riskLevel: AlertRiskLevel;
4308
+ customerId: string | null;
4309
+ assignedToUserIds: string[];
4310
+ assignedToTeamIds: string[];
4311
+ /** Stored typed-field bag (`{ [key]: { type, value } }`) for CUSTOM alerts; `{}` otherwise. */
4312
+ fields: Record<string, unknown>;
4313
+ notes: string | null;
4314
+ createdBy: {
4315
+ type: 'USER' | 'SERVICE' | 'UNRESOLVED';
4316
+ userId: string;
4317
+ name: string;
4318
+ } | null;
4319
+ externalRequestId: string | null;
4320
+ disposition: string | null;
4321
+ dispositionReason: string | null;
4322
+ closedAt: string | null;
4323
+ createdAt: string;
4324
+ updatedAt: string;
4325
+ /** Present on `alerts.create` and `alerts.get`. */
4326
+ resources?: AlertResourceDto[];
4327
+ }
1974
4328
  //# sourceMappingURL=types.d.ts.map