@flonkid/kyc 1.8.2 → 1.9.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/dist/server.d.cts CHANGED
@@ -1,3 +1,865 @@
1
+ interface components {
2
+ schemas: {
3
+ CreateSessionRequestDto: {
4
+ /**
5
+ * @description Client identifier for session association (optional)
6
+ * @example client-12345
7
+ */
8
+ clientId?: string;
9
+ /**
10
+ * @description Client metadata for identification (optional) - arbitrary object with client identifiers
11
+ * @example {
12
+ * "email": "user@example.com",
13
+ * "userId": "12345",
14
+ * "customId": "internal-id"
15
+ * }
16
+ */
17
+ clientMetadata?: Record<string, never>;
18
+ /**
19
+ * @description Document type for verification (required)
20
+ * @example id_card
21
+ * @enum {string}
22
+ */
23
+ documentType: "passport" | "id_card" | "driver_license";
24
+ /**
25
+ * @description Session lifetime in seconds (optional, default: 300)
26
+ * @default 300
27
+ * @example 300
28
+ */
29
+ expiresIn: number;
30
+ };
31
+ SessionResponseDto: {
32
+ /**
33
+ * @description Unique session identifier
34
+ * @example clx1234567890abcdef
35
+ */
36
+ id: string;
37
+ /**
38
+ * @description Session status
39
+ * @example pending
40
+ * @enum {string}
41
+ */
42
+ status: "pending" | "in_progress" | "completed" | "failed" | "expired";
43
+ /**
44
+ * Format: date-time
45
+ * @description Session expiration timestamp
46
+ * @example 2024-10-25T14:30:00.000Z
47
+ */
48
+ expiresAt: string;
49
+ /**
50
+ * @description Client metadata
51
+ * @example {
52
+ * "userId": "user_12345",
53
+ * "email": "john.doe@example.com"
54
+ * }
55
+ */
56
+ clientMetadata?: Record<string, never>;
57
+ /**
58
+ * @description Widget URL for embedding
59
+ * @example https://widget.flonk.id/?sessionId=clx1234567890abcdef&mode=embedded
60
+ */
61
+ widgetUrl: string;
62
+ /**
63
+ * @description QR code data for mobile verification
64
+ * @example https://widget.flonk.id/verify/clx1234567890abcdef?token=kyc_1234567890_abc123
65
+ */
66
+ qrCodeUrl: string;
67
+ /**
68
+ * Format: date-time
69
+ * @description Session creation timestamp
70
+ * @example 2024-10-25T14:25:00.000Z
71
+ */
72
+ createdAt: string;
73
+ /**
74
+ * @description Project identifier
75
+ * @example clxproject123
76
+ */
77
+ projectId: string;
78
+ /**
79
+ * @description Whether manual upload is allowed for this session
80
+ * @example true
81
+ */
82
+ allowManualUpload: boolean;
83
+ /**
84
+ * @description Embed token for widget authentication (like Stripe client_secret)
85
+ * @example eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
86
+ */
87
+ embedToken?: string;
88
+ /**
89
+ * @description Indicates if an existing session was reused instead of creating a new one
90
+ * @example false
91
+ */
92
+ reused?: boolean;
93
+ /**
94
+ * @description Test mode flag - true if created with test keys (sk_test_*)
95
+ * @example false
96
+ */
97
+ testMode?: boolean;
98
+ };
99
+ UploadDocumentImageDto: {
100
+ /**
101
+ * @description KYC Session ID
102
+ * @example cm5abc123def456
103
+ */
104
+ sessionId: string;
105
+ /**
106
+ * @description Image side/type
107
+ * @example front
108
+ * @enum {string}
109
+ */
110
+ imageType: "front" | "back" | "main";
111
+ /**
112
+ * @description Whether this is a retake photo (replaces existing photo)
113
+ * @default false
114
+ * @example false
115
+ */
116
+ isRetake: boolean;
117
+ /**
118
+ * Format: binary
119
+ * @description Single document image
120
+ */
121
+ images: string;
122
+ };
123
+ DocumentUploadResponseDto: {
124
+ /** @example true */
125
+ success: boolean;
126
+ /**
127
+ * @description Processing status: queued, processing, completed
128
+ * @example queued
129
+ */
130
+ status: string;
131
+ /**
132
+ * @description Job ID for tracking
133
+ * @example doc:session123:front:1234567890
134
+ */
135
+ jobId?: string;
136
+ /** @example passport */
137
+ detectedDocumentType: string;
138
+ /** @example 0.9 */
139
+ detectionConfidence: number;
140
+ /** @example front */
141
+ uploadedImageType: string;
142
+ /** @example front */
143
+ detectedSide?: string;
144
+ /** @example German ID Card */
145
+ documentName?: string;
146
+ /** @example true */
147
+ isValidDocument: boolean;
148
+ /** @example false */
149
+ requiresBackSide: boolean;
150
+ /** @example Please upload the back side of your ID card */
151
+ nextStepMessage: string;
152
+ /**
153
+ * @example {
154
+ * "front": true,
155
+ * "back": false
156
+ * }
157
+ */
158
+ uploadedSides: Record<string, never>;
159
+ /** @example false */
160
+ readyForVerification: boolean;
161
+ /** @example Image uploaded successfully. Processing in background. */
162
+ message?: string;
163
+ /**
164
+ * @description Estimated processing time in milliseconds
165
+ * @example 3000
166
+ */
167
+ estimatedProcessingTime?: number;
168
+ };
169
+ UploadFaceImageDto: {
170
+ /**
171
+ * @description KYC Session ID
172
+ * @example cm5abc123def456
173
+ */
174
+ sessionId: string;
175
+ /**
176
+ * Format: binary
177
+ * @description Face image for biometric verification
178
+ */
179
+ images: string;
180
+ };
181
+ FaceUploadResponseDto: {
182
+ /** @example true */
183
+ success: boolean;
184
+ /**
185
+ * @description Processing status: queued, processing, completed
186
+ * @example queued
187
+ */
188
+ status: string;
189
+ /**
190
+ * @description Job ID for tracking
191
+ * @example face:session123:1234567890
192
+ */
193
+ jobId?: string;
194
+ /** @example 0.85 */
195
+ confidence: number;
196
+ /** @example Face image uploaded. Processing liveness in background. */
197
+ message: string;
198
+ /** @example true */
199
+ readyForFinalVerification: boolean;
200
+ /**
201
+ * @description Estimated processing time in milliseconds
202
+ * @example 2000
203
+ */
204
+ estimatedProcessingTime?: number;
205
+ };
206
+ UploadPoaImageDto: {
207
+ /**
208
+ * @description KYC Session ID
209
+ * @example cm5abc123def456
210
+ */
211
+ sessionId: string;
212
+ /**
213
+ * Format: binary
214
+ * @description Proof of Address document (utility bill, bank statement, etc.). Supports JPEG, PNG, WebP, and PDF.
215
+ */
216
+ images: string;
217
+ /** @description Custom extraction prompt (overrides default) */
218
+ prompt?: string;
219
+ };
220
+ PoaExtractedDataDto: {
221
+ /** @example John Doe */
222
+ fullName?: string;
223
+ /** @example 123 Main Street */
224
+ address?: string;
225
+ /** @example Berlin */
226
+ city?: string;
227
+ /** @example 10115 */
228
+ postalCode?: string;
229
+ /** @example Germany */
230
+ country?: string;
231
+ /** @example utility_bill */
232
+ documentType?: string;
233
+ /** @example 2025-01-15 */
234
+ issueDate?: string;
235
+ /** @example Berlin Electricity GmbH */
236
+ issuer?: string;
237
+ };
238
+ PoaConfidenceBreakdownDto: {
239
+ /**
240
+ * @example {
241
+ * "full_name": 1,
242
+ * "address": 1,
243
+ * "city": 0
244
+ * }
245
+ */
246
+ fieldScores: Record<string, never>;
247
+ /** @example 1 */
248
+ totalWeight: number;
249
+ /** @example 0.75 */
250
+ achievedWeight: number;
251
+ /** @example 0.75 */
252
+ confidenceScore: number;
253
+ };
254
+ PoaUploadResponseDto: {
255
+ /** @example true */
256
+ success: boolean;
257
+ /** @example Proof of address uploaded and processed successfully */
258
+ message: string;
259
+ data?: components["schemas"]["PoaExtractedDataDto"];
260
+ /**
261
+ * @description Processing time in milliseconds
262
+ * @example 5000
263
+ */
264
+ processingTimeMs?: number;
265
+ /**
266
+ * @description Whether session is ready for final verification
267
+ * @example true
268
+ */
269
+ readyForVerification: boolean;
270
+ /**
271
+ * @description Confidence score from 0.0 to 1.0
272
+ * @example 0.85
273
+ */
274
+ confidenceScore?: number;
275
+ confidenceBreakdown?: components["schemas"]["PoaConfidenceBreakdownDto"];
276
+ /**
277
+ * @description PoA verification status based on confidence thresholds
278
+ * @example auto_approved
279
+ * @enum {string}
280
+ */
281
+ poaStatus?: "pending" | "auto_approved" | "manual_review" | "approved" | "rejected";
282
+ };
283
+ PoaAsyncResponseDto: {
284
+ /** @example true */
285
+ success: boolean;
286
+ /** @example f47ac10b-58cc-4372-a567-0e02b2c3d479 */
287
+ jobId: string;
288
+ /**
289
+ * @example processing
290
+ * @enum {string}
291
+ */
292
+ status: "processing";
293
+ /** @example PoA extraction started. Poll /kyc/poa-status/:jobId for results. */
294
+ message: string;
295
+ };
296
+ PoaStatusResponseDto: {
297
+ /** @example f47ac10b-58cc-4372-a567-0e02b2c3d479 */
298
+ jobId: string;
299
+ /**
300
+ * @example completed
301
+ * @enum {string}
302
+ */
303
+ status: "processing" | "completed" | "failed" | "not_found";
304
+ /** @example PoA extraction completed */
305
+ message: string;
306
+ data?: components["schemas"]["PoaExtractedDataDto"];
307
+ /**
308
+ * @description Confidence score from 0.0 to 1.0
309
+ * @example 0.85
310
+ */
311
+ confidenceScore?: number;
312
+ /**
313
+ * @example auto_approved
314
+ * @enum {string}
315
+ */
316
+ poaStatus?: "pending" | "auto_approved" | "manual_review" | "approved" | "rejected";
317
+ };
318
+ ExtractedDataDto: {
319
+ /** @example John Doe */
320
+ fullName: string;
321
+ /** @example John */
322
+ firstName: string;
323
+ /** @example Doe */
324
+ lastName: string;
325
+ /** @example 1990-01-01 */
326
+ dateOfBirth: string;
327
+ /** @example German */
328
+ nationality: string;
329
+ /** @example M */
330
+ sex: string;
331
+ };
332
+ VerificationDataDto: {
333
+ /** @example id_card */
334
+ documentType: string;
335
+ extractedData: components["schemas"]["ExtractedDataDto"];
336
+ /** @example atm_1a2b3c4d5e */
337
+ verificationAttemptId: string;
338
+ };
339
+ VerificationResponseDto: {
340
+ /** @example true */
341
+ success: boolean;
342
+ /**
343
+ * @description Processing status: queued, processing, completed, failed
344
+ * @example queued
345
+ */
346
+ status?: string;
347
+ /**
348
+ * @description Job ID for tracking
349
+ * @example verify:session123:1234567890
350
+ */
351
+ jobId?: string;
352
+ /** @example Verification started. You will receive results shortly. */
353
+ message?: string;
354
+ /** @example client123 */
355
+ clientId?: string;
356
+ /** @example 2024-01-15T10:30:00Z */
357
+ timestamp?: string;
358
+ /** @example 0.95 */
359
+ confidence?: number;
360
+ data?: components["schemas"]["VerificationDataDto"];
361
+ /**
362
+ * @description PoA verification status: auto_approved, manual_review, rejected, pending
363
+ * @example auto_approved
364
+ */
365
+ poaStatus?: string;
366
+ };
367
+ GrantVaultConsentDto: {
368
+ /** @description KYC session id whose primary verification just completed. */
369
+ sessionId: string;
370
+ /** @description Version of consent text the user agreed to. */
371
+ consentVersion?: string;
372
+ };
373
+ GrantVaultConsentResponseDto: {
374
+ verifiedIdentityId: string;
375
+ vaultPrefix: string;
376
+ consentVersion: string;
377
+ /** Format: date-time */
378
+ consentAt: string;
379
+ };
380
+ CheckVaultDto: {
381
+ /** @description KYC session id (current new session). */
382
+ sessionId: string;
383
+ };
384
+ CheckVaultResponseDto: {
385
+ available: boolean;
386
+ /** @enum {string} */
387
+ mode?: "full_reuse" | "partial_reuse_poa";
388
+ /** Format: date-time */
389
+ completedAt?: string;
390
+ sourceProjectName?: string;
391
+ documentType?: Record<string, never>;
392
+ vaultHasPoa?: boolean;
393
+ projectRequiresPoa?: boolean;
394
+ /**
395
+ * @description Identity proof method the widget must show before applying reuse.
396
+ * @enum {string}
397
+ */
398
+ challengeMethod?: "otp" | "liveness";
399
+ };
400
+ RequestVaultOtpDto: {
401
+ /** @description Current widget session id. */
402
+ sessionId: string;
403
+ };
404
+ RequestVaultOtpResponseDto: {
405
+ /** @description Always true — the endpoint does not reveal whether the email actually matches a vault entry. */
406
+ sent: boolean;
407
+ };
408
+ VerifyVaultOtpDto: {
409
+ sessionId: string;
410
+ /** @description 6-digit numeric code received by email. */
411
+ code: string;
412
+ };
413
+ VerifyVaultOtpResponseDto: {
414
+ verified: boolean;
415
+ };
416
+ VaultIdentityChallengeDto: {
417
+ sessionId: string;
418
+ /** @description Burst of selfie frames (Beta auto-capture). 1-6 frames. */
419
+ selfiesBase64?: string[];
420
+ /** @description Legacy single-selfie path. Prefer `selfiesBase64` for Beta burst. May include a "data:image/jpeg;base64," prefix or be raw base64. */
421
+ selfieBase64?: string;
422
+ };
423
+ VaultIdentityChallengeResponseDto: {
424
+ verified: boolean;
425
+ /** @description Face-match similarity score (0..1) when computed. */
426
+ similarity?: number;
427
+ liveness?: Record<string, never>;
428
+ /** @enum {string} */
429
+ reason?: "no_email" | "no_vault" | "no_portrait" | "liveness_failed" | "face_mismatch";
430
+ };
431
+ ApplyVaultReuseDto: {
432
+ sessionId: string;
433
+ /** @enum {string} */
434
+ mode: "full_reuse" | "partial_reuse_poa";
435
+ };
436
+ ApplyVaultReuseResponseDto: {
437
+ attemptId: string;
438
+ verifiedIdentityId: string;
439
+ /** @enum {string} */
440
+ mode: "full_reuse" | "partial_reuse_poa";
441
+ };
442
+ RevokeIdentityDto: {
443
+ /** @description Email whose vault entry should be revoked. Must match a session-verified email. */
444
+ email: string;
445
+ /** @description Optional human-readable reason. */
446
+ reason?: string;
447
+ };
448
+ RevokeIdentityResponseDto: {
449
+ revoked: boolean;
450
+ /** Format: date-time */
451
+ revokedAt: string;
452
+ };
453
+ MarkAllReadDto: Record<string, never>;
454
+ SendOtpDto: Record<string, never>;
455
+ VerifyOtpDto: Record<string, never>;
456
+ ResendOtpDto: Record<string, never>;
457
+ CreateBillingProfileDto: {
458
+ /** @description Company name (required for B2B invoicing) */
459
+ companyName?: string;
460
+ /** @description VAT/Tax ID number (EU format: XX followed by numbers) */
461
+ vatNumber?: string;
462
+ /** @description Alternative tax identification */
463
+ taxId?: string;
464
+ /** @description Address line 1 */
465
+ addressLine1?: string;
466
+ /** @description Address line 2 */
467
+ addressLine2?: string;
468
+ /** @description City */
469
+ city?: string;
470
+ /** @description State/Province */
471
+ state?: string;
472
+ /** @description Postal/ZIP code */
473
+ postalCode?: string;
474
+ /** @description Country code (2-letter ISO) */
475
+ country?: string;
476
+ /** @description Contact person name */
477
+ contactName?: string;
478
+ /** @description Email for receiving invoices */
479
+ contactEmail?: string;
480
+ /** @description Contact phone number */
481
+ contactPhone?: string;
482
+ /** @description Customer reference number for invoices */
483
+ invoiceRecipientNumber?: string;
484
+ /** @description Custom notes to include on invoices */
485
+ invoiceNotes?: string;
486
+ /**
487
+ * @description Preferred currency (EUR, USD, etc.)
488
+ * @default EUR
489
+ */
490
+ preferredCurrency: string;
491
+ /**
492
+ * @description Auto-generate monthly invoices
493
+ * @default true
494
+ */
495
+ autoInvoice: boolean;
496
+ };
497
+ UpdateBillingProfileDto: {
498
+ /** @description Company name (required for B2B invoicing) */
499
+ companyName?: string;
500
+ /** @description VAT/Tax ID number (EU format: XX followed by numbers) */
501
+ vatNumber?: string;
502
+ /** @description Alternative tax identification */
503
+ taxId?: string;
504
+ /** @description Address line 1 */
505
+ addressLine1?: string;
506
+ /** @description Address line 2 */
507
+ addressLine2?: string;
508
+ /** @description City */
509
+ city?: string;
510
+ /** @description State/Province */
511
+ state?: string;
512
+ /** @description Postal/ZIP code */
513
+ postalCode?: string;
514
+ /** @description Country code (2-letter ISO) */
515
+ country?: string;
516
+ /** @description Contact person name */
517
+ contactName?: string;
518
+ /** @description Email for receiving invoices */
519
+ contactEmail?: string;
520
+ /** @description Contact phone number */
521
+ contactPhone?: string;
522
+ /** @description Customer reference number for invoices */
523
+ invoiceRecipientNumber?: string;
524
+ /** @description Custom notes to include on invoices */
525
+ invoiceNotes?: string;
526
+ /**
527
+ * @description Preferred currency (EUR, USD, etc.)
528
+ * @default EUR
529
+ */
530
+ preferredCurrency: string;
531
+ /**
532
+ * @description Auto-generate monthly invoices
533
+ * @default true
534
+ */
535
+ autoInvoice: boolean;
536
+ };
537
+ ValidateVatDto: {
538
+ /** @description VAT number to validate (EU format) */
539
+ vatNumber: string;
540
+ };
541
+ TopUpBalanceDto: {
542
+ /**
543
+ * @description Amount to add to balance
544
+ * @example 50
545
+ */
546
+ amount: number;
547
+ /** @description Payment method reference (e.g., Stripe payment intent ID) */
548
+ paymentReference?: string;
549
+ /** @description Type of payment reference (e.g., stripe_payment, manual_topup) */
550
+ referenceType?: string;
551
+ /** @description Description for the top-up */
552
+ description?: string;
553
+ };
554
+ BalanceSettingsDto: {
555
+ /** @description Low balance alert threshold */
556
+ lowBalanceThreshold?: number;
557
+ /** @description Enable automatic top-up */
558
+ autoTopUpEnabled?: boolean;
559
+ /** @description Amount to auto top-up when balance is low */
560
+ autoTopUpAmount?: number;
561
+ /** @description Balance threshold to trigger auto top-up */
562
+ autoTopUpThreshold?: number;
563
+ /** @description Credit limit for negative balance */
564
+ creditLimit?: number;
565
+ };
566
+ PaylinqWebhookResponse: {
567
+ success: boolean;
568
+ message: string;
569
+ };
570
+ AddPaymentMethodDto: Record<string, never>;
571
+ CreateProjectDto: Record<string, never>;
572
+ UpdateProjectDto: Record<string, never>;
573
+ UpdatePoaSettingsDto: {
574
+ /**
575
+ * @description Enable PoA verification for this environment
576
+ * @example true
577
+ */
578
+ poaEnabled?: boolean;
579
+ /**
580
+ * @description Threshold for auto-approval (0.0-1.0). Documents above this confidence are auto-approved.
581
+ * @example 0.7
582
+ */
583
+ poaAutoApproveThreshold?: number;
584
+ /**
585
+ * @description Threshold for manual review (0.0-1.0). Documents between this and auto-approve threshold require manual review.
586
+ * @example 0.5
587
+ */
588
+ poaManualReviewThreshold?: number;
589
+ /**
590
+ * @description Block final verification until PoA is approved
591
+ * @example false
592
+ */
593
+ poaRequiredForVerification?: boolean;
594
+ /**
595
+ * @description Force all PoA to go through manual review (disable auto-approve)
596
+ * @example false
597
+ */
598
+ poaForceManualReview?: boolean;
599
+ };
600
+ RetryWebhookDeliveryDto: Record<string, never>;
601
+ InviteTeamMemberDto: Record<string, never>;
602
+ UpdateMemberRoleDto: Record<string, never>;
603
+ AcceptInvitationDto: Record<string, never>;
604
+ RegisterDto: Record<string, never>;
605
+ UpdateProfileDto: Record<string, never>;
606
+ ChangePasswordDto: Record<string, never>;
607
+ SetPasswordDto: Record<string, never>;
608
+ ResetPasswordDto: Record<string, never>;
609
+ CreateContactRequestDto: {
610
+ /**
611
+ * @description Full name of the person making contact
612
+ * @example John Doe
613
+ */
614
+ name: string;
615
+ /**
616
+ * @description Email address for contact
617
+ * @example john.doe@example.com
618
+ */
619
+ email: string;
620
+ };
621
+ ContactRequestResponseDto: {
622
+ /** @description Unique identifier for the contact request */
623
+ id: string;
624
+ /** @description Contact person name */
625
+ name: string;
626
+ /** @description Contact email address */
627
+ email: string;
628
+ /**
629
+ * @description Source of the contact request
630
+ * @example landing
631
+ */
632
+ source: string;
633
+ /**
634
+ * @description Status of the contact request
635
+ * @example new
636
+ */
637
+ status: string;
638
+ /**
639
+ * Format: date-time
640
+ * @description Timestamp when the request was created
641
+ */
642
+ createdAt: string;
643
+ };
644
+ CreateSessionDto: {
645
+ /**
646
+ * @description Custom client metadata for identification and tracking
647
+ * @example {
648
+ * "userId": "user_12345",
649
+ * "email": "john.doe@example.com",
650
+ * "name": "John Doe",
651
+ * "accountType": "premium"
652
+ * }
653
+ */
654
+ clientMetadata?: Record<string, never>;
655
+ /**
656
+ * @description Session expiry time in minutes (default: 5, max: 60)
657
+ * @example 30
658
+ */
659
+ expiryMinutes?: number;
660
+ /**
661
+ * @description Language for widget UI
662
+ * @example de
663
+ * @enum {string}
664
+ */
665
+ language?: "en" | "de" | "uk";
666
+ /**
667
+ * @description Server-side metadata for internal tracking
668
+ * @example {
669
+ * "requestId": "req_123",
670
+ * "sourceIp": "192.168.1.1",
671
+ * "userAgent": "MyApp/1.0"
672
+ * }
673
+ */
674
+ serverMetadata?: Record<string, never>;
675
+ };
676
+ SessionDetailsDto: {
677
+ /**
678
+ * @description Unique session identifier
679
+ * @example clx1234567890abcdef
680
+ */
681
+ id: string;
682
+ /**
683
+ * @description Session status
684
+ * @example pending
685
+ * @enum {string}
686
+ */
687
+ status: "pending" | "in_progress" | "completed" | "failed" | "expired";
688
+ /**
689
+ * Format: date-time
690
+ * @description Session expiration timestamp
691
+ * @example 2024-10-25T14:30:00.000Z
692
+ */
693
+ expiresAt: string;
694
+ /**
695
+ * @description Client metadata
696
+ * @example {
697
+ * "userId": "user_12345",
698
+ * "email": "john.doe@example.com"
699
+ * }
700
+ */
701
+ clientMetadata?: Record<string, never>;
702
+ /**
703
+ * @description Widget URL for embedding
704
+ * @example https://widget.flonk.id/?sessionId=clx1234567890abcdef&mode=embedded
705
+ */
706
+ widgetUrl: string;
707
+ /**
708
+ * @description QR code data for mobile verification
709
+ * @example https://widget.flonk.id/verify/clx1234567890abcdef?token=kyc_1234567890_abc123
710
+ */
711
+ qrCodeUrl: string;
712
+ /**
713
+ * Format: date-time
714
+ * @description Session creation timestamp
715
+ * @example 2024-10-25T14:25:00.000Z
716
+ */
717
+ createdAt: string;
718
+ /**
719
+ * @description Project identifier
720
+ * @example clxproject123
721
+ */
722
+ projectId: string;
723
+ /**
724
+ * @description Whether manual upload is allowed for this session
725
+ * @example true
726
+ */
727
+ allowManualUpload: boolean;
728
+ /**
729
+ * @description Embed token for widget authentication (like Stripe client_secret)
730
+ * @example eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
731
+ */
732
+ embedToken?: string;
733
+ /**
734
+ * @description Indicates if an existing session was reused instead of creating a new one
735
+ * @example false
736
+ */
737
+ reused?: boolean;
738
+ /**
739
+ * @description Test mode flag - true if created with test keys (sk_test_*)
740
+ * @example false
741
+ */
742
+ testMode?: boolean;
743
+ /**
744
+ * Format: date-time
745
+ * @description Last activity timestamp
746
+ * @example 2024-10-25T14:28:00.000Z
747
+ */
748
+ lastActivity?: string;
749
+ /**
750
+ * @description Server metadata
751
+ * @example {
752
+ * "requestId": "req_123",
753
+ * "sourceIp": "192.168.1.1"
754
+ * }
755
+ */
756
+ serverMetadata?: Record<string, never>;
757
+ /**
758
+ * Format: date-time
759
+ * @description Last update timestamp
760
+ * @example 2024-10-25T14:28:00.000Z
761
+ */
762
+ updatedAt: string;
763
+ };
764
+ UpdateStatusDto: Record<string, never>;
765
+ AddNoteDto: Record<string, never>;
766
+ UploadDocumentDto: {
767
+ /** @enum {string} */
768
+ documentType: "main" | "back" | "face" | "passport" | "id_card" | "driver_license" | "utility_bill" | "bank_statement" | "selfie";
769
+ };
770
+ UpdateSystemRoleDto: Record<string, never>;
771
+ SuspendUserDto: Record<string, never>;
772
+ UnsuspendUserDto: Record<string, never>;
773
+ ChangeMembershipRoleDto: Record<string, never>;
774
+ AddMembershipDto: Record<string, never>;
775
+ SuspendProjectDto: Record<string, never>;
776
+ UnsuspendProjectDto: Record<string, never>;
777
+ UpdateBrandingDto: Record<string, never>;
778
+ UpdateWebhookDto: Record<string, never>;
779
+ UpdateFaceAutoCaptureDto: Record<string, never>;
780
+ AddDomainDto: Record<string, never>;
781
+ CreditBalanceDto: Record<string, never>;
782
+ DebitBalanceDto: Record<string, never>;
783
+ ApproveProjectDto: Record<string, never>;
784
+ RejectProjectDto: Record<string, never>;
785
+ CreateInviteDto: Record<string, never>;
786
+ AcceptInviteDto: Record<string, never>;
787
+ UpdatePlatformFaceAutoCaptureDto: Record<string, never>;
788
+ WebhookExtractedDataDto: {
789
+ full_name?: string | null;
790
+ first_name?: string | null;
791
+ last_name?: string | null;
792
+ date_of_birth?: string | null;
793
+ nationality?: string | null;
794
+ sex?: string | null;
795
+ issue_date?: string | null;
796
+ expiry_date?: string | null;
797
+ place_of_birth?: string | null;
798
+ };
799
+ WebhookPoaVerificationDto: {
800
+ status: string;
801
+ confidence_score: number | null;
802
+ verified_address?: string | null;
803
+ address_match?: boolean;
804
+ };
805
+ WebhookDuplicateVerificationDto: {
806
+ is_duplicate: boolean;
807
+ previous_verification_id: string;
808
+ previous_verified_at: string;
809
+ /** @enum {string} */
810
+ match_type: "document_number" | "personal_data";
811
+ similarity_score: number;
812
+ };
813
+ WebhookReuseSourceDto: {
814
+ /** @enum {number} */
815
+ is_reused: true;
816
+ verified_identity_id: string;
817
+ original_project_id: string | null;
818
+ original_attempt_id: string;
819
+ original_completed_at: string;
820
+ consent_at: string;
821
+ mode: string;
822
+ };
823
+ WebhookEventObjectDto: {
824
+ id: string;
825
+ client_id?: string;
826
+ client_metadata?: {
827
+ [key: string]: unknown;
828
+ };
829
+ status: string;
830
+ confidence?: number;
831
+ document_type: string;
832
+ extracted_data: components["schemas"]["WebhookExtractedDataDto"];
833
+ created_at: string;
834
+ updated_at?: string;
835
+ updated_by?: string;
836
+ test_mode?: boolean;
837
+ poa_verification?: components["schemas"]["WebhookPoaVerificationDto"];
838
+ duplicate_verification?: components["schemas"]["WebhookDuplicateVerificationDto"];
839
+ reuse_source?: components["schemas"]["WebhookReuseSourceDto"];
840
+ previous_status?: string;
841
+ rejection_reason?: string;
842
+ reviewed_by?: string;
843
+ };
844
+ WebhookEventDataDto: {
845
+ object: components["schemas"]["WebhookEventObjectDto"];
846
+ };
847
+ WebhookEventDto: {
848
+ id: string;
849
+ /** @enum {string} */
850
+ type: "verification.completed" | "verification.status_changed" | "verification.updated";
851
+ created: number;
852
+ livemode: boolean;
853
+ data: components["schemas"]["WebhookEventDataDto"];
854
+ };
855
+ };
856
+ responses: never;
857
+ parameters: never;
858
+ requestBodies: never;
859
+ headers: never;
860
+ pathItems: never;
861
+ }
862
+
1
863
  type SessionStatus = 'pending' | 'connected' | 'processing' | 'completed' | 'failed' | 'expired';
