veriis
v0.1.2
Published
Official Node.js client for the Veris OCR API — passport MRZ, Aadhaar, document, and resume extraction.
Maintainers
Readme
veriis
Official Node.js / TypeScript client for the Veris OCR API by RecursAI Technologies — passport MRZ, Aadhaar, general document, and resume extraction.
It is a thin, fully-typed wrapper over the HTTP API: the heavy OCR (PaddleOCR PP-OCRv5 + PP-StructureV3, vision-LLM field extraction) runs in the Veris OCR service; this package makes calling it from a Node app a one-liner.
- ✅ Zero runtime dependencies (uses the Node 18+ global
fetch/FormData) - ✅ ESM and CommonJS, with bundled TypeScript types
- ✅ Accepts file paths,
Buffer,Uint8Array,ArrayBuffer,Blob, or streams - ✅ Typed responses for every endpoint
- ✅ Typed errors, timeouts, and automatic retries (429 / 502 / 503)
Requirements
- Node.js 18 or newer.
- A running Veris OCR service and an API key (
pk_live_.../pk_test_...). See the service README to run it locally via Docker or point at a deployment.
Install or upgrade
npm install veriis@^0.1.2This updates package.json and the active npm lockfile. Applications pinned to
an older exact version should commit the regenerated lockfile and redeploy.
Confirm the installed version with npm ls veriis.
Quickstart
import { VerisOCR } from "veriis";
const client = new VerisOCR({
baseUrl: "http://localhost:8000", // or https://veris.recursai.in
apiKey: "pk_live_...",
});
// Passport MRZ — pass a path, a Buffer, a stream, etc.
const passport = await client.passport.extract("./passport.jpg");
console.log(passport.mrz.passport_number, passport.mrz.expiry_date);
// General document (image, PDF, or DOCX), optional OCR language(s)
const doc = await client.document.extract(fs.readFileSync("./invoice.pdf"), {
lang: "eng+fra",
});
console.log(doc.page_count, doc.pages[0]?.text);
// Resume / CV → structured fields
const resume = await client.resume.extract("./cv.pdf");
console.log(resume.name, resume.total_experience_human, resume.skills);
const aadhaar = await client.aadhaar.extract("./aadhaar.png");
console.log(aadhaar.aadhaar.name, aadhaar.aadhaar.mobile_number);
const queued = await client.jobs.submitMany(aadhaarFiles, {
mode: "aadhaar",
concurrency: 4,
});CommonJS works too:
const { VerisOCR } = require("veriis");
const client = new VerisOCR({ baseUrl: "http://localhost:8000", apiKey: "pk_live_..." });Configuration
new VerisOCR({
baseUrl, // required — or set VERIS_OCR_BASE_URL
apiKey, // or set VERIS_OCR_API_KEY
adminToken, // only for admin.* calls — or set VERIS_OCR_ADMIN_TOKEN
timeoutMs, // default 120000 (OCR can be slow)
maxRetries, // default 2 (429/502/503 + idempotent connection errors)
headers, // extra headers on every request
fetch, // custom fetch implementation
});Any option can come from the environment instead:
export VERIS_OCR_BASE_URL=http://localhost:8000
export VERIS_OCR_API_KEY=pk_live_...const client = new VerisOCR(); // picks up the env varsFile inputs
Every extract method accepts any of:
| Input | Example |
| --- | --- |
| Path string | client.passport.extract("./passport.jpg") |
| Buffer / Uint8Array | client.passport.extract(buf) |
| ArrayBuffer | client.passport.extract(arrayBuffer) |
| Blob | client.passport.extract(blob) |
| Stream / async-iterable | client.passport.extract(fs.createReadStream("p.jpg")) |
| Explicit descriptor | client.passport.extract({ data: buf, filename: "p.jpg", contentType: "image/jpeg" }) |
The content type is sniffed from the bytes (JPEG/PNG/WEBP/PDF/DOCX) when not given.
API
Extraction
client.passport.extract(file, opts?)→PassportResponseclient.document.extract(file, { lang?, ...opts })→DocumentResponseclient.resume.extract(file, opts?)→ResumeResponse
Aadhaar and background jobs
client.aadhaar.extract(file, opts?)returnsAadhaarResponse.client.jobs.submit(file, { mode: "aadhaar", idempotencyKey? })queues one card.client.jobs.submitMany(files, { mode: "aadhaar", concurrency? })queues several cards concurrently.client.jobs.get(jobId, opts?)returns the current job status and result.client.jobs.listFailed({ limit? })lists retained failures for the API key.client.jobs.retry(jobId, opts?)atomically requeues a retained failed upload.
History
client.history.list({ mode?, limit?, offset? }, opts?)→HistoryListclient.history.get(id, opts?)→HistoryDetailclient.history.delete(id, opts?)→{ deleted }client.history.clear(opts?)→{ deleted }
Admin (requires adminToken)
client.admin.createKey(input, opts?)→AdminCreatedKey(plaintext key returned once)client.admin.listKeys(includeRevoked?, opts?)→AdminKeyListclient.admin.revokeKey(keyId, opts?)→AdminRevokeResponse
createKey accepts allowed_ocr_modes with any non-empty combination of
passport, document, resume, and aadhaar. Omitting it grants all four modes.
Health
client.health.check(opts?)→HealthResponse(no auth)
Every method takes an optional final opts object: { signal?, timeoutMs?, maxRetries? }.
Errors
All failures throw a subclass of VerisOCRError:
| Class | When |
| --- | --- |
| VerisOCRBadRequestError | 400 / 413 — bad, unsupported, or oversized input |
| VerisOCRAuthenticationError | 401 / 403 — missing / invalid / revoked key or admin token |
| VerisOCRNotFoundError | 404 |
| VerisOCRValidationError | 422 — detail holds the field errors |
| VerisOCRRateLimitError | 429 — check .retryAfter |
| VerisOCRServerError | 5xx |
| VerisOCRTimeoutError | request exceeded timeoutMs |
| VerisOCRConnectionError | network / DNS / connection failure |
import { VerisOCRRateLimitError, VerisOCRBadRequestError } from "veriis";
try {
await client.passport.extract("./passport.jpg");
} catch (err) {
if (err instanceof VerisOCRRateLimitError) {
console.warn(`Rate limited; retry after ${err.retryAfter}s`);
} else if (err instanceof VerisOCRBadRequestError) {
console.error(err.code, err.message, err.requestId);
} else {
throw err;
}
}Each error carries status, code, requestId, and detail when the server
provided them.
Cancellation
Pass an AbortSignal:
const controller = new AbortController();
setTimeout(() => controller.abort(), 5_000);
await client.document.extract("./big.pdf", { signal: controller.signal });Development
npm install
npm run typecheck # tsc --noEmit
npm test # vitest (no network — fetch is mocked)
npm run build # tsup → dist/ (ESM + CJS + .d.ts)License
Proprietary — © RecursAI Technologies.
