Saltar al contenido principal
El SDK de Node trae definiciones TypeScript completas, reintentos automáticos y un método tipado por cada endpoint de OrigoID. Funciona en cualquier runtime Node 18+ y en Deno.

Instalación

npm install @origoid/sdk
Paquete en npm: @origoid/sdk. Código en github.com/origoid/sdk-node (público, para auditar).

Inicializa el cliente

import { OrigoidApiClient } from "@origoid/sdk";

const client = new OrigoidApiClient({
  apiKey: process.env.ORIGOID_API_KEY!,
});
Ese es todo el setup — no hay nada más que configurar. Nunca hardcodees la API key. Cárgala desde process.env, un secrets manager (Vault, 1Password, Doppler, etc.), o la capa de config de tu plataforma.

Tu primera llamada

El ejemplo usa PELJ900101HDFRRN09, un CURP sintético de los ejemplos del OpenAPI — no es CURP de persona real. Reemplázalo con el CURP que necesites validar.
import { OrigoidApiClient } from "@origoid/sdk";

const client = new OrigoidApiClient({ apiKey: process.env.ORIGOID_API_KEY! });

const envelope = await client.renapo.validateCurp({
  curp: "PELJ900101HDFRRN09", // sintético — reemplazar con input real
});

if (envelope.status === "OK" && envelope.type === "SUCCESS") {
  // envelope.data trae el registro RENAPO.
  console.log("Titular del CURP:", envelope.data);
} else {
  // Otro tipo de resultado — revisa el catálogo de respuestas del endpoint para tu lógica.
  console.log(envelope.type, "—", envelope.message);
}
Cada método devuelve la misma shape Envelope: { status, type, message, data, transactionId, processedAt, billable, errors? }. Ver Envelope de respuesta para el contrato completo.

Métodos por recurso

El cliente agrupa operaciones bajo una propiedad por dominio regulatorio.

client.authentication

await client.authentication.issueToken({ expireAfter: 1800 });

client.renapo

await client.renapo.validateCurp({ curp: "PELJ900101HDFRRN09" });
await client.renapo.lookupCurp({
  givenNames: "JUAN",
  firstSurname: "PEREZ",
  secondSurname: "LOPEZ",
  dateOfBirth: "1990-01-01",
  gender: "H",
  birthStateCode: "DF",
});

client.sat

await client.sat.validateRfc({ rfc: "PEZJ811011KI1" });
await client.sat.extractCsf({ rfc: "PEZJ811011KI1", cif: "17060597619" });
await client.sat.validateCfdi({
  uuid: "7C8BD4EA-AE86-4CB5-88B8-C6E61E988A8B",
  rfcEmisor: "PEZJ811011KI1",
  rfcReceptor: "EMP170623KI3",
  total: "999999.99",
});

client.imss

await client.imss.lookupNss({ curp: "PELJ900101HDFRRN09" });
await client.imss.getEmploymentStatus({
  curp: "PELJ900101HDFRRN09",
  nss: "92038109713",
});

client.ine

await client.ine.validateVoterList({ cic: "123456789", citizenIdentifier: "987654321" });
await client.ine.extractVoterIdData({ front: "<jpg base64>", back: "<jpg base64>" });
await client.ine.extractQrData({ back: "<jpg base64 del reverso>" });

client.compliance

await client.compliance.searchSat69({ rfc: "PEZJ811011KI1" });
await client.compliance.searchSat69B({ rfc: "PEZJ811011KI1" });
await client.compliance.searchOfac({ name: "John Doe", minSimilarityScore: 85 });
await client.compliance.searchPeps({
  givenNames: "JUAN",
  firstSurname: "PEREZ",
  secondSurname: "LOPEZ",
});
Nota: el método para la lista SAT 69-B es searchSat69B (con B mayúscula). Los demás métodos de compliance siguen el patrón regular camelCase.

client.biometrics

await client.biometrics.matchFaces({
  face: "<selfie base64>",
  front: "<frente id base64>",
  threshold: 80,
  documentType: "INE",
});
await client.biometrics.checkLiveness({ selfie: "<selfie base64>" });

client.email

await client.email.validateEmail({ email: "user@example.com" });

client.proofOfAddress

await client.proofOfAddress.extractProofOfAddress({ file: "<pdf o jpg base64>" });

Manejo de errores

