SDK @zentto/kyc-sdk
@zentto/kyc-sdk es el cliente oficial de Zentto KYC para Node y browser. Envuelve la API REST (/v1/...), añade reintentos con backoff, timeout y manejo de errores tipados.
Instalación
Sección titulada «Instalación»Paquete privado (requiere acceso al scope @zentto/*):
npm install @zentto/kyc-sdkConfiguración del cliente
Sección titulada «Configuración del cliente»import { ZenttoKyc } from "@zentto/kyc-sdk";
const kyc = new ZenttoKyc({ apiKey: process.env.KYC_API_KEY, // zkyc_... (server-to-server) baseUrl: "https://kyc.zentto.net", // default timeout: 30000, // ms, default 30000 maxRetries: 3, // default 3});| Opción | Tipo | Default | Descripción |
|---|---|---|---|
apiKey | string | — | API key zkyc_... para auth server-to-server. Opcional si se usan cookies en browser. |
baseUrl | string | https://kyc.zentto.net | URL base del servicio. |
timeout | number | 30000 | Timeout por request en ms. |
maxRetries | number | 3 | Reintentos con backoff exponencial (no reintenta errores 4xx). |
withCredentials | boolean | true si no hay apiKey | Envía cookies httpOnly (uso browser/dashboard). |
En browser, sin exponer la API key:
const kyc = new ZenttoKyc({ withCredentials: true });Todas las respuestas incluyen ok: boolean. Los métodos devuelven el JSON de la API tal cual ({ ok, session }, { ok, result }, etc.).
Uploads: FileInput
Sección titulada «Uploads: FileInput»Los métodos multipart (documentos y biometría) reciben archivos como FileInput:
interface FileInput { data: Uint8Array | ArrayBuffer | Blob; filename: string; contentType?: string;}En Node (Buffer es un Uint8Array):
import { readFile } from "node:fs/promises";
const front: FileInput = { data: await readFile("./front.jpg"), filename: "front.jpg", contentType: "image/jpeg",};En browser (File/Blob de un <input type="file">):
const file = input.files[0]; // File extiende Blobconst front: FileInput = { data: file, filename: file.name, contentType: file.type };kyc.sessions
Sección titulada «kyc.sessions»| Método | Firma | Endpoint |
|---|---|---|
create | create(opts?: CreateSessionOptions) | POST /v1/sessions |
get | get(id: string) | GET /v1/sessions/:id |
list | list(opts?: ListSessionsOptions) | GET /v1/sessions |
delete | delete(id: string) | DELETE /v1/sessions/:id |
pending | pending() | GET /v1/sessions/pending |
decide | decide(id: string, opts: DecideSessionOptions) | POST /v1/sessions/:id/decision |
share | share(id: string) | POST /v1/sessions/:id/share |
import | import(shareToken: string) | POST /v1/sessions/import |
createWorkflow | createWorkflow(opts: CreateWorkflowOptions) | POST /v1/sessions/workflows |
listWorkflows | listWorkflows() | GET /v1/sessions/workflows |
getWorkflow | getWorkflow(id: string) | GET /v1/sessions/workflows/:id |
updateWorkflow | updateWorkflow(id: string, opts: UpdateWorkflowOptions) | PATCH /v1/sessions/workflows/:id |
deleteWorkflow | deleteWorkflow(id: string) | DELETE /v1/sessions/workflows/:id |
const { session } = await kyc.sessions.create({ features: ["id", "liveness", "face_match"],});const detail = await kyc.sessions.get(session.id);const { sessions, total } = await kyc.sessions.list({ status: "approved", limit: 20 });kyc.documents
Sección titulada «kyc.documents»| Método | Firma | Endpoint |
|---|---|---|
idVerification | idVerification(opts: IdVerificationOptions) | POST /v1/documents/id-verification |
proofOfAddress | proofOfAddress(opts: ProofOfAddressOptions) | POST /v1/documents/poa |
databaseValidation | databaseValidation(opts: DatabaseValidationOptions) | POST /v1/documents/database-validation |
const res = await kyc.documents.idVerification({ sessionId, frontImage: { data: frontBuf, filename: "front.jpg", contentType: "image/jpeg" }, backImage: { data: backBuf, filename: "back.jpg", contentType: "image/jpeg" },});kyc.biometrics
Sección titulada «kyc.biometrics»| Método | Firma | Endpoint |
|---|---|---|
liveness | liveness(opts: LivenessOptions) | POST /v1/biometrics/liveness |
faceMatch | faceMatch(opts: FaceMatchOptions) | POST /v1/biometrics/face-match |
ageEstimation | ageEstimation(opts: AgeEstimationOptions) | POST /v1/biometrics/age |
faceSearch | faceSearch(opts: FaceSearchOptions) | POST /v1/biometrics/face-search |
faceIndex | faceIndex(opts: FaceIndexOptions) | POST /v1/biometrics/face-search/index |
await kyc.biometrics.liveness({ sessionId, image: { data: buf, filename: "selfie.jpg" } });await kyc.biometrics.faceMatch({ sessionId, userImage: { data: selfie, filename: "selfie.jpg" }, refImage: { data: front, filename: "front.jpg" },});kyc.aml
Sección titulada «kyc.aml»| Método | Firma | Endpoint |
|---|---|---|
screen | screen(opts: AmlScreenOptions) | POST /v1/aml/screen |
const { match, score, hits } = await kyc.aml.screen({ fullName: "John Doe", entityType: "person",});kyc.kyb
Sección titulada «kyc.kyb»| Método | Firma | Endpoint |
|---|---|---|
check | check(opts: KybCheckOptions) | POST /v1/kyb |
get | get(id: string) | GET /v1/kyb/:id |
list | list() | GET /v1/kyb |
const { check } = await kyc.kyb.check({ companyName: "Acme Inc", country: "us" });kyc.webhooks
Sección titulada «kyc.webhooks»| Método | Firma | Endpoint |
|---|---|---|
create | create(opts: CreateWebhookOptions) | POST /v1/webhooks |
list | list() | GET /v1/webhooks |
delete | delete(id: string) | DELETE /v1/webhooks/:id |
test | test(id: string) | POST /v1/webhooks/:id/test |
deliveries | deliveries(id: string) | GET /v1/webhooks/:id/deliveries |
const { secret } = await kyc.webhooks.create({ url: "https://miapp.com/kyc/webhook", events: ["session.completed", "session.declined", "session.review"],});kyc.keys
Sección titulada «kyc.keys»| Método | Firma | Endpoint |
|---|---|---|
create | create(opts?: CreateApiKeyOptions) | POST /v1/keys |
list | list() | GET /v1/keys |
revoke | revoke(id: string) | DELETE /v1/keys/:id |
Manejo de errores
Sección titulada «Manejo de errores»El SDK lanza errores tipados ante fallos de la API o de red:
| Error | Cuándo |
|---|---|
ZenttoKycError | La API devolvió un error (statusCode >= 400) o el request falló. Expone statusCode y response. |
ZenttoKycTimeoutError | El request superó el timeout configurado (extiende ZenttoKycError, statusCode = 0). |
Los errores 4xx no se reintentan; los 5xx y los de red se reintentan con backoff exponencial hasta maxRetries.
import { ZenttoKyc, ZenttoKycError, ZenttoKycTimeoutError } from "@zentto/kyc-sdk";
try { const { session } = await kyc.sessions.create({ features: ["id"] });} catch (err) { if (err instanceof ZenttoKycTimeoutError) { // request superó el timeout } else if (err instanceof ZenttoKycError) { console.error(err.statusCode, err.response?.error); } else { throw err; }}