@sekyro/node 0.1.0-rc.3 → 0.1.0-rc.5
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/CHANGELOG.md +44 -0
- package/LICENSE +25 -16
- package/README.md +173 -24
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +808 -107
- package/dist/index.d.ts +808 -107
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/sbom.cdx.json +5 -5
package/dist/index.d.ts
CHANGED
|
@@ -16,12 +16,14 @@ type SessionStatus = "created" | "in_progress" | "review_pending" | "completed"
|
|
|
16
16
|
type SessionOutcome = "approved" | "review" | "rejected";
|
|
17
17
|
/**
|
|
18
18
|
* How the person proves their identity on an optional-document app: type the
|
|
19
|
-
* national number, or photograph the document.
|
|
19
|
+
* national number, or photograph the document (`document_chip`: native NFC clients only).
|
|
20
|
+
* `national_eid`: the country's national eID (e.g. Houwiyeti for Mauritania),
|
|
21
|
+
* offered when the app's profile turns the national eID on.
|
|
20
22
|
* @public
|
|
21
23
|
*/
|
|
22
|
-
type IdentityMethod = "national_number" | "document_photo";
|
|
24
|
+
type IdentityMethod = "national_number" | "document_photo" | "document_chip" | "national_eid";
|
|
23
25
|
/** The verification checks a flow may contain. @public */
|
|
24
|
-
type CheckType = "liveness" | "face_match" | "doc_ocr" | "population_registry" | "phone_otp";
|
|
26
|
+
type CheckType = "liveness" | "face_match" | "doc_ocr" | "population_registry" | "phone_otp" | "nfc_chip" | "email_otp" | "portrait_icao" | "eid_auth";
|
|
25
27
|
/** Per-check execution state within a session. @public */
|
|
26
28
|
type CheckState = "pending" | "input_required" | "processing" | "passed" | "failed" | "review" | "skipped";
|
|
27
29
|
/**
|
|
@@ -79,6 +81,14 @@ type PolicyFailureReason = SessionFailureReason | EligibilityReason | "document_
|
|
|
79
81
|
* @public
|
|
80
82
|
*/
|
|
81
83
|
type MatchReason = "name_mismatch" | "birth_date_mismatch" | "nationality_mismatch" | "document_number_mismatch";
|
|
84
|
+
/**
|
|
85
|
+
* Face-match probe-binding reason a `face_match` {@link SessionStep.reason} may
|
|
86
|
+
* carry (SDK spec §4.10): `probe_not_from_liveness` — the face image isn't the
|
|
87
|
+
* person in the liveness clip. Retryable within the step's attempts (the
|
|
88
|
+
* person re-takes the liveness capture); billed.
|
|
89
|
+
* @public
|
|
90
|
+
*/
|
|
91
|
+
type ProbeBindingReason = "probe_not_from_liveness";
|
|
82
92
|
/** Hosted-flow languages. @public */
|
|
83
93
|
type Locale = "ar" | "fr" | "en";
|
|
84
94
|
/** The environment a webhook was emitted from. @public */
|
|
@@ -91,12 +101,69 @@ type SekyroEnvironment = "sandbox" | "live";
|
|
|
91
101
|
interface SessionStep {
|
|
92
102
|
checkType: CheckType;
|
|
93
103
|
state: CheckState;
|
|
104
|
+
/** Sekyro flows: the flow node this check belongs to (e.g. `n_live`). */
|
|
105
|
+
nodeId?: string;
|
|
106
|
+
/** Sekyro flows: the service of that node. */
|
|
107
|
+
service?: ServiceId;
|
|
108
|
+
/** Sekyro flows: the check failed and the flow's fallback took over. */
|
|
109
|
+
handled?: true;
|
|
94
110
|
/** Machine-readable failure/review reason, when the check has one. */
|
|
95
111
|
reason?: string;
|
|
96
112
|
/** Calibrated model score in [0, 1] for scored checks (liveness, face match). */
|
|
97
113
|
calibratedScore?: number;
|
|
98
114
|
/** The check failed after using all of its attempts. */
|
|
99
115
|
attemptsExhausted?: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* `portrait_icao` only (ID mode): the per-criterion ICAO report of the last
|
|
118
|
+
* attempt — numbers and enums only, never the image.
|
|
119
|
+
*/
|
|
120
|
+
report?: PortraitReportEntry[];
|
|
121
|
+
/**
|
|
122
|
+
* `face_match` only: the probe-quality measurement of the selfie that was
|
|
123
|
+
* matched (occlusion, head pose, eye openness, sharpness). Recorded for
|
|
124
|
+
* information only: it never changes the step's state or reason.
|
|
125
|
+
*/
|
|
126
|
+
probeQuality?: ProbeQuality;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* The probe-quality measurement on a `face_match` step. Numbers only; `null`
|
|
130
|
+
* means the value could not be measured. Informational: no threshold applies.
|
|
131
|
+
* @public
|
|
132
|
+
*/
|
|
133
|
+
interface ProbeQuality {
|
|
134
|
+
/** Share of the inner face that is covered (a hand, a mask, a phone), in [0, 1]. */
|
|
135
|
+
occlusion: number | null;
|
|
136
|
+
/** Head pose in degrees. */
|
|
137
|
+
pose: {
|
|
138
|
+
yaw: number | null;
|
|
139
|
+
pitch: number | null;
|
|
140
|
+
roll: number | null;
|
|
141
|
+
};
|
|
142
|
+
/** Openness of the less-open eye, in [0, 1]. */
|
|
143
|
+
eyesOpen: number | null;
|
|
144
|
+
/** Sharpness of the face region (higher is sharper; no fixed scale). */
|
|
145
|
+
sharpness: number | null;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* One row of the `portrait_icao` report (ID mode): the server's measurement of
|
|
149
|
+
* one ICAO criterion and the threshold that applied.
|
|
150
|
+
* @public
|
|
151
|
+
*/
|
|
152
|
+
interface PortraitReportEntry {
|
|
153
|
+
criterion: "pose" | "eyes" | "mouth" | "occlusion" | "glare" | "lighting" | "background" | "resolution";
|
|
154
|
+
value: number | null;
|
|
155
|
+
threshold: number | string | null;
|
|
156
|
+
pass: boolean;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* A short-lived link to a session's ICAO portrait (480×640 JPEG), from
|
|
160
|
+
* {@link SessionsApi.portrait}. Download it before `expiresAt`; never store the URL.
|
|
161
|
+
* @public
|
|
162
|
+
*/
|
|
163
|
+
interface SessionPortraitLink {
|
|
164
|
+
url: string;
|
|
165
|
+
/** ISO 8601 (about 5 minutes after the call). */
|
|
166
|
+
expiresAt: string;
|
|
100
167
|
}
|
|
101
168
|
/**
|
|
102
169
|
* Out-of-band delivery of the session's hosted link, sent by Sekyro AI after the
|
|
@@ -134,24 +201,84 @@ interface SessionSubjectInput {
|
|
|
134
201
|
* its webhooks, and searchable on the subjects API.
|
|
135
202
|
*/
|
|
136
203
|
externalRef?: string;
|
|
204
|
+
/**
|
|
205
|
+
* Returning user (profile v2 step 5): verify this already-verified subject
|
|
206
|
+
* again with liveness + face match only, against the reference photo stored
|
|
207
|
+
* on the subject. Name exactly one target. Errors at create:
|
|
208
|
+
* `404 subject_not_found`, `409 subject_revoked`, `409 subject_no_reference`,
|
|
209
|
+
* `409 subject_stale` (older than the flow's `returning.maxAgeMonths`),
|
|
210
|
+
* `409 reuse_disabled` (the flow turns returning-user sessions off) and
|
|
211
|
+
* `400` / `409 reuse_target_ambiguous`.
|
|
212
|
+
*/
|
|
213
|
+
reuse?: SubjectReuseTarget;
|
|
137
214
|
}
|
|
138
|
-
/** A document type the backend reads (kyc-docs-v2 vocabulary). @public */
|
|
139
|
-
type ProfileDocumentType = "carte_identite" | "passport";
|
|
140
215
|
/**
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* `link` (use {@link CreateSessionInput.ttlMinutes}) and `overrides` (the
|
|
144
|
-
* app's own permission). Country codes are ISO 3166-1 alpha-2 (`MR`).
|
|
145
|
-
* Used through {@link EkycProfileOverride}.
|
|
216
|
+
* Which subject a returning-user session re-verifies — exactly ONE of the
|
|
217
|
+
* subject id, your own `externalRef` (must match a single subject) or the NNI.
|
|
146
218
|
* @public
|
|
147
219
|
*/
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
220
|
+
type SubjectReuseTarget = {
|
|
221
|
+
subjectId: string;
|
|
222
|
+
externalRef?: never;
|
|
223
|
+
nni?: never;
|
|
224
|
+
} | {
|
|
225
|
+
externalRef: string;
|
|
226
|
+
subjectId?: never;
|
|
227
|
+
nni?: never;
|
|
228
|
+
} | {
|
|
229
|
+
nni: string;
|
|
230
|
+
subjectId?: never;
|
|
231
|
+
externalRef?: never;
|
|
232
|
+
};
|
|
233
|
+
/** A document type the backend reads (kyc-docs-v2 vocabulary; `carte_identite` = identity card of any issuer). @public */
|
|
234
|
+
type ProfileDocumentType = "carte_identite" | "passport" | "residence_permit";
|
|
235
|
+
/**
|
|
236
|
+
* The services a Sekyro flow is built from. A session's steps
|
|
237
|
+
* ({@link SessionStep.service}) and {@link FlowOverrides.services} use these
|
|
238
|
+
* ids; one service may run several checks (e.g. `liveness` with an ICAO
|
|
239
|
+
* portrait).
|
|
240
|
+
* @public
|
|
241
|
+
*/
|
|
242
|
+
type ServiceId = "device_network" | "phone_otp" | "email_otp" | "national_eid" | "document" | "nfc" | "population_registry" | "supplied_identity" | "summary_confirm" | "liveness" | "face_match" | "aml_screening" | "face_dedup";
|
|
243
|
+
/**
|
|
244
|
+
* The general settings of a flow that a session may override (the flow's
|
|
245
|
+
* `link`, `language` and override policy are not overridable). Country codes
|
|
246
|
+
* are ISO 3166-1 alpha-2 (`MR`). Used through {@link FlowOverrides.settings}.
|
|
247
|
+
* @public
|
|
248
|
+
*/
|
|
249
|
+
interface FlowOverridableSettings {
|
|
250
|
+
/** Who may be verified. */
|
|
251
|
+
eligibility: {
|
|
252
|
+
/** Accepted nationalities: `'*'` or a list, optionally per IP location. */
|
|
253
|
+
nationalities: {
|
|
254
|
+
default: "*" | string[];
|
|
255
|
+
byLocation?: Record<string, "*" | string[]>;
|
|
256
|
+
};
|
|
257
|
+
/** Minimum age in years (1–120), or `null` for none. */
|
|
258
|
+
minAge: number | null;
|
|
152
259
|
};
|
|
153
|
-
|
|
154
|
-
|
|
260
|
+
/** Automatic decisions instead of human review (`retryConfidentRejects` lets confident rejects retry). */
|
|
261
|
+
decisions?: {
|
|
262
|
+
mode: "automatic" | "review";
|
|
263
|
+
retryConfidentRejects: boolean;
|
|
264
|
+
};
|
|
265
|
+
/** Data consistency across sources. */
|
|
266
|
+
fraud: {
|
|
267
|
+
/** Comparison of your `subject` data with the reference identity. */
|
|
268
|
+
nameMatch?: {
|
|
269
|
+
level: "strict" | "standard" | "lenient";
|
|
270
|
+
onMismatch: "fail" | "signal";
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
/** Returning-user sessions (`subject.reuse`). */
|
|
274
|
+
returning: {
|
|
275
|
+
/** `false`: returning-user sessions are refused (`409 reuse_disabled`). */
|
|
276
|
+
enabled: boolean;
|
|
277
|
+
/** Maximum age in months (1–120) of the subject's last verification; `null` = no limit. */
|
|
278
|
+
maxAgeMonths: number | null;
|
|
279
|
+
};
|
|
280
|
+
/** Identity-document rules. */
|
|
281
|
+
documents: {
|
|
155
282
|
/** Accepted document types: `'*'` (all) or a list, optionally per issuing country. */
|
|
156
283
|
accepted: {
|
|
157
284
|
default: "*" | ProfileDocumentType[];
|
|
@@ -163,69 +290,122 @@ interface EkycProfileSettings {
|
|
|
163
290
|
};
|
|
164
291
|
authenticity: "standard" | "off";
|
|
165
292
|
};
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Document substitution: the portrait a `document` or `nfc` step produces is
|
|
296
|
+
* compared with the registry portrait (or the chip with the printed photo).
|
|
297
|
+
* `signal` records a risk signal on a clear mismatch, `review` also sends the
|
|
298
|
+
* session to review, `off` compares nothing. `failBelow` is the mismatch bound
|
|
299
|
+
* in (0, 1), absent = the platform bound.
|
|
300
|
+
* @public
|
|
301
|
+
*/
|
|
302
|
+
interface DocumentSubstitutionSettings {
|
|
303
|
+
mode: "off" | "signal" | "review";
|
|
304
|
+
failBelow?: number;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* The per-service settings a session may override, by {@link ServiceId}.
|
|
308
|
+
* `attempts` limits are per step (absent = the platform default).
|
|
309
|
+
* @public
|
|
310
|
+
*/
|
|
311
|
+
interface FlowServiceSettings {
|
|
312
|
+
/** Device & Network Intelligence: IP location, anonymizers, cooldown, device and capture postures. */
|
|
313
|
+
device_network: {
|
|
314
|
+
/** Where the end user may be (IP location). */
|
|
315
|
+
locations: {
|
|
316
|
+
mode: "all";
|
|
317
|
+
} | {
|
|
318
|
+
mode: "only" | "all_except";
|
|
319
|
+
countries: string[];
|
|
320
|
+
};
|
|
321
|
+
/** VPN / proxy / Tor. */
|
|
322
|
+
anonymizers: "allow" | "block";
|
|
323
|
+
/** Device cooldown after repeated rejections (at most 5 tiers; `[]` = off). */
|
|
324
|
+
cooldown?: {
|
|
325
|
+
tiers: Array<{
|
|
326
|
+
rejectedSessions: number;
|
|
327
|
+
windowHours: number;
|
|
328
|
+
waitMinutes: number;
|
|
329
|
+
}>;
|
|
330
|
+
};
|
|
331
|
+
/** Device tamper and velocity actions. */
|
|
332
|
+
device?: {
|
|
333
|
+
tamper: "block" | "signal";
|
|
334
|
+
velocity: {
|
|
335
|
+
maxIdentitiesPerDevice: number;
|
|
336
|
+
windowDays: number;
|
|
337
|
+
action: "signal" | "block";
|
|
338
|
+
};
|
|
339
|
+
};
|
|
340
|
+
attestation?: "off" | "signal" | "enforce";
|
|
341
|
+
captureIntegrity?: "off" | "signal" | "enforce";
|
|
173
342
|
};
|
|
174
|
-
|
|
175
|
-
|
|
343
|
+
phone_otp: {
|
|
344
|
+
/** Where the number comes from: your `subject.phone` / `input.phone`, the person, or either. */
|
|
345
|
+
numberSource: "prefilled" | "user_entered" | "prefilled_or_entered";
|
|
346
|
+
/** Narrow the channels the person may choose from (absent = every channel the org has on). */
|
|
347
|
+
channels?: Array<"whatsapp" | "sms">;
|
|
348
|
+
/** Which countries codes may be sent to (absent = the flow's allowed `locations`). */
|
|
349
|
+
destinations?: "locations" | "any" | {
|
|
350
|
+
countries: string[];
|
|
351
|
+
};
|
|
352
|
+
attempts?: number;
|
|
176
353
|
};
|
|
177
|
-
|
|
178
|
-
|
|
354
|
+
email_otp: {
|
|
355
|
+
/** Where the address comes from: your `input.email`, the person, or either. */
|
|
356
|
+
emailSource: "prefilled" | "user_entered" | "prefilled_or_entered";
|
|
357
|
+
/** Disposable (temporary) addresses: allowed, flagged as a risk signal (default), or refused. */
|
|
358
|
+
disposable?: "allow" | "signal" | "block";
|
|
359
|
+
attempts?: number;
|
|
179
360
|
};
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
361
|
+
national_eid: {
|
|
362
|
+
/**
|
|
363
|
+
* `'org'` (every national eID the org can use, resolved at session create)
|
|
364
|
+
* or provider ids (`{country}.{provider}`, e.g. `MR.houwiyeti`).
|
|
365
|
+
*/
|
|
366
|
+
providers: "org" | string[];
|
|
367
|
+
/** The eID portrait is the face-match reference. */
|
|
368
|
+
portraitReference: boolean;
|
|
184
369
|
};
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
registry: number;
|
|
190
|
-
liveness: number;
|
|
191
|
-
faceMatch: number;
|
|
370
|
+
document: {
|
|
371
|
+
attempts?: number;
|
|
372
|
+
/** Compare the document photo with the registry photo (absent = the platform default). */
|
|
373
|
+
documentSubstitution?: DocumentSubstitutionSettings;
|
|
192
374
|
};
|
|
193
|
-
/**
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
countries: string[];
|
|
375
|
+
/** The chip read (its MRZ source is derived from the flow and is not overridable). */
|
|
376
|
+
nfc: {
|
|
377
|
+
maxAttempts?: number;
|
|
378
|
+
/** Compare the chip photo with the registry photo (absent = the platform default). */
|
|
379
|
+
documentSubstitution?: DocumentSubstitutionSettings;
|
|
199
380
|
};
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
381
|
+
population_registry: {
|
|
382
|
+
/** `'org'` (every registry the org can use, resolved at session create) or registry ids. */
|
|
383
|
+
sources: "org" | Array<"MR.anrpts">;
|
|
384
|
+
nniSource: "auto" | "typed" | "bound_only";
|
|
385
|
+
onUncovered: "skip";
|
|
386
|
+
attempts?: number;
|
|
205
387
|
};
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
mode: "automatic" | "review";
|
|
211
|
-
retryConfidentRejects: boolean;
|
|
388
|
+
supplied_identity: Record<string, never>;
|
|
389
|
+
summary_confirm: {
|
|
390
|
+
/** Offer « Reprendre » (re-open the identity source). */
|
|
391
|
+
retake: boolean;
|
|
212
392
|
};
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
windowHours: number;
|
|
218
|
-
waitMinutes: number;
|
|
219
|
-
}>;
|
|
393
|
+
liveness: {
|
|
394
|
+
/** `off`, selfie ICAO `alert` / `reject`, or `id_document` (ID-photo portrait, always rejects). */
|
|
395
|
+
icao: "off" | "alert" | "reject" | "id_document";
|
|
396
|
+
attempts?: number;
|
|
220
397
|
};
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
398
|
+
face_match: {
|
|
399
|
+
reference: "auto" | "document" | "registry";
|
|
400
|
+
attempts?: number;
|
|
401
|
+
};
|
|
402
|
+
aml_screening: {
|
|
403
|
+
lists: Array<"sanctions" | "pep" | "adverse_media">;
|
|
404
|
+
onHit: "review" | "fail";
|
|
405
|
+
};
|
|
406
|
+
face_dedup: {
|
|
407
|
+
scope: "app" | "org";
|
|
408
|
+
onDuplicate: "review" | "fail";
|
|
229
409
|
};
|
|
230
410
|
}
|
|
231
411
|
/**
|
|
@@ -237,37 +417,86 @@ type DeepPartial<T> = T extends readonly unknown[] ? T : T extends object ? {
|
|
|
237
417
|
[K in keyof T]?: DeepPartial<T[K]>;
|
|
238
418
|
} : T;
|
|
239
419
|
/**
|
|
240
|
-
* A per-session override of the
|
|
241
|
-
* ({@link CreateSessionInput.profile}): any subset of
|
|
242
|
-
* {@link EkycProfileSettings}, at any depth (every field optional). Objects
|
|
243
|
-
* are merged into the app's profile; arrays and scalar values replace it.
|
|
420
|
+
* A per-session override of the flow ({@link CreateSessionInput.overrides}).
|
|
244
421
|
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
422
|
+
* - `settings`: any subset of {@link FlowOverridableSettings}, at any depth.
|
|
423
|
+
* - `services`: keyed by service (applied to every node of that service): any
|
|
424
|
+
* subset of its {@link FlowServiceSettings}, or `'off'` to remove it from
|
|
425
|
+
* the flow. A service the flow does not use is ignored.
|
|
426
|
+
*
|
|
427
|
+
* Objects merge into the flow; arrays and scalar values replace. Unknown keys
|
|
428
|
+
* and invalid results answer `400 override_invalid`. An override may only
|
|
429
|
+
* make the flow stricter unless the flow allows widening; turning a service
|
|
430
|
+
* `'off'` always widens. A widening change answers `403 override_widens_flow`.
|
|
431
|
+
* The changed paths are reported on {@link Session.overriddenFields}.
|
|
432
|
+
*
|
|
433
|
+
* @example
|
|
434
|
+
* ```ts
|
|
435
|
+
* await sekyro.sessions.create({
|
|
436
|
+
* flow: "foreigners",
|
|
437
|
+
* overrides: {
|
|
438
|
+
* settings: { eligibility: { minAge: 21 } },
|
|
439
|
+
* services: { liveness: { attempts: 2 } },
|
|
440
|
+
* },
|
|
441
|
+
* });
|
|
442
|
+
* ```
|
|
251
443
|
* @public
|
|
252
444
|
*/
|
|
253
|
-
|
|
445
|
+
interface FlowOverrides {
|
|
446
|
+
settings?: DeepPartial<FlowOverridableSettings>;
|
|
447
|
+
services?: {
|
|
448
|
+
[S in ServiceId]?: DeepPartial<FlowServiceSettings[S]> | "off";
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* The flow version a session runs: its `flw_` id, its slug and the published
|
|
453
|
+
* version pinned at create.
|
|
454
|
+
* @public
|
|
455
|
+
*/
|
|
456
|
+
interface SessionFlowRef {
|
|
457
|
+
id: string;
|
|
458
|
+
slug: string;
|
|
459
|
+
version: number;
|
|
460
|
+
}
|
|
254
461
|
/**
|
|
255
|
-
*
|
|
256
|
-
*
|
|
462
|
+
* One flow of your app, from {@link Sekyro.listFlows}. Published flows only;
|
|
463
|
+
* pass `slug` or `id` as {@link CreateSessionInput.flow}.
|
|
464
|
+
* @public
|
|
465
|
+
*/
|
|
466
|
+
interface FlowSummary {
|
|
467
|
+
/** `flw_` id. */
|
|
468
|
+
id: string;
|
|
469
|
+
slug: string;
|
|
470
|
+
name: string;
|
|
471
|
+
/** The published version a new session runs. */
|
|
472
|
+
version: number;
|
|
473
|
+
/** The flow a session runs when you send no `flow`. */
|
|
474
|
+
isDefault: boolean;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Input of {@link SessionsApi.create}. The API key belongs to an app; the
|
|
478
|
+
* app's flow (its default flow, or the one named in `flow`) decides the steps.
|
|
257
479
|
* @public
|
|
258
480
|
*/
|
|
259
481
|
interface CreateSessionInput {
|
|
482
|
+
/**
|
|
483
|
+
* The app's flow to run: its slug (e.g. `foreigners`) or `flw_` id, as
|
|
484
|
+
* {@link Sekyro.listFlows} lists them. Absent = the app's default flow.
|
|
485
|
+
* Errors: `404 flow_not_found` (no such flow in the key's app),
|
|
486
|
+
* `409 flow_not_published`, `409 flow_archived`.
|
|
487
|
+
*/
|
|
488
|
+
flow?: string;
|
|
260
489
|
/** Pins the hosted-flow language. Omit to let the person's device decide. */
|
|
261
490
|
locale?: Locale;
|
|
262
491
|
/**
|
|
263
|
-
* Pre-choose the identity method when the
|
|
264
|
-
* (the hosted
|
|
492
|
+
* Pre-choose the identity method when the flow offers a choice of identity
|
|
493
|
+
* method (the hosted choice screen is then skipped). Ignored otherwise.
|
|
265
494
|
*/
|
|
266
495
|
identityMethod?: IdentityMethod;
|
|
267
496
|
/**
|
|
268
|
-
* Session lifetime in minutes. Must fall within the
|
|
269
|
-
*
|
|
270
|
-
*
|
|
497
|
+
* Session lifetime in minutes. Must fall within the flow's link range,
|
|
498
|
+
* otherwise the API answers `400 ttl_out_of_policy`. Omit to use the
|
|
499
|
+
* flow's default.
|
|
271
500
|
*/
|
|
272
501
|
ttlMinutes?: number;
|
|
273
502
|
/** Also send the hosted link to the person by SMS or WhatsApp. */
|
|
@@ -279,12 +508,13 @@ interface CreateSessionInput {
|
|
|
279
508
|
*/
|
|
280
509
|
subject?: SessionSubjectInput;
|
|
281
510
|
/**
|
|
282
|
-
* Override the
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
* `403
|
|
511
|
+
* Override the flow for this session only ({@link FlowOverrides}): its
|
|
512
|
+
* general settings and per-service settings, or turn a service `'off'`.
|
|
513
|
+
* `400 override_invalid` for an unknown key or an invalid result;
|
|
514
|
+
* `403 override_widens_flow` for a change that makes the flow less strict
|
|
515
|
+
* when the flow does not allow widening.
|
|
286
516
|
*/
|
|
287
|
-
|
|
517
|
+
overrides?: FlowOverrides;
|
|
288
518
|
/**
|
|
289
519
|
* Step inputs consumed server-side. The known anchors are typed (all
|
|
290
520
|
* strings — an `nni` is a 10-digit string, never a number); further keys
|
|
@@ -296,11 +526,59 @@ interface CreateSessionInput {
|
|
|
296
526
|
nni?: string;
|
|
297
527
|
/** E.164 phone number, e.g. `+22236123456`. */
|
|
298
528
|
phone?: string;
|
|
529
|
+
/** Email address for the email OTP step (`emailSource` `prefilled` / `prefilled_or_entered`). */
|
|
530
|
+
email?: string;
|
|
299
531
|
fullName?: string;
|
|
300
532
|
/** ISO 8601 date (`YYYY-MM-DD`). */
|
|
301
533
|
birthDate?: string;
|
|
534
|
+
/**
|
|
535
|
+
* Partner-supplied identity data (`supplied` mode only): the person's
|
|
536
|
+
* biographic record and photo as YOUR system holds them — for example
|
|
537
|
+
* from your own ANRPTS answer, converted with {@link registryFromAnrpts}.
|
|
538
|
+
* Sekyro AI stores it as data you vouch for, makes no registry call, and
|
|
539
|
+
* never receives or stores any registry key. `nni` must be set too and
|
|
540
|
+
* equal `suppliedIdentity.nni`. Refused unless Sekyro AI enabled the mode
|
|
541
|
+
* for the environment (`403 supplied_identity_not_entitled`); required in
|
|
542
|
+
* that mode when the app verifies identity (`422 supplied_identity_required`).
|
|
543
|
+
*/
|
|
544
|
+
suppliedIdentity?: SuppliedIdentityRecord;
|
|
302
545
|
} & Record<string, unknown>;
|
|
303
546
|
}
|
|
547
|
+
/**
|
|
548
|
+
* Partner-supplied identity data (`sessions.create` `input.suppliedIdentity`):
|
|
549
|
+
* the person's biographic record and photo, as your organization holds them.
|
|
550
|
+
* Sekyro AI treats it as identity data supplied by your organization, not as
|
|
551
|
+
* a registry lookup. Refusals at create: `400 supplied_identity_nni_mismatch`,
|
|
552
|
+
* `422 supplied_identity_stale` (`fetchedAt` older than 24 h),
|
|
553
|
+
* `422 supplied_identity_photo_unusable` (not a JPEG/PNG of at most 1 MB within the
|
|
554
|
+
* size bounds). In a `supplied` environment whose app verifies identity, a create
|
|
555
|
+
* without `input.suppliedIdentity` is `422 supplied_identity_required`. The face on
|
|
556
|
+
* the photo is checked after consent, at the face match (`no_face_reference`).
|
|
557
|
+
* @public
|
|
558
|
+
*/
|
|
559
|
+
interface SuppliedIdentityRecord {
|
|
560
|
+
/** 10-digit NNI, as a string. */
|
|
561
|
+
nni: string;
|
|
562
|
+
firstNameFr: string;
|
|
563
|
+
lastNameFr: string;
|
|
564
|
+
fatherNameFr?: string;
|
|
565
|
+
firstNameAr: string;
|
|
566
|
+
lastNameAr: string;
|
|
567
|
+
fatherNameAr?: string;
|
|
568
|
+
/** ISO 8601 date (`YYYY-MM-DD`). */
|
|
569
|
+
birthDate: string;
|
|
570
|
+
birthPlaceFr?: string;
|
|
571
|
+
birthPlaceAr?: string;
|
|
572
|
+
sex?: "M" | "F";
|
|
573
|
+
/** Nationality text as your source holds it (e.g. `Mauritanienne`). */
|
|
574
|
+
nationalities?: string[];
|
|
575
|
+
/** Base64 JPEG or PNG (at most 1 MB decoded). */
|
|
576
|
+
photo: string;
|
|
577
|
+
/** ISO 8601 date (`YYYY-MM-DD`) of the registry photo. */
|
|
578
|
+
photoDate?: string;
|
|
579
|
+
/** ISO 8601 date-time at which your system obtained this record. */
|
|
580
|
+
fetchedAt: string;
|
|
581
|
+
}
|
|
304
582
|
/** Per-request options. @public */
|
|
305
583
|
interface RequestOptions {
|
|
306
584
|
/**
|
|
@@ -321,6 +599,9 @@ interface CreatedSession {
|
|
|
321
599
|
clientToken: string;
|
|
322
600
|
/** Hosted verification link for this session. */
|
|
323
601
|
hostedUrl: string;
|
|
602
|
+
/** The flow version the session runs (the default flow when you sent no `flow`). */
|
|
603
|
+
flow?: SessionFlowRef;
|
|
604
|
+
/** The checks on the session's path (checks of a lane not taken are omitted). */
|
|
324
605
|
steps: SessionStep[];
|
|
325
606
|
/** ISO 8601 — when the session (and its link) stop accepting input. */
|
|
326
607
|
expiresAt: string;
|
|
@@ -382,6 +663,43 @@ interface SessionDevice {
|
|
|
382
663
|
deviceKeys: string[];
|
|
383
664
|
signals: SessionDeviceSignal[];
|
|
384
665
|
}
|
|
666
|
+
/**
|
|
667
|
+
* The national eID that verified the session's identity (the `eid_auth` check
|
|
668
|
+
* passed): the provider id (`{country}.{provider}`, e.g. `MR.houwiyeti`), its
|
|
669
|
+
* ISO 3166-1 alpha-2 country and when. A passed eID ends the session.
|
|
670
|
+
* @public
|
|
671
|
+
*/
|
|
672
|
+
interface EidResult {
|
|
673
|
+
provider: string;
|
|
674
|
+
country: string;
|
|
675
|
+
verifiedAt: string;
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* The full phone number and email address the person verified in a session
|
|
679
|
+
* (an OTP check that passed) — sent ONLY to you (the session view and your
|
|
680
|
+
* webhooks), never to the person's browser, and removed when the session's
|
|
681
|
+
* personal data is purged. You are the controller of these values. A
|
|
682
|
+
* prefilled value that was not verified is never listed.
|
|
683
|
+
* @public
|
|
684
|
+
*/
|
|
685
|
+
interface VerifiedContacts {
|
|
686
|
+
/** From a passed `phone_otp` check. */
|
|
687
|
+
phone?: {
|
|
688
|
+
/** E.164, e.g. `+22236123456`. */
|
|
689
|
+
number: string;
|
|
690
|
+
/** The channel the code was delivered on. */
|
|
691
|
+
channel: "whatsapp" | "sms";
|
|
692
|
+
/** ISO 8601. */
|
|
693
|
+
verifiedAt: string;
|
|
694
|
+
};
|
|
695
|
+
/** From a passed `email_otp` check. */
|
|
696
|
+
email?: {
|
|
697
|
+
/** The verified address (domain lowercased). */
|
|
698
|
+
address: string;
|
|
699
|
+
/** ISO 8601. */
|
|
700
|
+
verifiedAt: string;
|
|
701
|
+
};
|
|
702
|
+
}
|
|
385
703
|
/**
|
|
386
704
|
* The whitelisted session view returned by {@link SessionsApi.get}. Never
|
|
387
705
|
* contains the client token.
|
|
@@ -389,8 +707,11 @@ interface SessionDevice {
|
|
|
389
707
|
*/
|
|
390
708
|
interface Session {
|
|
391
709
|
id: string;
|
|
710
|
+
/** Sekyro flows: the flow version the session runs (absent on sessions created before flows). */
|
|
711
|
+
flow?: SessionFlowRef;
|
|
392
712
|
status: SessionStatus;
|
|
393
713
|
outcome: SessionOutcome | null;
|
|
714
|
+
/** The checks on the session's path (checks of a lane the person did not take are omitted). */
|
|
394
715
|
steps: SessionStep[];
|
|
395
716
|
/** ISO 8601. */
|
|
396
717
|
expiresAt: string;
|
|
@@ -420,13 +741,34 @@ interface Session {
|
|
|
420
741
|
* `failureReason: 'device_cooldown'`.
|
|
421
742
|
*/
|
|
422
743
|
retryAfter?: string;
|
|
423
|
-
/**
|
|
744
|
+
/**
|
|
745
|
+
* Dotted paths this session's {@link CreateSessionInput.overrides} changed
|
|
746
|
+
* (e.g. `settings.decisions.mode`, `services.liveness`).
|
|
747
|
+
*/
|
|
424
748
|
overriddenFields?: string[];
|
|
425
749
|
/**
|
|
426
750
|
* Risk signals recorded on the session (e.g. `device_velocity`,
|
|
427
|
-
* `timezone_mismatch`
|
|
751
|
+
* `timezone_mismatch`, `icao_non_compliant` when an `alert` ICAO policy flagged
|
|
752
|
+
* the selfie) — signals only, never a verdict by themselves.
|
|
428
753
|
*/
|
|
429
754
|
riskSignals?: string[];
|
|
755
|
+
/**
|
|
756
|
+
* `true` for a returning-user session (created with
|
|
757
|
+
* {@link SessionSubjectInput.reuse}): liveness + face match against the
|
|
758
|
+
* subject's stored reference photo only.
|
|
759
|
+
*/
|
|
760
|
+
returning?: true;
|
|
761
|
+
/** On a returning-user session: the subject (person) it re-verifies. */
|
|
762
|
+
reuseOf?: string;
|
|
763
|
+
/** The contacts verified in this session (passed OTP checks only); absent when none. */
|
|
764
|
+
verifiedContacts?: VerifiedContacts;
|
|
765
|
+
/** The national eID that verified this session (the `eid_auth` check passed); absent otherwise. */
|
|
766
|
+
eid?: EidResult;
|
|
767
|
+
/**
|
|
768
|
+
* ID mode (`portrait.purpose = id_document`) only: the ICAO portrait can be
|
|
769
|
+
* fetched with {@link SessionsApi.portrait}.
|
|
770
|
+
*/
|
|
771
|
+
portraitAvailable?: boolean;
|
|
430
772
|
}
|
|
431
773
|
/**
|
|
432
774
|
* `data` of the terminal / review-pending session lifecycle events
|
|
@@ -434,14 +776,17 @@ interface Session {
|
|
|
434
776
|
* `session.expired` | `session.rejected`) — ids and enums only, no civil data,
|
|
435
777
|
* scores or links. `outcome` and `steps` travel on `completed` / `failed`;
|
|
436
778
|
* `review_pending` carries `steps` without an outcome; `expired` carries the
|
|
437
|
-
* status
|
|
779
|
+
* status and the session's refs (`flow`, subject ids, `overriddenFields`).
|
|
438
780
|
* @public
|
|
439
781
|
*/
|
|
440
782
|
interface SessionLifecycleEventData {
|
|
441
783
|
sessionId: string;
|
|
442
784
|
status: SessionStatus;
|
|
443
785
|
outcome?: SessionOutcome | null;
|
|
444
|
-
|
|
786
|
+
/** The checks on the session's path (checks of a lane the person did not take are omitted). */
|
|
787
|
+
steps?: Array<Pick<SessionStep, "checkType" | "state" | "nodeId" | "service">>;
|
|
788
|
+
/** Sekyro flows: the flow version the session runs (absent on sessions created before flows). */
|
|
789
|
+
flow?: SessionFlowRef;
|
|
445
790
|
/** Machine-readable reason, when the transition has one. */
|
|
446
791
|
reason?: string;
|
|
447
792
|
/** End-user network context (no IP); on `completed` / `failed` when recorded. */
|
|
@@ -463,25 +808,140 @@ interface SessionLifecycleEventData {
|
|
|
463
808
|
* different subject than `subjectId` — the subjects are never merged.
|
|
464
809
|
*/
|
|
465
810
|
subjectConflict?: boolean;
|
|
811
|
+
/** `true` on a returning-user session (liveness + face match against the stored photo). */
|
|
812
|
+
returning?: true;
|
|
813
|
+
/** On a returning-user session: the subject (person) it re-verifies. */
|
|
814
|
+
reuseOf?: string;
|
|
466
815
|
/**
|
|
467
816
|
* On `session.failed` with `failureReason: 'device_cooldown'`: ISO time
|
|
468
817
|
* from which the device may start a new verification.
|
|
469
818
|
*/
|
|
470
819
|
retryAfter?: string;
|
|
471
|
-
/** Dotted
|
|
820
|
+
/** Dotted paths the session's create-time {@link CreateSessionInput.overrides} changed. */
|
|
472
821
|
overriddenFields?: string[];
|
|
822
|
+
/** On `completed` / `failed`: the contacts verified in this session (passed OTP checks only). */
|
|
823
|
+
verifiedContacts?: VerifiedContacts;
|
|
824
|
+
/** On `completed` / `failed`: the national eID that verified this session, when one did. */
|
|
825
|
+
eid?: EidResult;
|
|
826
|
+
/**
|
|
827
|
+
* ID mode only, on `completed` / `failed`: the ICAO portrait can be fetched
|
|
828
|
+
* with {@link SessionsApi.portrait} (the event never carries the image).
|
|
829
|
+
*/
|
|
830
|
+
portraitAvailable?: boolean;
|
|
473
831
|
}
|
|
474
832
|
/**
|
|
475
|
-
* `data` of `subject.updated` — a session linked to the subject reached
|
|
476
|
-
* terminal state
|
|
833
|
+
* `data` of `subject.updated` — either a session linked to the subject reached
|
|
834
|
+
* a terminal state (`sessionId`, session `status`, `outcome`), or the subject
|
|
835
|
+
* was revoked (`status: 'revoked'`, no session). Ids and enums only.
|
|
477
836
|
* @public
|
|
478
837
|
*/
|
|
479
838
|
interface SubjectUpdatedEventData {
|
|
480
839
|
subjectId: string;
|
|
840
|
+
/** The session that reached a terminal state; absent on a revocation. */
|
|
841
|
+
sessionId?: string;
|
|
842
|
+
status: SessionStatus | "revoked";
|
|
843
|
+
/** The session outcome; absent on a revocation. */
|
|
844
|
+
outcome?: SessionOutcome | null;
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* `data` of `subject.enrolled` — the subject's first reference photo was
|
|
848
|
+
* stored (it can now be used for returning-user sessions). Ids and enums only.
|
|
849
|
+
* @public
|
|
850
|
+
*/
|
|
851
|
+
interface SubjectEnrolledEventData {
|
|
852
|
+
subjectId: string;
|
|
853
|
+
/** The approved session the reference photo came from. */
|
|
481
854
|
sessionId: string;
|
|
855
|
+
assurance: SubjectAssurance;
|
|
856
|
+
}
|
|
857
|
+
/**
|
|
858
|
+
* `data` of `subject.deleted`. A delete through the subjects API carries
|
|
859
|
+
* `subjectId`; a right-to-erasure request carries the tokenized `subjectRef`
|
|
860
|
+
* (with `orgId` / `env`) instead — never the national number.
|
|
861
|
+
* @public
|
|
862
|
+
*/
|
|
863
|
+
interface SubjectDeletedEventData {
|
|
864
|
+
subjectId?: string;
|
|
865
|
+
subjectRef?: string;
|
|
866
|
+
orgId?: string;
|
|
867
|
+
env?: SekyroEnvironment;
|
|
868
|
+
}
|
|
869
|
+
/** Subject lifecycle: a revoked subject cannot be reused. @public */
|
|
870
|
+
type SubjectStatus = "active" | "revoked";
|
|
871
|
+
/**
|
|
872
|
+
* How strongly a subject's identity was established: the reference photo
|
|
873
|
+
* came from the national registry, the document's chip (`chip_biometric`, a
|
|
874
|
+
* passed chip read plus a face match) or the document, and a face match passed
|
|
875
|
+
* (`*_biometric`) or the session had no face match (`*_only`). `supplied_*`:
|
|
876
|
+
* partner-supplied identity data (`input.suppliedIdentity`), with
|
|
877
|
+
* (`supplied_biometric`) or without (`supplied_only`) a face match against its photo.
|
|
878
|
+
* @public
|
|
879
|
+
*/
|
|
880
|
+
type SubjectAssurance = "registry_biometric" | "chip_biometric" | "document_biometric" | "registry_only" | "document_only" | "supplied_biometric" | "supplied_only";
|
|
881
|
+
/**
|
|
882
|
+
* Origin of a subject's stored reference photo, best first (`chip`: the document chip's portrait;
|
|
883
|
+
* `org_supplied`: the photo of your partner-supplied identity data).
|
|
884
|
+
* @public
|
|
885
|
+
*/
|
|
886
|
+
type SubjectReferenceSource = "registry" | "doc_registry" | "chip" | "org_supplied" | "document";
|
|
887
|
+
/** One session linked to a subject. @public */
|
|
888
|
+
interface SubjectSession {
|
|
889
|
+
sessionId: string;
|
|
890
|
+
appId: string | null;
|
|
891
|
+
/** ISO 8601 — when the session was linked. */
|
|
892
|
+
at: string;
|
|
482
893
|
status: SessionStatus;
|
|
483
894
|
outcome: SessionOutcome | null;
|
|
484
895
|
}
|
|
896
|
+
/**
|
|
897
|
+
* A subject (the same person across your apps), as `GET /subjects/:id`
|
|
898
|
+
* returns it. Never contains photo keys or URLs.
|
|
899
|
+
* @public
|
|
900
|
+
*/
|
|
901
|
+
interface Subject {
|
|
902
|
+
id: string;
|
|
903
|
+
status: SubjectStatus;
|
|
904
|
+
/** ISO 8601 — present only when revoked. */
|
|
905
|
+
revokedAt?: string;
|
|
906
|
+
sessions: SubjectSession[];
|
|
907
|
+
externalRefs: string[];
|
|
908
|
+
/** ISO 8601. */
|
|
909
|
+
firstSeenAt: string;
|
|
910
|
+
/** ISO 8601. */
|
|
911
|
+
lastSeenAt: string;
|
|
912
|
+
/** ISO 8601, or `null` before the first approved session. */
|
|
913
|
+
lastPassedAt: string | null;
|
|
914
|
+
/** ISO 8601 of the last approved full or returning session, or `null`. */
|
|
915
|
+
lastVerifiedAt: string | null;
|
|
916
|
+
/** The stored reference photo's origin and date — `null` until one is stored. */
|
|
917
|
+
reference: {
|
|
918
|
+
source: SubjectReferenceSource;
|
|
919
|
+
capturedAt: string;
|
|
920
|
+
} | null;
|
|
921
|
+
assurance: SubjectAssurance | null;
|
|
922
|
+
/**
|
|
923
|
+
* A returning-user session can be created now: active, a reference photo is
|
|
924
|
+
* stored, and the last FULL verification (returning-user sessions do not
|
|
925
|
+
* reset it) is within the returning-user limit of your app's default flow
|
|
926
|
+
* (`settings.returning`: turned on, and `maxAgeMonths` when set).
|
|
927
|
+
*/
|
|
928
|
+
returningReady: boolean;
|
|
929
|
+
/** The verified name / birth date of the latest approved session. */
|
|
930
|
+
display?: {
|
|
931
|
+
name?: string;
|
|
932
|
+
birthDate?: string;
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
/** Result of {@link SubjectsApi.delete}. @public */
|
|
936
|
+
interface DeletedSubject {
|
|
937
|
+
id: string;
|
|
938
|
+
deleted: true;
|
|
939
|
+
}
|
|
940
|
+
/** Options of {@link SubjectsApi.revoke}. @public */
|
|
941
|
+
interface RevokeSubjectInput {
|
|
942
|
+
/** Kept on the audit trail only (≤ 500 characters). Do not put personal data here. */
|
|
943
|
+
reason?: string;
|
|
944
|
+
}
|
|
485
945
|
/**
|
|
486
946
|
* `data` of `subject.suspicious_activity` — a device already linked to
|
|
487
947
|
* ANOTHER subject was used for a session of this subject. `count` is the
|
|
@@ -501,6 +961,12 @@ interface SessionStepCompletedEventData {
|
|
|
501
961
|
sessionId: string;
|
|
502
962
|
checkType: CheckType;
|
|
503
963
|
state: CheckState;
|
|
964
|
+
/** Sekyro flows: the flow node of the passed check. */
|
|
965
|
+
nodeId?: string;
|
|
966
|
+
/** Sekyro flows: the service of that node. */
|
|
967
|
+
service?: ServiceId;
|
|
968
|
+
/** Sekyro flows: the flow version the session runs (absent on sessions created before flows). */
|
|
969
|
+
flow?: SessionFlowRef;
|
|
504
970
|
/** The subject (person) the session is linked to, when known. */
|
|
505
971
|
subjectId?: string;
|
|
506
972
|
/** Your own id for the person, from `subject.externalRef` at create. */
|
|
@@ -510,6 +976,12 @@ interface SessionStepCompletedEventData {
|
|
|
510
976
|
* different subject than `subjectId` — the subjects are never merged.
|
|
511
977
|
*/
|
|
512
978
|
subjectConflict?: boolean;
|
|
979
|
+
/** `true` on a returning-user session (liveness + face match against the stored photo). */
|
|
980
|
+
returning?: true;
|
|
981
|
+
/** On a returning-user session: the subject (person) it re-verifies. */
|
|
982
|
+
reuseOf?: string;
|
|
983
|
+
/** When the passed check is `phone_otp` / `email_otp`: that one verified contact. */
|
|
984
|
+
verifiedContacts?: VerifiedContacts;
|
|
513
985
|
}
|
|
514
986
|
/**
|
|
515
987
|
* `data` of `session.review_decided` — a human (or the review-timeout sweep)
|
|
@@ -522,6 +994,8 @@ interface SessionReviewDecidedEventData {
|
|
|
522
994
|
sessionId: string;
|
|
523
995
|
outcome: "pass" | "fail";
|
|
524
996
|
reason: string;
|
|
997
|
+
/** Sekyro flows: the flow version the session runs (absent on sessions created before flows). */
|
|
998
|
+
flow?: SessionFlowRef;
|
|
525
999
|
/** The subject (person) the session is linked to, when known. */
|
|
526
1000
|
subjectId?: string;
|
|
527
1001
|
/** Your own id for the person, from `subject.externalRef` at create. */
|
|
@@ -531,6 +1005,12 @@ interface SessionReviewDecidedEventData {
|
|
|
531
1005
|
* different subject than `subjectId` — the subjects are never merged.
|
|
532
1006
|
*/
|
|
533
1007
|
subjectConflict?: boolean;
|
|
1008
|
+
/** `true` on a returning-user session (liveness + face match against the stored photo). */
|
|
1009
|
+
returning?: true;
|
|
1010
|
+
/** On a returning-user session: the subject (person) it re-verifies. */
|
|
1011
|
+
reuseOf?: string;
|
|
1012
|
+
/** ID mode only: the ICAO portrait can be fetched with {@link SessionsApi.portrait}. */
|
|
1013
|
+
portraitAvailable?: boolean;
|
|
534
1014
|
}
|
|
535
1015
|
/**
|
|
536
1016
|
* Event type → the shape of its `data`. Session events are typed; the
|
|
@@ -547,10 +1027,10 @@ interface WebhookEventDataMap {
|
|
|
547
1027
|
"session.rejected": SessionLifecycleEventData;
|
|
548
1028
|
"session.expired": SessionLifecycleEventData;
|
|
549
1029
|
"session.failed": SessionLifecycleEventData;
|
|
550
|
-
"subject.enrolled":
|
|
1030
|
+
"subject.enrolled": SubjectEnrolledEventData;
|
|
551
1031
|
"subject.updated": SubjectUpdatedEventData;
|
|
552
1032
|
"subject.suspicious_activity": SubjectSuspiciousActivityEventData;
|
|
553
|
-
"subject.deleted":
|
|
1033
|
+
"subject.deleted": SubjectDeletedEventData;
|
|
554
1034
|
"aml.match_flagged": Record<string, unknown>;
|
|
555
1035
|
"payment.received": Record<string, unknown>;
|
|
556
1036
|
"invoice.generated": Record<string, unknown>;
|
|
@@ -638,7 +1118,7 @@ declare class SessionsApi {
|
|
|
638
1118
|
* surface on purpose (only its bound `call` crosses this boundary).
|
|
639
1119
|
* @internal
|
|
640
1120
|
*/
|
|
641
|
-
constructor(call: <T>(method: "GET" | "POST", path: string, body?: unknown, idempotencyKey?: string) => Promise<T>);
|
|
1121
|
+
constructor(call: <T>(method: "GET" | "POST" | "DELETE", path: string, body?: unknown, idempotencyKey?: string) => Promise<T>);
|
|
642
1122
|
/**
|
|
643
1123
|
* `POST /sessions`. Returns the one-time `clientToken` — hand it to the
|
|
644
1124
|
* browser, never persist it. Pass an `idempotencyKey` so a retried call
|
|
@@ -650,10 +1130,54 @@ declare class SessionsApi {
|
|
|
650
1130
|
* optional-document session on the person's behalf (the hosted method
|
|
651
1131
|
* screen is then skipped). `409 method_locked` once the choice can no
|
|
652
1132
|
* longer change; `409 session_not_active` on a finished or expired session.
|
|
1133
|
+
* On a flow session: `409 choice_not_found` (the flow has no identity-method
|
|
1134
|
+
* choice), `409 choice_locked`, `409 choice_option_unavailable` (see
|
|
1135
|
+
* {@link isFlowError}).
|
|
653
1136
|
*/
|
|
654
1137
|
selectMethod(id: string, method: IdentityMethod): Promise<Session>;
|
|
655
1138
|
/** `GET /sessions/:id` — the whitelisted view (no client token). */
|
|
656
1139
|
get(id: string): Promise<Session>;
|
|
1140
|
+
/**
|
|
1141
|
+
* `GET /sessions/:id/portrait?format=url` — ID mode: a 5-minute presigned
|
|
1142
|
+
* link to the 480×640 ICAO portrait (JPEG). Needs the `portrait:read` scope
|
|
1143
|
+
* (keys minted from the dashboard carry it). `404 portrait_not_available`
|
|
1144
|
+
* until the session's `portrait_icao` check has passed (`portraitAvailable`).
|
|
1145
|
+
*/
|
|
1146
|
+
portrait(id: string): Promise<SessionPortraitLink>;
|
|
1147
|
+
}
|
|
1148
|
+
/**
|
|
1149
|
+
* `sekyro.subjects` — read and manage subjects (the same person across your
|
|
1150
|
+
* apps). Reads need the `subjects:read` scope, `revoke` / `delete` the
|
|
1151
|
+
* `subjects:write` scope (keys minted from the dashboard carry both; an older
|
|
1152
|
+
* key answers `403 insufficient_scope`). A foreign or unknown id answers
|
|
1153
|
+
* `404 subject_not_found`.
|
|
1154
|
+
*
|
|
1155
|
+
* Type-only export, like {@link SessionsApi}: obtained through
|
|
1156
|
+
* {@link Sekyro.subjects}.
|
|
1157
|
+
* @public
|
|
1158
|
+
*/
|
|
1159
|
+
declare class SubjectsApi {
|
|
1160
|
+
private readonly call;
|
|
1161
|
+
/** @internal */
|
|
1162
|
+
constructor(call: <T>(method: "GET" | "POST" | "DELETE", path: string, body?: unknown, idempotencyKey?: string) => Promise<T>);
|
|
1163
|
+
/** `GET /subjects/:id` — the subject, its sessions and its returning-user readiness. */
|
|
1164
|
+
get(id: string): Promise<Subject>;
|
|
1165
|
+
/** `GET /subjects?externalRef=…` — the subjects carrying your own id (newest first, at most 50). */
|
|
1166
|
+
list(query: {
|
|
1167
|
+
externalRef: string;
|
|
1168
|
+
}): Promise<Subject[]>;
|
|
1169
|
+
/**
|
|
1170
|
+
* `POST /subjects/:id/revoke` — the subject can no longer be used for
|
|
1171
|
+
* returning-user sessions. Idempotent: revoking again returns the same view.
|
|
1172
|
+
* Emits `subject.updated` with `status: 'revoked'`.
|
|
1173
|
+
*/
|
|
1174
|
+
revoke(id: string, input?: RevokeSubjectInput, opts?: RequestOptions): Promise<Subject>;
|
|
1175
|
+
/**
|
|
1176
|
+
* `DELETE /subjects/:id` — deletes the subject's stored photos, face
|
|
1177
|
+
* templates and identifiers, and unlinks its sessions. Emits
|
|
1178
|
+
* `subject.deleted`. Cannot be undone; a second call answers `404`.
|
|
1179
|
+
*/
|
|
1180
|
+
delete(id: string): Promise<DeletedSubject>;
|
|
657
1181
|
}
|
|
658
1182
|
/**
|
|
659
1183
|
* Sekyro AI partner API client. Server-side only: it carries your API key.
|
|
@@ -670,8 +1194,17 @@ declare class SessionsApi {
|
|
|
670
1194
|
* @public
|
|
671
1195
|
*/
|
|
672
1196
|
declare class Sekyro {
|
|
1197
|
+
#private;
|
|
673
1198
|
readonly sessions: SessionsApi;
|
|
1199
|
+
readonly subjects: SubjectsApi;
|
|
674
1200
|
constructor(opts: SekyroOptions);
|
|
1201
|
+
/**
|
|
1202
|
+
* `GET /flows` — the published flows of the API key's app (default flow
|
|
1203
|
+
* first, then by name). Pass a flow's `slug` or `id` as
|
|
1204
|
+
* {@link CreateSessionInput.flow}. Needs the `sessions:create` scope; a key
|
|
1205
|
+
* not bound to an app answers `401 key_not_bound`.
|
|
1206
|
+
*/
|
|
1207
|
+
listFlows(): Promise<FlowSummary[]>;
|
|
675
1208
|
}
|
|
676
1209
|
|
|
677
1210
|
/** Why {@link verifyWebhook} rejected a delivery. @public */
|
|
@@ -687,7 +1220,7 @@ declare class SekyroWebhookError extends Error {
|
|
|
687
1220
|
constructor(code: SekyroWebhookErrorCode, message?: string);
|
|
688
1221
|
}
|
|
689
1222
|
/** Why the {@link Sekyro} constructor rejected its options. @public */
|
|
690
|
-
type SekyroConfigErrorCode = "missing_api_key" | "invalid_base_url";
|
|
1223
|
+
type SekyroConfigErrorCode = "missing_api_key" | "invalid_base_url" | "invalid_registry_record";
|
|
691
1224
|
/**
|
|
692
1225
|
* Thrown synchronously by `new Sekyro(...)` for an unusable configuration —
|
|
693
1226
|
* before any request is made. Extends `TypeError` so existing
|
|
@@ -699,15 +1232,104 @@ declare class SekyroConfigError extends TypeError {
|
|
|
699
1232
|
readonly code: SekyroConfigErrorCode;
|
|
700
1233
|
constructor(code: SekyroConfigErrorCode, message?: string);
|
|
701
1234
|
}
|
|
1235
|
+
/**
|
|
1236
|
+
* The flow codes of the partner API (Sekyro flows). Each carries
|
|
1237
|
+
* {@link SekyroApiError.details} (see {@link SekyroFlowErrorDetailsMap} and
|
|
1238
|
+
* {@link isFlowError}). On `sessions.create`:
|
|
1239
|
+
* - `flow_not_found` (404): no flow with this slug or `flw_` id in the key's app;
|
|
1240
|
+
* - `flow_not_published` (409): the flow has no published version yet;
|
|
1241
|
+
* - `flow_archived` (409): the flow is archived;
|
|
1242
|
+
* - `override_invalid` (400): an unknown key or value in `overrides`, or a
|
|
1243
|
+
* result that is not a valid flow;
|
|
1244
|
+
* - `override_widens_flow` (403): the override makes the flow less strict
|
|
1245
|
+
* (e.g. a service turned `'off'`) and the flow does not allow widening;
|
|
1246
|
+
* - `reuse_disabled` (409): `subject.reuse` on a flow whose returning-user
|
|
1247
|
+
* sessions are turned off.
|
|
1248
|
+
*
|
|
1249
|
+
* On `sessions.selectMethod` (a flow session's identity-method choice):
|
|
1250
|
+
* `choice_not_found` (409: the session's flow has no identity-method choice),
|
|
1251
|
+
* `choice_locked` (409: it can no longer change) and
|
|
1252
|
+
* `choice_option_unavailable` (409: that method is not offered).
|
|
1253
|
+
* @public
|
|
1254
|
+
*/
|
|
1255
|
+
type SekyroFlowErrorCode = "flow_not_found" | "flow_not_published" | "flow_archived" | "override_invalid" | "override_widens_flow" | "reuse_disabled" | "choice_not_found" | "choice_locked" | "choice_option_unavailable";
|
|
1256
|
+
/**
|
|
1257
|
+
* One machine-readable issue of a flow error. Never carries a value you sent.
|
|
1258
|
+
* @public
|
|
1259
|
+
*/
|
|
1260
|
+
interface FlowErrorIssue {
|
|
1261
|
+
/**
|
|
1262
|
+
* A flow validation code (e.g. `face_match_needs_liveness`), `schema_invalid`,
|
|
1263
|
+
* `schema_unknown_field`, `field_widens_flow`, or the error's own code.
|
|
1264
|
+
*/
|
|
1265
|
+
code: string;
|
|
1266
|
+
/** A short plain English sentence. */
|
|
1267
|
+
message: string;
|
|
1268
|
+
/** The field of your request body, e.g. `overrides.services.liveness.attempts`, `flow`, `subject.reuse`. */
|
|
1269
|
+
path?: string;
|
|
1270
|
+
/** A node of your app's flow. */
|
|
1271
|
+
nodeId?: string;
|
|
1272
|
+
/** The service of that node (or of the `overrides.services` key). */
|
|
1273
|
+
service?: ServiceId;
|
|
1274
|
+
/** `override_widens_flow`: the widened field, e.g. `settings.eligibility.minAge`, `services.nfc`. */
|
|
1275
|
+
field?: string;
|
|
1276
|
+
}
|
|
1277
|
+
/** `details` common to every flow error: at least one issue. @public */
|
|
1278
|
+
interface FlowErrorDetails {
|
|
1279
|
+
issues: FlowErrorIssue[];
|
|
1280
|
+
}
|
|
1281
|
+
/** `details` of `override_widens_flow`: the widened fields, plus one `field_widens_flow` issue each. @public */
|
|
1282
|
+
interface FlowWidensErrorDetails extends FlowErrorDetails {
|
|
1283
|
+
fields: string[];
|
|
1284
|
+
}
|
|
1285
|
+
/** `details` of `flow_not_published`, `flow_archived` and `reuse_disabled`: the flow concerned. @public */
|
|
1286
|
+
interface FlowRefErrorDetails extends FlowErrorDetails {
|
|
1287
|
+
flow: {
|
|
1288
|
+
id: string;
|
|
1289
|
+
slug: string;
|
|
1290
|
+
};
|
|
1291
|
+
}
|
|
1292
|
+
/**
|
|
1293
|
+
* {@link SekyroFlowErrorCode} → the shape of its {@link SekyroApiError.details}.
|
|
1294
|
+
* @public
|
|
1295
|
+
*/
|
|
1296
|
+
interface SekyroFlowErrorDetailsMap {
|
|
1297
|
+
flow_not_found: FlowErrorDetails;
|
|
1298
|
+
flow_not_published: FlowRefErrorDetails;
|
|
1299
|
+
flow_archived: FlowRefErrorDetails;
|
|
1300
|
+
override_invalid: FlowErrorDetails;
|
|
1301
|
+
override_widens_flow: FlowWidensErrorDetails;
|
|
1302
|
+
reuse_disabled: FlowRefErrorDetails;
|
|
1303
|
+
choice_not_found: FlowErrorDetails;
|
|
1304
|
+
choice_locked: FlowErrorDetails;
|
|
1305
|
+
choice_option_unavailable: FlowErrorDetails;
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* A {@link SekyroApiError} narrowed by {@link isFlowError}: `code` is a flow
|
|
1309
|
+
* code and `details` has that code's shape.
|
|
1310
|
+
* @public
|
|
1311
|
+
*/
|
|
1312
|
+
type SekyroFlowError<C extends SekyroFlowErrorCode = SekyroFlowErrorCode> = C extends SekyroFlowErrorCode ? SekyroApiError & {
|
|
1313
|
+
readonly code: C;
|
|
1314
|
+
readonly details: SekyroFlowErrorDetailsMap[C];
|
|
1315
|
+
} : never;
|
|
1316
|
+
/**
|
|
1317
|
+
* {@link SekyroApiError.code}: an SDK code, a documented flow code, or any
|
|
1318
|
+
* other API code (the union stays open so a new API code never breaks a build).
|
|
1319
|
+
* @public
|
|
1320
|
+
*/
|
|
1321
|
+
type SekyroApiErrorCode = SekyroClientErrorCode | SekyroFlowErrorCode | (string & {});
|
|
702
1322
|
/** Constructor input of {@link SekyroApiError}. @public */
|
|
703
1323
|
interface SekyroApiErrorInit {
|
|
704
1324
|
/** HTTP status; `0` when no response was received (network / timeout). */
|
|
705
1325
|
status: number;
|
|
706
1326
|
/** API error code, or `network` | `timeout` | `http_error` | `malformed_response`. */
|
|
707
|
-
code:
|
|
1327
|
+
code: SekyroApiErrorCode;
|
|
708
1328
|
message: string;
|
|
709
1329
|
/** The API's `request_id`, when the response carried one. */
|
|
710
1330
|
requestId?: string;
|
|
1331
|
+
/** The API's `error.details`, when the response carried them (the flow codes: {@link SekyroFlowErrorDetailsMap}). */
|
|
1332
|
+
details?: unknown;
|
|
711
1333
|
/** Underlying error (network failures, abort reasons, JSON parse errors). */
|
|
712
1334
|
cause?: unknown;
|
|
713
1335
|
}
|
|
@@ -725,11 +1347,90 @@ type SekyroClientErrorCode = "network" | "timeout" | "http_error" | "malformed_r
|
|
|
725
1347
|
declare class SekyroApiError extends Error {
|
|
726
1348
|
readonly name = "SekyroApiError";
|
|
727
1349
|
readonly status: number;
|
|
728
|
-
readonly code:
|
|
1350
|
+
readonly code: SekyroApiErrorCode;
|
|
729
1351
|
readonly requestId: string | undefined;
|
|
1352
|
+
/**
|
|
1353
|
+
* The API's `error.details`, when the response carried them; `undefined`
|
|
1354
|
+
* otherwise. Untyped here: narrow with {@link isFlowError} to read a flow
|
|
1355
|
+
* code's documented shape ({@link SekyroFlowErrorDetailsMap}).
|
|
1356
|
+
*/
|
|
1357
|
+
readonly details: unknown;
|
|
730
1358
|
readonly retryable: boolean;
|
|
731
1359
|
constructor(init: SekyroApiErrorInit);
|
|
732
1360
|
}
|
|
1361
|
+
/**
|
|
1362
|
+
* Narrow an error to a flow error, optionally to given codes: `true` only for
|
|
1363
|
+
* a {@link SekyroApiError} with a flow code whose `details` have that code's
|
|
1364
|
+
* documented shape, so `err.details` is typed after the check. An error whose
|
|
1365
|
+
* `details` are missing or unexpected is not narrowed (read `err.code`).
|
|
1366
|
+
*
|
|
1367
|
+
* @example
|
|
1368
|
+
* ```ts
|
|
1369
|
+
* try {
|
|
1370
|
+
* await sekyro.sessions.create({ flow, overrides });
|
|
1371
|
+
* } catch (err) {
|
|
1372
|
+
* if (isFlowError(err, "override_widens_flow")) err.details.fields; // string[]
|
|
1373
|
+
* else if (isFlowError(err)) err.details.issues.map((i) => i.path);
|
|
1374
|
+
* }
|
|
1375
|
+
* ```
|
|
1376
|
+
* @public
|
|
1377
|
+
*/
|
|
1378
|
+
declare function isFlowError<C extends SekyroFlowErrorCode = SekyroFlowErrorCode>(err: unknown, ...codes: C[]): err is SekyroFlowError<C>;
|
|
1379
|
+
|
|
1380
|
+
/**
|
|
1381
|
+
* The raw ANRPTS `getPersonne` answer your server received with your own
|
|
1382
|
+
* access: `{ personne, photo }`, where `photo` is a base64 JPEG (optionally
|
|
1383
|
+
* data-URL prefixed). Only the fields the mapping reads are typed.
|
|
1384
|
+
* @public
|
|
1385
|
+
*/
|
|
1386
|
+
interface AnrptsPersonneResponse {
|
|
1387
|
+
personne?: {
|
|
1388
|
+
nni?: string | undefined;
|
|
1389
|
+
prenomFr?: string | undefined;
|
|
1390
|
+
patronymeFr?: string | undefined;
|
|
1391
|
+
perePrenomFr?: string | undefined;
|
|
1392
|
+
prenomAr?: string | undefined;
|
|
1393
|
+
patronymeAr?: string | undefined;
|
|
1394
|
+
perePrenomAr?: string | undefined;
|
|
1395
|
+
/** ISO date or date-time (`1990-01-01T00:00:00.000Z`), or `DD/MM/YYYY`. */
|
|
1396
|
+
dateNaissance?: string | undefined;
|
|
1397
|
+
lieuNaissanceFr?: string | undefined;
|
|
1398
|
+
lieuNaissanceAr?: string | undefined;
|
|
1399
|
+
sexeCode?: string | undefined;
|
|
1400
|
+
nationalities?: string[] | undefined;
|
|
1401
|
+
[key: string]: unknown;
|
|
1402
|
+
};
|
|
1403
|
+
photo?: string | undefined;
|
|
1404
|
+
datePhoto?: string | undefined;
|
|
1405
|
+
[key: string]: unknown;
|
|
1406
|
+
}
|
|
1407
|
+
/** Options of {@link registryFromAnrpts}. @public */
|
|
1408
|
+
interface RegistryFromAnrptsOptions {
|
|
1409
|
+
/**
|
|
1410
|
+
* When YOUR system received this ANRPTS answer (not "now" when you map a cached
|
|
1411
|
+
* answer). Required: records older than 24 h are refused at session create.
|
|
1412
|
+
*/
|
|
1413
|
+
fetchedAt: Date | string;
|
|
1414
|
+
}
|
|
1415
|
+
/**
|
|
1416
|
+
* Convert an ANRPTS `getPersonne` answer that YOUR server already received,
|
|
1417
|
+
* with your own access, into the `input.suppliedIdentity` record of
|
|
1418
|
+
* `sessions.create` (partner-supplied identity data). A pure, local mapping:
|
|
1419
|
+
* it makes no network call, and Sekyro AI never sees, receives or stores any
|
|
1420
|
+
* ANRPTS key — only the record and photo you pass.
|
|
1421
|
+
*
|
|
1422
|
+
* ```ts
|
|
1423
|
+
* const anrpts = await myAnrptsClient.getPersonne(nni); // your call, your key
|
|
1424
|
+
* const suppliedIdentity = registryFromAnrpts(anrpts, { fetchedAt: receivedAt });
|
|
1425
|
+
* await sekyro.sessions.create({ input: { nni, suppliedIdentity } });
|
|
1426
|
+
* ```
|
|
1427
|
+
*
|
|
1428
|
+
* Throws {@link SekyroConfigError} (`invalid_registry_record`) when a required
|
|
1429
|
+
* field (NNI, French and Arabic first and last names, birth date, photo) is
|
|
1430
|
+
* missing. The message names the field, never its value.
|
|
1431
|
+
* @public
|
|
1432
|
+
*/
|
|
1433
|
+
declare function registryFromAnrpts(response: AnrptsPersonneResponse, options: RegistryFromAnrptsOptions): SuppliedIdentityRecord;
|
|
733
1434
|
|
|
734
1435
|
/**
|
|
735
1436
|
* The HTTP header carrying the webhook signature:
|
|
@@ -787,4 +1488,4 @@ interface VerifyWebhookOptions {
|
|
|
787
1488
|
*/
|
|
788
1489
|
declare function verifyWebhook(rawBody: string, header: string | null | undefined, secret: string, opts?: VerifyWebhookOptions): WebhookEnvelope;
|
|
789
1490
|
|
|
790
|
-
export { type CheckState, type CheckType, type CreateSessionInput, type CreatedSession, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type DecisionReason, type DeepPartial, type DeliverOptions, type
|
|
1491
|
+
export { type AnrptsPersonneResponse, type CheckState, type CheckType, type CreateSessionInput, type CreatedSession, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type DecisionReason, type DeepPartial, type DeletedSubject, type DeliverOptions, type DocumentSubstitutionSettings, type EidResult, type EligibilityReason, type FetchLike, type FlowErrorDetails, type FlowErrorIssue, type FlowOverridableSettings, type FlowOverrides, type FlowRefErrorDetails, type FlowServiceSettings, type FlowSummary, type FlowWidensErrorDetails, type IdentityMethod, LEGACY_SIGNATURE_HEADER, type Locale, type MatchReason, type PolicyFailureReason, type PortraitReportEntry, type ProbeBindingReason, type ProbeQuality, type ProfileDocumentType, type RegistryFromAnrptsOptions, type RequestOptions, type RevokeSubjectInput, SEKYRO_SIGNATURE_HEADER, Sekyro, SekyroApiError, type SekyroApiErrorCode, type SekyroApiErrorInit, type SekyroClientErrorCode, SekyroConfigError, type SekyroConfigErrorCode, type SekyroEnvironment, type SekyroFlowError, type SekyroFlowErrorCode, type SekyroFlowErrorDetailsMap, type SekyroOptions, SekyroWebhookError, type SekyroWebhookErrorCode, type ServiceId, type Session, type SessionDevice, type SessionDeviceSignal, type SessionEventData, type SessionFailureReason, type SessionFlowRef, type SessionLifecycleEventData, type SessionNetwork, type SessionNetworkEvent, type SessionOutcome, type SessionPortraitLink, type SessionReviewDecidedEventData, type SessionStatus, type SessionStep, type SessionStepCompletedEventData, type SessionSubjectInput, SessionsApi, type Subject, type SubjectAssurance, type SubjectDeletedEventData, type SubjectEnrolledEventData, type SubjectReferenceSource, type SubjectReuseTarget, type SubjectSession, type SubjectStatus, type SubjectSuspiciousActivityEventData, type SubjectUpdatedEventData, SubjectsApi, type SuppliedIdentityRecord, type VerifiedContacts, type VerifyWebhookOptions, type WebhookEnvelope, type WebhookEnvelopeOf, type WebhookEventDataMap, type WebhookEventType, isFlowError, registryFromAnrpts, signatureFromHeaders, verifyWebhook };
|