@sekyro/node 0.1.0-rc.2 → 0.1.0-rc.3
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 +12 -0
- package/LICENSE +3 -3
- package/README.md +3 -3
- package/dist/index.cjs +1 -308
- package/dist/index.d.cts +394 -8
- package/dist/index.d.ts +394 -8
- package/dist/index.js +1 -272
- package/package.json +6 -9
- package/sbom.cdx.json +153 -0
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Wire-level enums and shapes of the Sekyro partner API (`/api/v2`). These
|
|
2
|
+
* Wire-level enums and shapes of the Sekyro AI partner API (`/api/v2`). These
|
|
3
3
|
* mirror the backend's frozen partner contract; they are plain string unions so
|
|
4
4
|
* a newer API value never throws at runtime — it simply widens the type in the
|
|
5
5
|
* next SDK release.
|
|
@@ -14,10 +14,71 @@ type SessionStatus = "created" | "in_progress" | "review_pending" | "completed"
|
|
|
14
14
|
* @public
|
|
15
15
|
*/
|
|
16
16
|
type SessionOutcome = "approved" | "review" | "rejected";
|
|
17
|
+
/**
|
|
18
|
+
* How the person proves their identity on an optional-document app: type the
|
|
19
|
+
* national number, or photograph the document.
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
type IdentityMethod = "national_number" | "document_photo";
|
|
17
23
|
/** The verification checks a flow may contain. @public */
|
|
18
24
|
type CheckType = "liveness" | "face_match" | "doc_ocr" | "population_registry" | "phone_otp";
|
|
19
25
|
/** Per-check execution state within a session. @public */
|
|
20
26
|
type CheckState = "pending" | "input_required" | "processing" | "passed" | "failed" | "review" | "skipped";
|
|
27
|
+
/**
|
|
28
|
+
* Why a session was stopped by a profile-v2 policy gate rather than by a
|
|
29
|
+
* failed check:
|
|
30
|
+
* - `location_not_allowed` — the end user's IP location is not allowed for the app;
|
|
31
|
+
* - `anonymizer_blocked` — an anonymizer (VPN / proxy / Tor) was detected while the app blocks them;
|
|
32
|
+
* - `capture_tampered` — the device reported a tampered capture (virtual
|
|
33
|
+
* camera, hooking, emulator…) while the app's `device.tamper` is `block`;
|
|
34
|
+
* - `device_velocity_exceeded` — the device already verified more different
|
|
35
|
+
* people than `device.velocity` allows, with `action: 'block'`;
|
|
36
|
+
* - `device_cooldown` — the device had too many rejected sessions
|
|
37
|
+
* (`cooldown` tiers); {@link Session.retryAfter} says when it may try again.
|
|
38
|
+
* Not billed.
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
type SessionFailureReason = "location_not_allowed" | "anonymizer_blocked" | "capture_tampered" | "device_velocity_exceeded" | "device_cooldown";
|
|
42
|
+
/**
|
|
43
|
+
* Profile-v2 decision-mode reasons a check's {@link SessionStep.reason} may
|
|
44
|
+
* carry when the app decides automatically (`decisions.mode: 'automatic'`)
|
|
45
|
+
* instead of routing to human review. All are retryable within the step's
|
|
46
|
+
* attempts: `liveness_inconclusive` (liveness middle band),
|
|
47
|
+
* `match_inconclusive` (face match middle band on every reference),
|
|
48
|
+
* `document_authenticity` (doc_ocr authenticity warning — retake the original)
|
|
49
|
+
* and `mobile_required` (liveness captured on a desktop — continue on a phone;
|
|
50
|
+
* not billed). Every inconclusive attempt is billed.
|
|
51
|
+
* @public
|
|
52
|
+
*/
|
|
53
|
+
type DecisionReason = "liveness_inconclusive" | "match_inconclusive" | "document_authenticity" | "mobile_required";
|
|
54
|
+
/**
|
|
55
|
+
* Profile-v2 eligibility reasons a check's {@link SessionStep.reason} may carry:
|
|
56
|
+
* `document_type_not_accepted` (doc_ocr; the person may pick another
|
|
57
|
+
* document), `nationality_not_allowed` and `underage` (doc_ocr or
|
|
58
|
+
* population_registry; terminal), and `age_unverifiable` (the app sets a
|
|
59
|
+
* minimum age but the birth date could not be read — doc_ocr: retryable with
|
|
60
|
+
* a clearer photo; population_registry: terminal).
|
|
61
|
+
* @public
|
|
62
|
+
*/
|
|
63
|
+
type EligibilityReason = "document_type_not_accepted" | "nationality_not_allowed" | "underage" | "age_unverifiable";
|
|
64
|
+
/**
|
|
65
|
+
* Why a profile-v2 policy ended a session: a session-level
|
|
66
|
+
* {@link SessionFailureReason} (location / anonymizer gate), or the failed
|
|
67
|
+
* check's policy reason — an {@link EligibilityReason} or
|
|
68
|
+
* `document_nni_mismatch` (the document belongs to someone other than the
|
|
69
|
+
* NNI the session was created for).
|
|
70
|
+
* @public
|
|
71
|
+
*/
|
|
72
|
+
type PolicyFailureReason = SessionFailureReason | EligibilityReason | "document_nni_mismatch";
|
|
73
|
+
/**
|
|
74
|
+
* Profile-v2 matching reasons a check's {@link SessionStep.reason} may carry
|
|
75
|
+
* when the data you sent in {@link CreateSessionInput.subject} differs from the
|
|
76
|
+
* reference identity: `name_mismatch`, `birth_date_mismatch`,
|
|
77
|
+
* `nationality_mismatch` (doc_ocr or population_registry) and
|
|
78
|
+
* `document_number_mismatch` (doc_ocr). All are final.
|
|
79
|
+
* @public
|
|
80
|
+
*/
|
|
81
|
+
type MatchReason = "name_mismatch" | "birth_date_mismatch" | "nationality_mismatch" | "document_number_mismatch";
|
|
21
82
|
/** Hosted-flow languages. @public */
|
|
22
83
|
type Locale = "ar" | "fr" | "en";
|
|
23
84
|
/** The environment a webhook was emitted from. @public */
|
|
@@ -34,9 +95,11 @@ interface SessionStep {
|
|
|
34
95
|
reason?: string;
|
|
35
96
|
/** Calibrated model score in [0, 1] for scored checks (liveness, face match). */
|
|
36
97
|
calibratedScore?: number;
|
|
98
|
+
/** The check failed after using all of its attempts. */
|
|
99
|
+
attemptsExhausted?: boolean;
|
|
37
100
|
}
|
|
38
101
|
/**
|
|
39
|
-
* Out-of-band delivery of the session's hosted link, sent by Sekyro after the
|
|
102
|
+
* Out-of-band delivery of the session's hosted link, sent by Sekyro AI after the
|
|
40
103
|
* session is created. Best effort: a failed send never fails the create.
|
|
41
104
|
* @public
|
|
42
105
|
*/
|
|
@@ -46,6 +109,148 @@ interface DeliverOptions {
|
|
|
46
109
|
/** E.164 phone number of the recipient, e.g. `+22236123456`. */
|
|
47
110
|
to: string;
|
|
48
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* What you already know about the person (`subject` at session create). A
|
|
114
|
+
* closed object: unknown keys are refused (`400`). Every field is optional;
|
|
115
|
+
* `null` or blank counts as absent. Identity fields are compared with the
|
|
116
|
+
* person's document or registry record when the app's profile turns name
|
|
117
|
+
* matching on; `nni` binds the session to that identity.
|
|
118
|
+
* @public
|
|
119
|
+
*/
|
|
120
|
+
interface SessionSubjectInput {
|
|
121
|
+
/** 10-digit Mauritanian NNI, as a string. */
|
|
122
|
+
nni?: string;
|
|
123
|
+
/** E.164 phone number, e.g. `+22236123456`. */
|
|
124
|
+
phone?: string;
|
|
125
|
+
fullName?: string;
|
|
126
|
+
/** ISO 8601 date (`YYYY-MM-DD`). */
|
|
127
|
+
birthDate?: string;
|
|
128
|
+
/** ISO 3166-1 alpha-2, e.g. `MR`. */
|
|
129
|
+
nationality?: string;
|
|
130
|
+
/** Identity-document number (1–40 characters). */
|
|
131
|
+
documentNumber?: string;
|
|
132
|
+
/**
|
|
133
|
+
* Your own id for this person (1–128 characters). Echoed on the session and
|
|
134
|
+
* its webhooks, and searchable on the subjects API.
|
|
135
|
+
*/
|
|
136
|
+
externalRef?: string;
|
|
137
|
+
}
|
|
138
|
+
/** A document type the backend reads (kyc-docs-v2 vocabulary). @public */
|
|
139
|
+
type ProfileDocumentType = "carte_identite" | "passport";
|
|
140
|
+
/**
|
|
141
|
+
* The settings of an app's eKYC profile that a session may override — a
|
|
142
|
+
* mirror of the backend profile (schema version 2) without `schemaVersion`,
|
|
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}.
|
|
146
|
+
* @public
|
|
147
|
+
*/
|
|
148
|
+
interface EkycProfileSettings {
|
|
149
|
+
/** Phone OTP step: off, or on with where the number comes from. */
|
|
150
|
+
phone: "off" | {
|
|
151
|
+
numberSource: "prefilled" | "user_entered" | "prefilled_or_entered";
|
|
152
|
+
};
|
|
153
|
+
document: {
|
|
154
|
+
mode: "off" | "optional" | "mandatory";
|
|
155
|
+
/** Accepted document types: `'*'` (all) or a list, optionally per issuing country. */
|
|
156
|
+
accepted: {
|
|
157
|
+
default: "*" | ProfileDocumentType[];
|
|
158
|
+
byIssuer?: Record<string, ProfileDocumentType[]>;
|
|
159
|
+
};
|
|
160
|
+
/** Expired documents: refused, allowed, or allowed for `graceDays` (1–365) after expiry. */
|
|
161
|
+
expired: "reject" | "allow" | {
|
|
162
|
+
graceDays: number;
|
|
163
|
+
};
|
|
164
|
+
authenticity: "standard" | "off";
|
|
165
|
+
};
|
|
166
|
+
registry: {
|
|
167
|
+
enabled: boolean;
|
|
168
|
+
sources: Array<"MR.anrpts">;
|
|
169
|
+
/** Which identity is the reference for face match and your data. */
|
|
170
|
+
reference?: "document" | "registry";
|
|
171
|
+
/** What happens when the registry has no record for the NNI. */
|
|
172
|
+
onNoRecord?: "fail" | "use_document";
|
|
173
|
+
};
|
|
174
|
+
liveness: {
|
|
175
|
+
enabled: boolean;
|
|
176
|
+
};
|
|
177
|
+
faceMatch: {
|
|
178
|
+
enabled: boolean;
|
|
179
|
+
};
|
|
180
|
+
/** Comparison of your `subject` data with the reference identity. */
|
|
181
|
+
nameMatch?: {
|
|
182
|
+
level: "strict" | "standard" | "lenient";
|
|
183
|
+
onMismatch: "fail" | "signal";
|
|
184
|
+
};
|
|
185
|
+
/** Per-step attempt limits. */
|
|
186
|
+
attempts?: {
|
|
187
|
+
phone: number;
|
|
188
|
+
document: number;
|
|
189
|
+
registry: number;
|
|
190
|
+
liveness: number;
|
|
191
|
+
faceMatch: number;
|
|
192
|
+
};
|
|
193
|
+
/** Where the end user may be (IP location). */
|
|
194
|
+
locations: {
|
|
195
|
+
mode: "all";
|
|
196
|
+
} | {
|
|
197
|
+
mode: "only" | "all_except";
|
|
198
|
+
countries: string[];
|
|
199
|
+
};
|
|
200
|
+
anonymizers: "allow" | "block";
|
|
201
|
+
/** Accepted nationalities: `'*'` or a list, optionally per IP location. */
|
|
202
|
+
nationalities: {
|
|
203
|
+
default: "*" | string[];
|
|
204
|
+
byLocation?: Record<string, "*" | string[]>;
|
|
205
|
+
};
|
|
206
|
+
/** Minimum age in years (1–120), or `null` for none. */
|
|
207
|
+
minAge: number | null;
|
|
208
|
+
/** Automatic decisions instead of human review (`retryConfidentRejects` lets confident rejects retry). */
|
|
209
|
+
decisions?: {
|
|
210
|
+
mode: "automatic" | "review";
|
|
211
|
+
retryConfidentRejects: boolean;
|
|
212
|
+
};
|
|
213
|
+
/** Device cooldown after repeated rejections (at most 5 tiers; `[]` = off). */
|
|
214
|
+
cooldown?: {
|
|
215
|
+
tiers: Array<{
|
|
216
|
+
rejectedSessions: number;
|
|
217
|
+
windowHours: number;
|
|
218
|
+
waitMinutes: number;
|
|
219
|
+
}>;
|
|
220
|
+
};
|
|
221
|
+
/** Device tamper and velocity actions. */
|
|
222
|
+
device?: {
|
|
223
|
+
tamper: "block" | "signal";
|
|
224
|
+
velocity: {
|
|
225
|
+
maxIdentitiesPerDevice: number;
|
|
226
|
+
windowDays: number;
|
|
227
|
+
action: "signal" | "block";
|
|
228
|
+
};
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* `T` with every property optional, recursively. Arrays are replaced as a
|
|
233
|
+
* whole, never merged element by element.
|
|
234
|
+
* @public
|
|
235
|
+
*/
|
|
236
|
+
type DeepPartial<T> = T extends readonly unknown[] ? T : T extends object ? {
|
|
237
|
+
[K in keyof T]?: DeepPartial<T[K]>;
|
|
238
|
+
} : T;
|
|
239
|
+
/**
|
|
240
|
+
* A per-session override of the app's eKYC profile
|
|
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.
|
|
244
|
+
*
|
|
245
|
+
* The API validates the merged result like a profile save. Unknown keys are
|
|
246
|
+
* rejected server-side (`400`, also for keys this SDK version does not type).
|
|
247
|
+
* An override may only make the profile stricter unless the app allows
|
|
248
|
+
* widening (`overrides.allowWidening`); otherwise a widening change answers
|
|
249
|
+
* `403 override_widens_profile`. The changed paths are reported on
|
|
250
|
+
* {@link Session.overriddenFields}.
|
|
251
|
+
* @public
|
|
252
|
+
*/
|
|
253
|
+
type EkycProfileOverride = DeepPartial<EkycProfileSettings>;
|
|
49
254
|
/**
|
|
50
255
|
* Input of {@link SessionsApi.create}. There is no recipe field: the API key
|
|
51
256
|
* belongs to an app, and that app's eKYC profile decides the steps.
|
|
@@ -54,6 +259,11 @@ interface DeliverOptions {
|
|
|
54
259
|
interface CreateSessionInput {
|
|
55
260
|
/** Pins the hosted-flow language. Omit to let the person's device decide. */
|
|
56
261
|
locale?: Locale;
|
|
262
|
+
/**
|
|
263
|
+
* Pre-choose the identity method when the app's document step is optional
|
|
264
|
+
* (the hosted method screen is then skipped). Ignored for other apps.
|
|
265
|
+
*/
|
|
266
|
+
identityMethod?: IdentityMethod;
|
|
57
267
|
/**
|
|
58
268
|
* Session lifetime in minutes. Must fall within the app profile's link
|
|
59
269
|
* range, otherwise the API answers `400 ttl_out_of_policy`. Omit to use the
|
|
@@ -62,6 +272,19 @@ interface CreateSessionInput {
|
|
|
62
272
|
ttlMinutes?: number;
|
|
63
273
|
/** Also send the hosted link to the person by SMS or WhatsApp. */
|
|
64
274
|
deliver?: DeliverOptions;
|
|
275
|
+
/**
|
|
276
|
+
* What you already know about the person (preferred over `input` for
|
|
277
|
+
* identity data). A key sent in both `subject` and `input` with different
|
|
278
|
+
* values answers `400 subject_input_conflict`.
|
|
279
|
+
*/
|
|
280
|
+
subject?: SessionSubjectInput;
|
|
281
|
+
/**
|
|
282
|
+
* Override the app's eKYC profile for this session only (profile v2): a
|
|
283
|
+
* deep-partial {@link EkycProfileOverride}. Unknown keys are rejected
|
|
284
|
+
* server-side; a change that makes the profile less strict answers
|
|
285
|
+
* `403 override_widens_profile` unless the app allows widening.
|
|
286
|
+
*/
|
|
287
|
+
profile?: EkycProfileOverride;
|
|
65
288
|
/**
|
|
66
289
|
* Step inputs consumed server-side. The known anchors are typed (all
|
|
67
290
|
* strings — an `nni` is a 10-digit string, never a number); further keys
|
|
@@ -102,6 +325,63 @@ interface CreatedSession {
|
|
|
102
325
|
/** ISO 8601 — when the session (and its link) stop accepting input. */
|
|
103
326
|
expiresAt: string;
|
|
104
327
|
}
|
|
328
|
+
/**
|
|
329
|
+
* The end user's network at the start of the session (IP-derived, approximate).
|
|
330
|
+
* @public
|
|
331
|
+
*/
|
|
332
|
+
interface SessionNetworkEvent {
|
|
333
|
+
/** ISO 8601. */
|
|
334
|
+
at: string;
|
|
335
|
+
/** ISO 3166-1 alpha-2. */
|
|
336
|
+
country?: string;
|
|
337
|
+
region?: string;
|
|
338
|
+
city?: string;
|
|
339
|
+
asn?: number;
|
|
340
|
+
operator?: string;
|
|
341
|
+
connectionType: "mobile" | "hosting" | "unknown";
|
|
342
|
+
anonymizer: {
|
|
343
|
+
vpn: boolean;
|
|
344
|
+
tor: boolean;
|
|
345
|
+
hosting: boolean;
|
|
346
|
+
};
|
|
347
|
+
/** IANA time zone reported by the end user's device. */
|
|
348
|
+
browserTimezone?: string;
|
|
349
|
+
/** True when the device time zone does not belong to the IP country. */
|
|
350
|
+
timezoneMismatch?: boolean;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* End-user network context; absent when not recorded.
|
|
354
|
+
* @public
|
|
355
|
+
*/
|
|
356
|
+
interface SessionNetwork {
|
|
357
|
+
/** The start event's IP address. Never sent in webhooks. */
|
|
358
|
+
ip?: string;
|
|
359
|
+
/** True when a later call came from a different country than the start. */
|
|
360
|
+
countryChanged: boolean;
|
|
361
|
+
start: SessionNetworkEvent;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Device signals detected on the end user's device.
|
|
365
|
+
* @public
|
|
366
|
+
*/
|
|
367
|
+
type SessionDeviceSignal = "webdriver" | "headless" | "emulator" | "rooted" | "jailbroken" | "debugger" | "hooking" | "virtual_camera";
|
|
368
|
+
/**
|
|
369
|
+
* End-user device summary; absent when not recorded.
|
|
370
|
+
* @public
|
|
371
|
+
*/
|
|
372
|
+
interface SessionDevice {
|
|
373
|
+
platform: "web" | "android" | "ios";
|
|
374
|
+
sdk?: string;
|
|
375
|
+
os?: string;
|
|
376
|
+
osVersion?: string;
|
|
377
|
+
browser?: string;
|
|
378
|
+
browserVersion?: string;
|
|
379
|
+
deviceClass: "mobile" | "tablet" | "desktop" | "unknown";
|
|
380
|
+
model?: string;
|
|
381
|
+
/** Device ids hashed with a key unique to your organization. */
|
|
382
|
+
deviceKeys: string[];
|
|
383
|
+
signals: SessionDeviceSignal[];
|
|
384
|
+
}
|
|
105
385
|
/**
|
|
106
386
|
* The whitelisted session view returned by {@link SessionsApi.get}. Never
|
|
107
387
|
* contains the client token.
|
|
@@ -116,6 +396,37 @@ interface Session {
|
|
|
116
396
|
expiresAt: string;
|
|
117
397
|
/** ISO 8601. */
|
|
118
398
|
createdAt: string;
|
|
399
|
+
/** End-user network context; absent when not recorded. */
|
|
400
|
+
network?: SessionNetwork;
|
|
401
|
+
/** End-user device; absent when not recorded. */
|
|
402
|
+
device?: SessionDevice;
|
|
403
|
+
/**
|
|
404
|
+
* Set when a profile-v2 policy ended the session: a session-level gate
|
|
405
|
+
* (location, anonymizer) or a failed check's policy reason (eligibility,
|
|
406
|
+
* `document_nni_mismatch`). Absent otherwise.
|
|
407
|
+
*/
|
|
408
|
+
failureReason?: PolicyFailureReason;
|
|
409
|
+
/** The subject (person) this session is linked to, once an identifier is known. */
|
|
410
|
+
subjectId?: string;
|
|
411
|
+
/** Your own id for the person, from `subject.externalRef` at create. */
|
|
412
|
+
externalRef?: string;
|
|
413
|
+
/**
|
|
414
|
+
* `true` when an identifier this session read already belongs to a
|
|
415
|
+
* different subject than `subjectId` — the subjects are never merged.
|
|
416
|
+
*/
|
|
417
|
+
subjectConflict?: boolean;
|
|
418
|
+
/**
|
|
419
|
+
* ISO 8601 — when the end user's device may verify again; set with
|
|
420
|
+
* `failureReason: 'device_cooldown'`.
|
|
421
|
+
*/
|
|
422
|
+
retryAfter?: string;
|
|
423
|
+
/** Dotted profile paths this session's {@link CreateSessionInput.profile} changed (e.g. `decisions.mode`). */
|
|
424
|
+
overriddenFields?: string[];
|
|
425
|
+
/**
|
|
426
|
+
* Risk signals recorded on the session (e.g. `device_velocity`,
|
|
427
|
+
* `timezone_mismatch`) — signals only, never a verdict by themselves.
|
|
428
|
+
*/
|
|
429
|
+
riskSignals?: string[];
|
|
119
430
|
}
|
|
120
431
|
/**
|
|
121
432
|
* `data` of the terminal / review-pending session lifecycle events
|
|
@@ -133,6 +444,54 @@ interface SessionLifecycleEventData {
|
|
|
133
444
|
steps?: Array<Pick<SessionStep, "checkType" | "state">>;
|
|
134
445
|
/** Machine-readable reason, when the transition has one. */
|
|
135
446
|
reason?: string;
|
|
447
|
+
/** End-user network context (no IP); on `completed` / `failed` when recorded. */
|
|
448
|
+
network?: Omit<SessionNetwork, "ip">;
|
|
449
|
+
/** End-user device; on `completed` / `failed` when recorded. */
|
|
450
|
+
device?: SessionDevice;
|
|
451
|
+
/**
|
|
452
|
+
* On `session.failed`: set when a profile-v2 policy ended the session — a
|
|
453
|
+
* session-level gate (location, anonymizer) or a failed check's policy
|
|
454
|
+
* reason (eligibility, `document_nni_mismatch`).
|
|
455
|
+
*/
|
|
456
|
+
failureReason?: PolicyFailureReason;
|
|
457
|
+
/** The subject (person) the session is linked to, when known. */
|
|
458
|
+
subjectId?: string;
|
|
459
|
+
/** Your own id for the person, from `subject.externalRef` at create. */
|
|
460
|
+
externalRef?: string;
|
|
461
|
+
/**
|
|
462
|
+
* `true` when an identifier this session read already belongs to a
|
|
463
|
+
* different subject than `subjectId` — the subjects are never merged.
|
|
464
|
+
*/
|
|
465
|
+
subjectConflict?: boolean;
|
|
466
|
+
/**
|
|
467
|
+
* On `session.failed` with `failureReason: 'device_cooldown'`: ISO time
|
|
468
|
+
* from which the device may start a new verification.
|
|
469
|
+
*/
|
|
470
|
+
retryAfter?: string;
|
|
471
|
+
/** Dotted profile paths the session's create-time override changed. */
|
|
472
|
+
overriddenFields?: string[];
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* `data` of `subject.updated` — a session linked to the subject reached a
|
|
476
|
+
* terminal state. Ids and enums only.
|
|
477
|
+
* @public
|
|
478
|
+
*/
|
|
479
|
+
interface SubjectUpdatedEventData {
|
|
480
|
+
subjectId: string;
|
|
481
|
+
sessionId: string;
|
|
482
|
+
status: SessionStatus;
|
|
483
|
+
outcome: SessionOutcome | null;
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* `data` of `subject.suspicious_activity` — a device already linked to
|
|
487
|
+
* ANOTHER subject was used for a session of this subject. `count` is the
|
|
488
|
+
* subject's running total of such events. Ids only.
|
|
489
|
+
* @public
|
|
490
|
+
*/
|
|
491
|
+
interface SubjectSuspiciousActivityEventData {
|
|
492
|
+
subjectId: string;
|
|
493
|
+
sessionId: string;
|
|
494
|
+
count: number;
|
|
136
495
|
}
|
|
137
496
|
/**
|
|
138
497
|
* `data` of `session.step.completed` — the check that just passed.
|
|
@@ -142,6 +501,15 @@ interface SessionStepCompletedEventData {
|
|
|
142
501
|
sessionId: string;
|
|
143
502
|
checkType: CheckType;
|
|
144
503
|
state: CheckState;
|
|
504
|
+
/** The subject (person) the session is linked to, when known. */
|
|
505
|
+
subjectId?: string;
|
|
506
|
+
/** Your own id for the person, from `subject.externalRef` at create. */
|
|
507
|
+
externalRef?: string;
|
|
508
|
+
/**
|
|
509
|
+
* `true` when an identifier this session read already belongs to a
|
|
510
|
+
* different subject than `subjectId` — the subjects are never merged.
|
|
511
|
+
*/
|
|
512
|
+
subjectConflict?: boolean;
|
|
145
513
|
}
|
|
146
514
|
/**
|
|
147
515
|
* `data` of `session.review_decided` — a human (or the review-timeout sweep)
|
|
@@ -154,6 +522,15 @@ interface SessionReviewDecidedEventData {
|
|
|
154
522
|
sessionId: string;
|
|
155
523
|
outcome: "pass" | "fail";
|
|
156
524
|
reason: string;
|
|
525
|
+
/** The subject (person) the session is linked to, when known. */
|
|
526
|
+
subjectId?: string;
|
|
527
|
+
/** Your own id for the person, from `subject.externalRef` at create. */
|
|
528
|
+
externalRef?: string;
|
|
529
|
+
/**
|
|
530
|
+
* `true` when an identifier this session read already belongs to a
|
|
531
|
+
* different subject than `subjectId` — the subjects are never merged.
|
|
532
|
+
*/
|
|
533
|
+
subjectConflict?: boolean;
|
|
157
534
|
}
|
|
158
535
|
/**
|
|
159
536
|
* Event type → the shape of its `data`. Session events are typed; the
|
|
@@ -171,6 +548,8 @@ interface WebhookEventDataMap {
|
|
|
171
548
|
"session.expired": SessionLifecycleEventData;
|
|
172
549
|
"session.failed": SessionLifecycleEventData;
|
|
173
550
|
"subject.enrolled": Record<string, unknown>;
|
|
551
|
+
"subject.updated": SubjectUpdatedEventData;
|
|
552
|
+
"subject.suspicious_activity": SubjectSuspiciousActivityEventData;
|
|
174
553
|
"subject.deleted": Record<string, unknown>;
|
|
175
554
|
"aml.match_flagged": Record<string, unknown>;
|
|
176
555
|
"payment.received": Record<string, unknown>;
|
|
@@ -266,11 +645,18 @@ declare class SessionsApi {
|
|
|
266
645
|
* cannot create a second session.
|
|
267
646
|
*/
|
|
268
647
|
create(input?: CreateSessionInput, opts?: RequestOptions): Promise<CreatedSession>;
|
|
648
|
+
/**
|
|
649
|
+
* `POST /sessions/:id/method` — choose the identity method of an
|
|
650
|
+
* optional-document session on the person's behalf (the hosted method
|
|
651
|
+
* screen is then skipped). `409 method_locked` once the choice can no
|
|
652
|
+
* longer change; `409 session_not_active` on a finished or expired session.
|
|
653
|
+
*/
|
|
654
|
+
selectMethod(id: string, method: IdentityMethod): Promise<Session>;
|
|
269
655
|
/** `GET /sessions/:id` — the whitelisted view (no client token). */
|
|
270
656
|
get(id: string): Promise<Session>;
|
|
271
657
|
}
|
|
272
658
|
/**
|
|
273
|
-
* Sekyro partner API client. Server-side only: it carries your API key.
|
|
659
|
+
* Sekyro AI partner API client. Server-side only: it carries your API key.
|
|
274
660
|
*
|
|
275
661
|
* Throws {@link SekyroConfigError} synchronously when `apiKey` is missing or
|
|
276
662
|
* `baseUrl` is not `https:` (plain `http:` is accepted for `localhost`,
|
|
@@ -292,7 +678,7 @@ declare class Sekyro {
|
|
|
292
678
|
type SekyroWebhookErrorCode = "invalid_signature" | "stale" | "malformed";
|
|
293
679
|
/**
|
|
294
680
|
* Thrown by {@link verifyWebhook}. Respond with a 4xx and do not process the
|
|
295
|
-
* body; Sekyro retries deliveries that do not receive a 2xx.
|
|
681
|
+
* body; Sekyro AI retries deliveries that do not receive a 2xx.
|
|
296
682
|
* @public
|
|
297
683
|
*/
|
|
298
684
|
declare class SekyroWebhookError extends Error {
|
|
@@ -352,7 +738,7 @@ declare class SekyroApiError extends Error {
|
|
|
352
738
|
*/
|
|
353
739
|
declare const SEKYRO_SIGNATURE_HEADER = "x-sekyro-signature";
|
|
354
740
|
/**
|
|
355
|
-
* The pre-rebrand name of the signature header. Sekyro sends BOTH headers with
|
|
741
|
+
* The pre-rebrand name of the signature header. Sekyro AI sends BOTH headers with
|
|
356
742
|
* the same value during the transition; prefer {@link SEKYRO_SIGNATURE_HEADER}
|
|
357
743
|
* and use {@link signatureFromHeaders} to accept either.
|
|
358
744
|
* @public
|
|
@@ -380,13 +766,13 @@ interface VerifyWebhookOptions {
|
|
|
380
766
|
now?: () => number;
|
|
381
767
|
}
|
|
382
768
|
/**
|
|
383
|
-
* Verify a Sekyro webhook delivery and return its parsed envelope, discriminated
|
|
769
|
+
* Verify a Sekyro AI webhook delivery and return its parsed envelope, discriminated
|
|
384
770
|
* on `event` (narrow with a `switch` to type `data`).
|
|
385
771
|
*
|
|
386
772
|
* - `rawBody` MUST be the request body exactly as received (before any JSON
|
|
387
773
|
* parsing / re-serialisation); the signature covers those bytes.
|
|
388
774
|
* - Accepts the delivery when ANY `v1` in the header matches, which is what
|
|
389
|
-
* makes secret rotation seamless (Sekyro signs with current + previous).
|
|
775
|
+
* makes secret rotation seamless (Sekyro AI signs with current + previous).
|
|
390
776
|
* - Uses `node:crypto` only; the digest compare is constant-time.
|
|
391
777
|
*
|
|
392
778
|
* Checks run in this order: header/secret present → header well-formed →
|
|
@@ -401,4 +787,4 @@ interface VerifyWebhookOptions {
|
|
|
401
787
|
*/
|
|
402
788
|
declare function verifyWebhook(rawBody: string, header: string | null | undefined, secret: string, opts?: VerifyWebhookOptions): WebhookEnvelope;
|
|
403
789
|
|
|
404
|
-
export { type CheckState, type CheckType, type CreateSessionInput, type CreatedSession, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type DeliverOptions, type FetchLike, LEGACY_SIGNATURE_HEADER, type Locale, type RequestOptions, SEKYRO_SIGNATURE_HEADER, Sekyro, SekyroApiError, type SekyroApiErrorInit, type SekyroClientErrorCode, SekyroConfigError, type SekyroConfigErrorCode, type SekyroEnvironment, type SekyroOptions, SekyroWebhookError, type SekyroWebhookErrorCode, type Session, type SessionEventData, type SessionLifecycleEventData, type SessionOutcome, type SessionReviewDecidedEventData, type SessionStatus, type SessionStep, type SessionStepCompletedEventData, SessionsApi, type VerifyWebhookOptions, type WebhookEnvelope, type WebhookEnvelopeOf, type WebhookEventDataMap, type WebhookEventType, signatureFromHeaders, verifyWebhook };
|
|
790
|
+
export { type CheckState, type CheckType, type CreateSessionInput, type CreatedSession, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type DecisionReason, type DeepPartial, type DeliverOptions, type EkycProfileOverride, type EkycProfileSettings, type EligibilityReason, type FetchLike, type IdentityMethod, LEGACY_SIGNATURE_HEADER, type Locale, type MatchReason, type PolicyFailureReason, type ProfileDocumentType, type RequestOptions, SEKYRO_SIGNATURE_HEADER, Sekyro, SekyroApiError, type SekyroApiErrorInit, type SekyroClientErrorCode, SekyroConfigError, type SekyroConfigErrorCode, type SekyroEnvironment, type SekyroOptions, SekyroWebhookError, type SekyroWebhookErrorCode, type Session, type SessionDevice, type SessionDeviceSignal, type SessionEventData, type SessionFailureReason, type SessionLifecycleEventData, type SessionNetwork, type SessionNetworkEvent, type SessionOutcome, type SessionReviewDecidedEventData, type SessionStatus, type SessionStep, type SessionStepCompletedEventData, type SessionSubjectInput, SessionsApi, type SubjectSuspiciousActivityEventData, type SubjectUpdatedEventData, type VerifyWebhookOptions, type WebhookEnvelope, type WebhookEnvelopeOf, type WebhookEventDataMap, type WebhookEventType, signatureFromHeaders, verifyWebhook };
|