2
864
  type DocumentType = 'passport' | 'id_card' | 'driver_license';
3
865
  type WidgetLanguage = 'en' | 'de' | 'uk';
@@ -5,6 +867,12 @@ interface FlonkKYCServerOptions {
5
867
  secretKey: string;
6
868
  apiBase?: string;
7
869
  timeout?: number;
870
+ /** Max retry attempts for transient failures (429/5xx/network). Default 2. */
871
+ maxRetries?: number;
872
+ /** Base backoff in ms (full-jittered exponential). Default 250. */
873
+ retryBaseMs?: number;
874
+ /** Pin the REST API version (`Flonk-Version` header). Default: the SDK's build version. */
875
+ apiVersion?: string;
8
876
  }
9
877
  interface CreateSessionParams {
10
878
  clientMetadata?: Record<string, unknown>;
@@ -12,6 +880,13 @@ interface CreateSessionParams {
12
880
  expiryMinutes?: number;
13
881
  language?: WidgetLanguage;
14
882
  serverMetadata?: Record<string, unknown>;
883
+ /**
884
+ * Idempotency key for this create. A retry with the same key returns the
885
+ * original session instead of creating a new one. Auto-generated (UUID) per
886
+ * call if omitted; supply your own to make a specific create idempotent
887
+ * across process restarts.
888
+ */
889
+ idempotencyKey?: string;
15
890
  }
16
891
  interface Session {
17
892
  id: string;
@@ -36,42 +911,48 @@ interface UpdateSessionParams {
36
911
  clientMetadata?: Record<string, unknown>;
37
912
  serverMetadata?: Record<string, unknown>;
38
913
  }
39
- interface WebhookEvent {
914
+ type WebhookSchemas = components['schemas'];
915
+ type WebhookObjectFull = WebhookSchemas['WebhookEventObjectDto'];
916
+ /** Fields common to every verification webhook's `data.object` (generated). */
917
+ type WebhookObjectBase = Omit<WebhookObjectFull, 'duplicate_verification' | 'reuse_source' | 'previous_status' | 'rejection_reason' | 'reviewed_by' | 'updated_at' | 'updated_by'>;
918
+ interface WebhookEventBase {
40
919
  id: string;
41
- type: 'verification.completed' | 'verification.status_changed' | 'verification.updated';
42
920
  created: number;
43
921
  livemode: boolean;
922
+ }
923
+ /** Automated AI verification finished. */
924
+ interface VerificationCompletedEvent extends WebhookEventBase {
925
+ type: 'verification.completed';
44
926
  data: {
45
- object: {
46
- id: string;
47
- client_id?: string;
48
- client_metadata?: Record<string, unknown>;
49
- status: string;
50
- confidence?: number;
51
- document_type: string;
52
- extracted_data: {
53
- full_name?: string;
54
- first_name?: string;
55
- last_name?: string;
56
- date_of_birth?: string;
57
- nationality?: string;
58
- sex?: string;
59
- [key: string]: unknown;
60
- };
61
- created_at: string;
62
- updated_at?: string;
63
- updated_by?: string;
64
- test_mode?: boolean;
65
- poa_verification?: {
66
- status: string;
67
- confidence_score: number | null;
68
- };
69
- previous_status?: string;
70
- rejection_reason?: string;
71
- reviewed_by?: string;
72
- };
927
+ object: WebhookObjectBase & Pick<WebhookObjectFull, 'duplicate_verification' | 'reuse_source'>;
928
+ };
929
+ }
930
+ /** An admin manually approved/rejected the verification. */
931
+ interface VerificationStatusChangedEvent extends WebhookEventBase {
932
+ type: 'verification.status_changed';
933
+ data: {
934
+ object: WebhookObjectBase & Pick<WebhookObjectFull, 'previous_status' | 'rejection_reason' | 'reviewed_by'>;
935
+ };
936
+ }
937
+ /** An admin edited verification data, or async PoA review finished. */
938
+ interface VerificationUpdatedEvent extends WebhookEventBase {
939
+ type: 'verification.updated';
940
+ data: {
941
+ object: WebhookObjectBase & Pick<WebhookObjectFull, 'updated_at' | 'updated_by'>;
73
942
  };
74
943
  }
944
+ /**
945
+ * Closed discriminated union — the Stripe approach. `event.type` narrows
946
+ * `event.data.object`, so a `switch (event.type)` is type-safe and exhaustive,
947
+ * and per-event fields live only on the events that carry them. Kept current by
948
+ * the OpenAPI codegen pipeline (TYPES.md): a new platform event type is picked
949
+ * up on the next generation. A brand-new type still arrives at runtime
950
+ * (`constructEvent` never rejects it) — handle it in the `default` branch, and
951
+ * cast if you must reference it before regenerating.
952
+ */
953
+ type WebhookEvent = VerificationCompletedEvent | VerificationStatusChangedEvent | VerificationUpdatedEvent;
954
+ /** Union of every event `type` literal this SDK knows. */
955
+ type WebhookEventType = WebhookEvent['type'];
75
956
  interface WebhookVerifyOptions {
76
957
  /** Max clock skew in seconds. Default: 300 */
77
958
  maxSkewSeconds?: number;
@@ -79,7 +960,13 @@ interface WebhookVerifyOptions {
79
960
 
80
961
  declare class Webhooks {
81
962
  /**
82
- * Verify X-Signature-256 header: "sha256=<hex>"
963
+ * Verify X-Signature-256 header: "sha256=<hex>".
964
+ *
965
+ * NOTE: this format carries no timestamp, so it has **no replay protection** —
966
+ * a captured request stays valid forever. Prefer {@link verifyTimestampSignature}
967
+ * (the `t=,v1=` header, sent as `X-Signature`), and dedupe by `event.id` in
968
+ * your own store (a unique index, or Redis `SET id 1 NX EX <ttl>`) so retries
969
+ * are processed once.
83
970
  */
84
971
  verifySignature(payload: string, signature: string, secret: string): WebhookEvent;
85
972
  /**
@@ -92,11 +979,18 @@ declare class Webhooks {
92
979
  constructEvent(payload: string, signature: string, secret: string): WebhookEvent;
93
980
  private parsePayload;
94
981
  private parseHeader;
982
+ /**
983
+ * Constant-time string compare with no length-dependent branch: HMAC both
984
+ * sides with a per-call random key so the compared buffers are always 32
985
+ * bytes regardless of input length, then timingSafeEqual. Equal digests imply
986
+ * equal inputs (HMAC collision resistance), so this leaks neither the result
987
+ * nor the length via timing.
988
+ */
95
989
  private safeEqual;
96
990
  }
97
991
 
98
992
  declare class FlonkKYCServer {
99
- static readonly version = "1.8.2";
993
+ static readonly version = "1.9.1";
100
994
  private readonly http;
101
995
  readonly webhooks: Webhooks;
102
996
  constructor(options: FlonkKYCServerOptions);
@@ -105,14 +999,22 @@ declare class FlonkKYCServer {
105
999
  updateSession(sessionId: string, params: UpdateSessionParams): Promise<SessionDetails>;
106
1000
  }
107
1001
 
1002
+ /**
1003
+ * Stable, machine-branchable error codes returned by the API in the `code`
1004
+ * field of an error body. Open union (`| (string & {})`) so new codes don't
1005
+ * break consumers — branch on the ones you handle, fall through on the rest.
1006
+ */
1007
+ type FlonkErrorCode = 'authentication_error' | 'invalid_publishable_key' | 'session_not_found' | 'session_expired' | 'session_invalid_state' | 'rate_limited' | 'validation_error' | 'api_error' | (string & {});
108
1008
  declare class FlonkError extends Error {
109
- readonly code: string;
1009
+ readonly code: FlonkErrorCode;
110
1010
  readonly statusCode?: number | undefined;
111
- constructor(message: string, code: string, statusCode?: number | undefined);
1011
+ constructor(message: string, code: FlonkErrorCode, statusCode?: number | undefined);
112
1012
  }
113
1013
  declare class FlonkAPIError extends FlonkError {
114
1014
  readonly body?: unknown | undefined;
115
- constructor(message: string, statusCode: number, body?: unknown | undefined);
1015
+ constructor(message: string, statusCode: number, body?: unknown | undefined,
1016
+ /** The API's stable error code (from the response body), if it sent one. */
1017
+ code?: FlonkErrorCode);
116
1018
  }
117
1019
  declare class FlonkAuthenticationError extends FlonkError {
118
1020
  constructor(message?: string);
@@ -124,4 +1026,4 @@ declare class FlonkWebhookSignatureError extends FlonkError {
124
1026
  constructor(message?: string);
125
1027
  }
126
1028
 
127
- export { type CreateSessionParams, type DocumentType, FlonkAPIError, FlonkAuthenticationError, FlonkError, FlonkKYCServer, type FlonkKYCServerOptions, FlonkValidationError, FlonkWebhookSignatureError, type Session, type SessionDetails, type SessionStatus, type UpdateSessionParams, type WebhookEvent, type WebhookVerifyOptions, Webhooks, type WidgetLanguage };
1029
+ export { type CreateSessionParams, type DocumentType, FlonkAPIError, FlonkAuthenticationError, FlonkError, type FlonkErrorCode, FlonkKYCServer, type FlonkKYCServerOptions, FlonkValidationError, FlonkWebhookSignatureError, type Session, type SessionDetails, type SessionStatus, type UpdateSessionParams, type VerificationCompletedEvent, type VerificationStatusChangedEvent, type VerificationUpdatedEvent, type WebhookEvent, type WebhookEventType, type WebhookVerifyOptions, Webhooks, type WidgetLanguage };