Skip to content
ES

SDK @zentto/kyc-sdk

This content is not available in your language yet.

@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.

Paquete privado (requiere acceso al scope @zentto/*):

Ventana de terminal
npm install @zentto/kyc-sdk
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ónTipoDefaultDescripción
apiKeystringAPI key zkyc_... para auth server-to-server. Opcional si se usan cookies en browser.
baseUrlstringhttps://kyc.zentto.netURL base del servicio.
timeoutnumber30000Timeout por request en ms.
maxRetriesnumber3Reintentos con backoff exponencial (no reintenta errores 4xx).
withCredentialsbooleantrue si no hay apiKeyEnví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.).

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 Blob
const front: FileInput = { data: file, filename: file.name, contentType: file.type };
MétodoFirmaEndpoint
createcreate(opts?: CreateSessionOptions)POST /v1/sessions
getget(id: string)GET /v1/sessions/:id
listlist(opts?: ListSessionsOptions)GET /v1/sessions
deletedelete(id: string)DELETE /v1/sessions/:id
pendingpending()GET /v1/sessions/pending
decidedecide(id: string, opts: DecideSessionOptions)POST /v1/sessions/:id/decision
shareshare(id: string)POST /v1/sessions/:id/share
importimport(shareToken: string)POST /v1/sessions/import
createWorkflowcreateWorkflow(opts: CreateWorkflowOptions)POST /v1/sessions/workflows
listWorkflowslistWorkflows()GET /v1/sessions/workflows
getWorkflowgetWorkflow(id: string)GET /v1/sessions/workflows/:id
updateWorkflowupdateWorkflow(id: string, opts: UpdateWorkflowOptions)PATCH /v1/sessions/workflows/:id
deleteWorkflowdeleteWorkflow(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 });
MétodoFirmaEndpoint
idVerificationidVerification(opts: IdVerificationOptions)POST /v1/documents/id-verification
proofOfAddressproofOfAddress(opts: ProofOfAddressOptions)POST /v1/documents/poa
databaseValidationdatabaseValidation(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" },
});
MétodoFirmaEndpoint
livenessliveness(opts: LivenessOptions)POST /v1/biometrics/liveness
faceMatchfaceMatch(opts: FaceMatchOptions)POST /v1/biometrics/face-match
ageEstimationageEstimation(opts: AgeEstimationOptions)POST /v1/biometrics/age
faceSearchfaceSearch(opts: FaceSearchOptions)POST /v1/biometrics/face-search
faceIndexfaceIndex(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" },
});
MétodoFirmaEndpoint
screenscreen(opts: AmlScreenOptions)POST /v1/aml/screen
const { match, score, hits } = await kyc.aml.screen({
fullName: "John Doe",
entityType: "person",
});
MétodoFirmaEndpoint
checkcheck(opts: KybCheckOptions)POST /v1/kyb
getget(id: string)GET /v1/kyb/:id
listlist()GET /v1/kyb
const { check } = await kyc.kyb.check({ companyName: "Acme Inc", country: "us" });
MétodoFirmaEndpoint
createcreate(opts: CreateWebhookOptions)POST /v1/webhooks
listlist()GET /v1/webhooks
deletedelete(id: string)DELETE /v1/webhooks/:id
testtest(id: string)POST /v1/webhooks/:id/test
deliveriesdeliveries(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"],
});
MétodoFirmaEndpoint
createcreate(opts?: CreateApiKeyOptions)POST /v1/keys
listlist()GET /v1/keys
revokerevoke(id: string)DELETE /v1/keys/:id

El SDK lanza errores tipados ante fallos de la API o de red:

ErrorCuándo
ZenttoKycErrorLa API devolvió un error (statusCode >= 400) o el request falló. Expone statusCode y response.
ZenttoKycTimeoutErrorEl 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;
}
}