@dossier-wiki/os-sdk 1.4.0 → 1.4.2-staging.5.1

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/docs/REFERENCE.md CHANGED
@@ -44,8 +44,20 @@ the recorded event-time bounds.
44
44
  `status`, `preferredName`, `aliases`, `dateOfBirth`, `nationality[]`,
45
45
  `countryOfResidence[]`, `taxId`, `emails[]`, `phones[]`,
46
46
  `identificationDocuments[]`, `faceImageFileIds[]`, `addresses[]`, `tags[]`,
47
- `assignedToUserIds[]`, and `assignedToTeamIds[]`. Contact entries are
48
- `{ value, primary }`.
47
+ `assignedToUserIds[]`, `assignedToTeamIds[]`, `profileTemplateKey`, `fields[]`,
48
+ and `deferInitialScreening`. Contact entries are `{ value, primary }`.
49
+ `deferInitialScreening: true` skips the initial screening that creation
50
+ normally enqueues; use it when another path screens the customer, such as a
51
+ stakeholder screened with its entity.
52
+
53
+ `profileTemplateKey` names the customer's Profile Template (omit it to get the
54
+ default `INDIVIDUAL` template, if one is set). `fields` are the template's
55
+ typed profile fields (`TypedFieldValueInput[]`), validated Tier A against
56
+ `ProfileTemplate.fieldConfig`; sending `fields` with no template is a 400. On
57
+ `update`, `fields` merge (listed keys change, `value: null` clears, unlisted
58
+ keys stay) and `profileTemplateKey` switches template. Responses carry
59
+ `profileTemplateKey`, `fields` (`TypedFieldValue[]`) and `riskRatingSource`
60
+ (`'MANUAL' | 'MATRIX' | null`).
49
61
 
50
62
  Legacy field names from the pre-1.0 contract are still accepted on create and
51
63
  map onto the canonical ones — `email` / `phone` scalars fold into `emails[]` /
@@ -81,8 +93,9 @@ whenever both are supplied. Prefer the canonical names in new integrations.
81
93
  `create(input)` requires `externalId` and `legalName`. Optional create fields
82
94
  are `status`, `tradingNames[]`, `registrationNumber`, `taxId`,
83
95
  `countryOfIncorporation`, `dateOfIncorporation`, `entityType`, `websites[]`,
84
- `stakeholders[]`, `locations[]`, `tags[]`, `assignedToUserIds[]`, and
85
- `assignedToTeamIds[]`. Each stakeholder has required `name` and uppercase
96
+ `stakeholders[]`, `locations[]`, `tags[]`, `assignedToUserIds[]`,
97
+ `assignedToTeamIds[]`, `profileTemplateKey`, and `fields[]` (same profile
98
+ semantics as individuals, against an `ENTITY` template). Each stakeholder has required `name` and uppercase
86
99
  `role` (`SHAREHOLDER`, `UBO`, or `DIRECTOR`). Entity locations use the same
87
100
  `AddressInputDto` shape as individual addresses.
88
101
 
