@verifymx/sdk-node
v0.1.0-beta.1
Published
Official Node.js / TypeScript SDK for the VerifyMX identity-verification API. Mexican market — INE, CURP, RFC, passport.
Maintainers
Readme
@verifymx/sdk-node
Official Node.js / TypeScript SDK for VerifyMX — the identity-verification API for the Mexican market. Drop-in MetaMap-compatible REST interface with native support for INE, CURP, RFC and passport.
npm install @verifymx/sdk-node
# or
pnpm add @verifymx/sdk-node
# or
yarn add @verifymx/sdk-nodeRequires Node 18+. Uses native fetch and FormData.
Quickstart
import { VerifyMXClient } from '@verifymx/sdk-node';
const vmx = new VerifyMXClient({
clientId: process.env.VERIFYMX_CLIENT_ID!,
clientSecret: process.env.VERIFYMX_CLIENT_SECRET!,
});
// 1. Start a verification
const ver = await vmx.createVerification({ workflowId: 'wf_default' });
// 2. Upload an INE front photo
import { readFileSync } from 'node:fs';
await vmx.uploadDocument(ver.id, readFileSync('./ine-front.jpg'), 'ine-front.jpg', 'front');
// 3. Wait for the verdict
const result = await vmx.waitUntilTerminal(ver.id);
// result.status is one of: APPROVED | REJECTED | MANUAL_REVIEW | EXPIREDWhat the SDK takes care of for you
- OAuth client_credentials auth flow with a cached, auto-refreshing token.
- Retry with backoff on 429 (honors
Retry-After) and 5xx, plus transient network errors (ECONNRESET, ETIMEDOUT, etc.). Default 3 retries. - Idempotency keys auto-generated on every
POSTso the retries above cannot accidentally create duplicate verifications. Override with{ idempotencyKey }if you want to dedupe across processes. - Typed errors —
RateLimitedError,UnauthorizedError,NotFoundError,ValidationError,ConflictError,ServerError,NetworkError,TimeoutError— all extendingVerifyMXError. - Polling —
waitUntilTerminal(id)blocks until the verification reaches a final status, or throwsTimeoutError. - Webhook signature verification — see below.
Error handling
import {
VerifyMXClient,
RateLimitedError,
UnauthorizedError,
ValidationError,
VerifyMXError,
} from '@verifymx/sdk-node';
try {
await vmx.createVerification({ workflowId: 'wf_default' });
} catch (err) {
if (err instanceof RateLimitedError) {
// SDK already retried up to `retries.max` times. Caller is over budget.
console.warn(`Hit rate limit; wait ${err.retryAfter}s`);
} else if (err instanceof UnauthorizedError) {
console.error('Bad credentials — check VERIFYMX_CLIENT_ID/SECRET');
} else if (err instanceof ValidationError) {
console.error('Bad input:', err.message, err.details);
} else if (err instanceof VerifyMXError) {
// Some other API error
console.error(`VerifyMX error ${err.code}: ${err.message} (requestId: ${err.requestId})`);
} else {
throw err;
}
}The code field on VerifyMXError is the server's stable error taxonomy
(e.g. 'WORKFLOW_INACTIVE', 'CURP_STATUS_ANNULLED', 'VALIDATION_ERROR').
Branch on it when you need to react to a specific business rule.
Webhook signature verification
Mount as middleware (Express / Fastify / Connect-compatible):
import express from 'express';
import { webhookMiddleware } from '@verifymx/sdk-node';
const app = express();
app.post(
'/webhooks/verifymx',
express.raw({ type: 'application/json' }), // raw body required
webhookMiddleware(process.env.WEBHOOK_SECRET!),
(req, res) => {
const event = JSON.parse(req.body.toString('utf-8'));
// ... handle event.type === 'verification.approved' etc.
res.status(200).send('ok');
},
);Or verify manually:
import { verifyWebhookSignature } from '@verifymx/sdk-node';
const signature = req.headers['x-verifymx-signature'] as string;
const ok = verifyWebhookSignature(
rawBody, // string or Buffer — NOT the parsed object
signature,
process.env.WEBHOOK_SECRET!,
);
if (!ok) return res.status(401).send('bad signature');Critical: always pass the raw request body. If you pass the parsed JSON re-serialized, the HMAC will mismatch on whitespace and key ordering.
Configuration
new VerifyMXClient({
clientId: '...', // required
clientSecret: '...', // required
apiUrl: 'https://api.verifymx.xyz', // default
timeoutMs: 30_000, // per-request timeout (default 30s)
retries: {
max: 3, // max retries after first attempt
baseDelayMs: 500, // doubles per attempt, capped at 16s
},
userAgent: 'my-app/1.4.2', // optional, appended to the SDK UA
});API reference
Methods follow the REST endpoints documented at docs.verifymx.xyz. Highlights:
| Method | Endpoint |
| ---------------------------------------------- | ----------------------------------------- |
| createVerification(input) | POST /verifications |
| getVerification(id) | GET /verifications/:id |
| listVerifications(opts?) | GET /verifications |
| updateVerificationStatus(id, status, notes?) | PATCH /verifications/:id/status |
| uploadDocument(id, file, name, type) | POST /verifications/:id/inputs (multipart) |
| waitUntilTerminal(id, opts?) | polling helper |
| createWorkflow(data) / listWorkflows() / etc. | /workflows |
| createWebhook(url, events) / etc. | /webhooks |
| screenName(name, opts?) | POST /aml/screen |
| sendOtp(...) / verifyOtp(...) | POST /otp/{send,verify} |
Stability
0.1.0-beta — the API surface is stable but minor pre-1.0 changes are still
possible. We will keep a changelog in CHANGELOG.md and call
out anything breaking in release notes.
Links
License
Apache-2.0