El SDK distingue entre errores de negocio (vienen dentro del envelope) y errores de transporte (lanzados como excepciones tipadas).

Errores de negocio — léelos del envelope

Para cualquier respuesta HTTP 200, incluyendo INVALID_REQUEST, el SDK devuelve un objeto Envelope normal. Revisa status y type antes de usar data:
const env = await client.renapo.validateCurp({ curp: "BAD" });

if (env.status === "ERROR") {
  // INVALID_REQUEST, SERVICE_UNAVAILABLE, …
  console.error(env.type, env.message);
} else {
  // status === "OK" — puede ser un NOT_FOUND de negocio
  switch (env.type) {
    case "SUCCESS":            /* env.data trae el registro */ break;
    case "CURP_NOT_FOUND":     /* sin match */ break;
    // ver /es/errors y /es/catalogs para el catálogo completo
  }
}

Errores de transporte — try/catch

Para 401, 429 y fallas de transporte irrecuperables el SDK lanza errores tipados:
import {
  OrigoidApiClient,
  OrigoidApiError,
  OrigoidApiTimeoutError,
} from "@origoid/sdk";

try {
  const env = await client.renapo.validateCurp({ curp: "PELJ900101HDFRRN09" });
  // … usa env
} catch (err) {
  if (err instanceof OrigoidApiTimeoutError) {
    // request no completó dentro del timeout configurado
  } else if (err instanceof OrigoidApiError) {
    // err.statusCode — 401, 429, etc.
    // err.body — envelope que devolvió el servidor
  } else {
    throw err; // inesperado
  }
}

Configuración por llamada (avanzado)

Cada método acepta un segundo argumento opcional:
await client.ine.validateVoterList(
  { cic: "123456789", citizenIdentifier: "987654321" },
  {
    timeoutInSeconds: 120,   // default 60
    maxRetries: 3,           // default 2
    abortSignal: ac.signal,  // AbortController estándar
    headers: { "x-trace-id": "..." },
  },
);
Lee esto antes de tunear timeouts o retries. El SDK sólo reintenta errores 5xx y fallas de red, nunca respuestas de negocio exitosas — entonces los retries no crean llamadas duplicadas facturables cuando el API respondió correctamente. crean llamadas extra cuando el request realmente falló: un request que hace timeout tres veces puede consumir tres créditos si la llamada eventualmente tuvo éxito en un intento posterior.
  • Los defaults (timeoutInSeconds: 60, maxRetries: 2) son correctos para casi cualquier workload. Cambia sólo con razón específica.
  • Combinar timeout largo con maxRetries alto (ej. 120s × 5) significa que un único request fallando puede ocupar un thread cliente hasta 10 minutos — malo para tu throughput y tu infraestructura.
  • Sobrescribe per-call sólo en endpoints con cold starts lentos conocidos (algunas llamadas de compliance y de lista INE).

TypeScript

Cada tipo de request y response se exporta bajo el namespace OrigoidApi:
import { OrigoidApi } from "@origoid/sdk";

function handleResult(env: OrigoidApi.Envelope) {
  if (env.status === "OK" && env.type === "SUCCESS" && env.data) {
    // env.data está tipado
  }
}

CommonJS

El paquete trae ambos entry points ESM y CJS. En proyectos CommonJS:
const { OrigoidApiClient } = require("@origoid/sdk");
const client = new OrigoidApiClient({ apiKey: process.env.ORIGOID_API_KEY });

Uso desde navegador

No llames a OrigoID directo desde un navegador. Las API keys son credenciales de larga vida con acceso facturable a tu cuenta; en el momento que una key llega al bundle del navegador, a la consola, o a local storage, queda efectivamente pública y en riesgo de abuso — del mismo modo que nunca pondrías la secret key de un procesador de tarjetas en código del lado cliente. El patrón correcto es backend-for-frontend (BFF): tu navegador habla con tu servidor, tu servidor guarda la API key y llama a OrigoID desde un ambiente confiable (Node, Python, Go). Si tu caso de uso genuinamente requiere llamadas directas desde navegador (widget de partner, formulario embebido, etc.) podemos habilitar CORS para tus orígenes específicos. La key sólo permanece segura si la escopeas con cuidado y la complementas con restricciones de referrer/origen — te ayudamos a diseñar ese flujo. Contáctanos y trabajamos la arquitectura contigo.