@@ -144,9 +157,45 @@ for (const m of matches.filter((m) => m.disposition === 'FALSE_POSITIVE')) {
144
157
 
145
158
  The assessment only ever eliminates on a contradiction — never on a missing attribute, never on geography alone, and never on a sanctions listing unless the contradiction is hard. A `retain` is not a confirmation, only the absence of grounds to eliminate, and an absent `disambiguation` means the match was never assessed. `resolvedBy` distinguishes the automation from your users.
146
159
 
147
- `customers.riskRating` — `update(customerId, input)` → `PUT .../risk-rating`
160
+ `customers.kyc`
148
161
 
149
- `customers.riskAssessments` — `list`, `create` on `.../risk-assessments`
162
+ | Method | Endpoint |
163
+ | --- | --- |
164
+ | `start(customerId, { providerConfigId?, workflowId? })` | `POST .../kyc/sessions` — returns the hosted `sessionUrl` to hand to the customer |
165
+ | `list(customerId)` | `GET .../kyc/sessions` |
166
+ | `refresh(customerId, sessionId)` | `POST .../kyc/sessions/{sessionId}/refresh` |
167
+ | `review(customerId, sessionId, { decision, reason?, notifyCustomer?, customerMessage? })` | `POST .../kyc/sessions/{sessionId}/review` — needs `customer:update` |
168
+ | `report(customerId, sessionId)` | `GET .../kyc/sessions/{sessionId}/report` — PDF bytes (`Uint8Array`); needs `report:read` |
169
+ | `evidenceBundle(customerId, sessionId)` | `GET .../kyc/sessions/{sessionId}/evidence` — ZIP bytes (`Uint8Array`); needs `report:read` |
170
+ | `delete(customerId, sessionId)` | `DELETE .../kyc/sessions/{sessionId}` — unfinished sessions only |
171
+
172
+ The OS keeps every session after it ends, so `report` and `evidenceBundle` work after the provider has deleted its copy. The bundle holds `report.pdf`, every archived evidence file at full resolution under `evidence/` (document pages, faces, liveness video, signature) and the raw data under `data/`.
173
+
174
+ `customers.riskRating`
175
+
176
+ | Method | Endpoint |
177
+ | --- | --- |
178
+ | `update(customerId, { riskRating, justification? })` | `PUT .../risk-rating` — sets a sticky officer override (`riskRatingSource: 'MANUAL'`); returns `UpdateRiskRatingResponseDto` |
179
+ | `clearOverride(customerId)` | `DELETE .../risk-rating/override` — hands the rating back to the risk matrix; returns the latest matrix assessment |
180
+
181
+ `customers.riskAssessments`
182
+
183
+ | Method | Endpoint |
184
+ | --- | --- |
185
+ | `list(customerId)` | `GET .../risk-assessments` — questionnaires and matrix runs, newest first |
186
+ | `create(customerId, input)` | `POST .../risk-assessments` — submit a questionnaire |
187
+ | `evaluate(customerId)` | `POST .../risk-assessments/evaluate` — run the Profile Template risk matrix now; returns the latest matrix assessment |
188
+
189
+ `CustomerRiskAssessmentResponseDto.method` is `QUESTIONNAIRE` or `MATRIX`.
190
+ Matrix runs add `compositeScore`, `breakdown` (`RiskMatrixBreakdown`: per
191
+ factor `input → criterion → level → score → weighted`, the composite, the
192
+ preliminary rating, escalations that fired, incomplete factors, final rating
193
+ and outcome), `profileTemplateVersion`, `trigger` (`PROFILE_UPDATED`,
194
+ `KYC_SYNC`, `SCHEDULED`, `TEMPLATE_CHANGED`, `MANUAL`), `requiredDueDiligence`
195
+ (`SDD | CDD | EDD`) and `nextReviewAt`. The matrix records its computed
196
+ rating on every run but never overwrites a `MANUAL` rating. `evaluate` and
197
+ `clearOverride` return 400 when the customer has no Profile Template with a
198
+ risk matrix.
150
199
 
151
200
  `customers.expectedActivity` — `get`, `update` on `.../expected-activity`
152
201
 
@@ -188,6 +237,8 @@ observation contracts.
188
237
 
189
238
  Standing assignment can also be stamped at create via `assignedToUserIds` / `assignedToTeamIds` on `individuals.create` / `entities.create`.
190
239
 
240
+ `customers.assignProfileTemplate({ customerIds, profileTemplateKey })` — `POST /v1/customers/profile-template-assignment` puts up to 500 existing customers on a live profile template. Values the template can hold are kept and defaults applied; required fields left empty come back per customer in `assigned[].missingFields` instead of refusing it (the next `fields` update must fill them). Customers already on the template are `unchanged`; other party types, archived customers and unknown ids are `skipped` with a `reason`. Requires `customer:update`.
241
+
191
242
  `individuals.create(input, { screening: 'sync' })` / `entities.create(input, { screening: 'sync' })` run the INITIAL screening inline and return it under `screening` (`InitialScreeningResultDto`: run status, `alertId`, and the `matches` array in the `listResults` shape). Without the option the call queues the screening as before and the response has no `screening` field.
192
243
 
193
244
  `targets` must contain at least one non-empty `userIds` or `teamIds` array.
@@ -199,7 +250,10 @@ writes require `customer:update`; archived customers return 422.
199
250
  ### `identificationDocuments` (document-scoped)
200
251
 
201
252
  Top-level resource for operating on a single identification document by its id
202
- — the review workflow's surface. Customer-scoped create/update/delete also
253
+ — the review workflow's surface. Stage definitions may carry an optional
254
+ `returnAssignment` (`RULE` | `RESTORE` | `ASK`) saying what happens to
255
+ assignees when an alert is returned to that stage; omission means `RULE`, and
256
+ Resolved stages never carry it. Customer-scoped create/update/delete also
203
257
  exist on `individuals.identificationDocuments` / `entities.identificationDocuments`.
204
258
 
205
259
  | Method | Endpoint |
@@ -532,6 +586,55 @@ schema. Editing `fields` never re-validates existing alerts — new required
532
586
  fields apply to alerts raised afterwards. Archive is refused (409) while any
533
587
  alert of the type is OPEN.
534
588
 
589
+ `config.profileTemplates` — the template a customer is created against
590
+ (Customer → Profile Template parallels Account → Product).
591
+
592
+ | Method | Endpoint |
593
+ | --- | --- |
594
+ | `list({ partyType?, includeArchived? })` | `GET /v1/config/profile-templates` |
595
+ | `get(id)` | `GET /v1/config/profile-templates/{id}` |
596
+ | `getByKey(key)` | `GET /v1/config/profile-templates/by-key/{key}` (404 when absent) |
597
+ | `versions(id)` | `GET /v1/config/profile-templates/{id}/versions` (newest first, each with `changes`) |
598
+ | `version(id, version)` | `GET /v1/config/profile-templates/{id}/versions/{version}` |
599
+ | `restoreVersion(id, version)` | `POST /v1/config/profile-templates/{id}/versions/{version}/restore` (republish as the newest version) |
600
+ | `create(input)` | `POST /v1/config/profile-templates` (409 when `key` is taken) |
601
+ | `update(id, input)` | `PATCH /v1/config/profile-templates/{id}` |
602
+ | `archive(id)` | `DELETE /v1/config/profile-templates/{id}` (archive; no hard delete) |
603
+ | `previewRiskMatrix(input)` | `POST /v1/config/profile-templates/preview-risk-matrix` (dry run for one customer; nothing saved) |
604
+ | `riskMatrixImpact(id, input)` | `POST /v1/config/profile-templates/{id}/risk-matrix-impact` (dry run for every live customer on the template; at most 5,000) |
605
+
606
+ A factor may read a platform-derived `input` (`customer.nationality`,
607
+ `customer.productKeys`, `customer.expectedMonthlyVolume`) instead of a profile
608
+ `field`. Individual and entity responses carry `nextReviewAt`, the customer's
609
+ next periodic review; the daily sweep opens a `periodic-review` Task when it
610
+ falls due.
611
+
612
+ A template carries an immutable org-unique `key`, `partyType` (`INDIVIDUAL` \|
613
+ `ENTITY`), `isDefault` (at most one live default per party type),
614
+ `fieldConfig` (`TypedFieldDefinition[]`), an optional `riskMatrix`
615
+ (`RiskMatrix`: `scale`, `bands`, `factors`, `escalations`, `outcomes`; each
616
+ `RiskFactor` is `field` + `levels` for select or yes/no fields — BOOLEAN
617
+ options `"true"` / `"false"`, a multi-select scores its highest-scoring
618
+ selected option — `field` + `ranges` (`RiskRange`: min inclusive, max
619
+ exclusive, open ends, no overlaps; money in major units) for NUMBER / MONETARY
620
+ fields, or `criteria`; any option, range or criterion may set its own `score`
621
+ to override its level's scale score) and
622
+ `kycWorkflows` (`KycWorkflowBinding[]`, one per purpose; only `ONBOARDING` is
623
+ used today), plus the creation setup of the simple create form for its party
624
+ type: `individualCreation` (`SimpleCustomerCreationPreferences`, `INDIVIDUAL`
625
+ templates) or `entityCreation` (`SimpleEntityCreationPreferences`, `ENTITY`
626
+ templates) — the other is always `null`. Writes take
627
+ `UpdateSimpleCustomerCreationPreferencesInput` /
628
+ `UpdateSimpleEntityCreationPreferencesInput` (full replacement); sending the
629
+ other party type's field is a 400. `create` without one copies the org's
630
+ current Simple Customer Creation preference; `update` with `null` clears it
631
+ (the org-wide preference applies again). The whole definition is validated on
632
+ save and every problem is returned in one 400. Changing `fieldConfig`,
633
+ `riskMatrix`, `kycWorkflows` or the creation setup publishes a new immutable
634
+ version (`versions` snapshots carry fields, matrix and workflows only); only
635
+ `fieldConfig` / `riskMatrix` changes re-assess the template's customers.
636
+ Archiving keeps existing customers on the template and clears `isDefault`.
637
+
535
638
  `config.currencies`
536
639
 
537
640
  | Method | Endpoint |
@@ -591,7 +694,7 @@ Entry fields: `name` (required), `entryType` (`INDIVIDUAL` \| `ENTITY`, default
591
694
 
592
695
  ### `reports`
593
696
 
594
- On-demand PDF reports. Every method resolves to the raw PDF bytes as a `Uint8Array`; write them to disk (`fs.writeFileSync`) or stream them to your own download response. Gated on `report:read`. Each call records a `report.generated` activity on the subject record.
697
+ On-demand PDF reports. Every method resolves to the raw PDF bytes as a `Uint8Array`; write them to disk (`fs.writeFileSync`) or stream them to your own download response. The API key needs the `reports:read` permission (part of the Full Access preset; a key without it gets `403`). Each call records a `report.generated` activity on the subject record, attributed to the key.
595
698
 
596
699
  | Method | Endpoint |
597
700
  | --- | --- |
@@ -654,6 +757,14 @@ type TypedFieldStored =
654
757
  | { key: string; type: 'monetary'; amountMinor: number; currency: string; precision: number };
655
758
 
656
759
  interface UntypedKeyValueDto { key: string; value: unknown }
760
+
761
+ // Read shape on customer profile fields — the canonical uppercase tag.
762
+ type TypedFieldValue =
763
+ | { key: string; type: 'TEXT' | 'DATE' | 'CURRENCY' | 'SINGLE_SELECT'; value: string }
764
+ | { key: string; type: 'NUMBER'; value: number }
765
+ | { key: string; type: 'BOOLEAN'; value: boolean }
766
+ | { key: string; type: 'LIST' | 'MULTI_SELECT' | 'SET'; value: string[] }
767
+ | { key: string; type: 'MONETARY'; amountMinor: number; currency: string; precision: number };
657
768
  ```
658
769
 
659
770
  DTOs that carry these:
@@ -665,6 +776,9 @@ DTOs that carry these:
665
776
  | `CreateEventDefinitionDto` / `UpdateEventDefinitionDto` | `properties` (`TypedFieldDefinition[]`) | schema |
666
777
  | `CreateCustomAlertTypeDto` / `UpdateCustomAlertTypeDto` | `fields` (`TypedFieldDefinition[]`) | schema |
667
778
  | `CreateCustomAlertDto` / `AlertResponseDto` | `fields` | A |
779
+ | `CreateProfileTemplateInput` / `UpdateProfileTemplateInput` / `ProfileTemplate` | `fieldConfig` (`TypedFieldDefinition[]`) | schema |
780
+ | `CreateIndividualInput` / `UpdateIndividualDto` / `CreateEntityInput` / `UpdateEntityDto` | `fields` (`TypedFieldValueInput[]`) | A |
781
+ | `IndividualResponseDto` / `EntityResponseDto` | `fields` (`TypedFieldValue[]`) | A |
668
782
  | `CounterpartyResponseDto` | `otherProperties` | C |
669
783
  | Event ingestion (`POST /v1/events`) | `fields` | B |
670
784
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dossier-wiki/os-sdk",
3
- "version": "1.4.0",
3
+ "version": "1.4.2-staging.5.1",
4
4
  "description": "TypeScript SDK for the Dossiers OS API — customers, accounts, transactions, rules, screening, and configuration.",
5
5
  "license": "MIT",
6
6
  "type": "module",