Official zero-dependency TypeScript SDK for the Scanii content security API.
Works in Node 22+ and modern browsers (anywhere fetch and FormData are native).
- Light. Zero runtime dependencies, stdlib only.
- Up to date. Always current with the latest Scanii API.
- Integration-only. Wraps the REST API — retries, concurrency, and batching are the caller's responsibility.
npm install @scanii/coreLooking for
scanii(unscoped)? That's a placeholder — install@scanii/coreinstead.
import { ScaniiClient, ScaniiTarget } from '@scanii/core';
const client = new ScaniiClient({
key: process.env.SCANII_KEY!,
secret: process.env.SCANII_SECRET!,
endpoint: ScaniiTarget.US1,
});
// Scan a file from disk (Node-only):
const result = await client.processFile('./document.pdf');
console.log(result.findings);
// Or pass any supported content type:
const result2 = await client.process(new Blob([buffer]));In the browser, pass a File from an <input type="file">:
const fileInput = document.querySelector<HTMLInputElement>('#file')!;
const result = await client.process(fileInput.files![0]);For browser usage, prefer minting a short-lived auth token server-side and constructing the client with { token }.
| Method | REST | Returns |
|---|---|---|
process(content, metadata?, callback?) |
POST /files |
Promise<ScaniiProcessingResult> |
processFile(path, metadata?, callback?) |
POST /files |
Promise<ScaniiProcessingResult> |
processFromUrl(location, options?) |
POST /files |
Promise<ScaniiProcessingResult> (v2.2 preview) |
processAsync(content, metadata?, callback?) |
POST /files/async |
Promise<ScaniiPendingResult> |
processAsyncFile(path, metadata?, callback?) |
POST /files/async |
Promise<ScaniiPendingResult> |
fetch(url, metadata?, callback?) |
POST /files/fetch |
Promise<ScaniiPendingResult> |
retrieve(id) |
GET /files/{id} |
Promise<ScaniiProcessingResult> |
retrieveTrace(id) |
GET /files/{id}/trace |
Promise<ScaniiTraceResult | undefined> (v2.2 preview) |
ping() |
GET /ping |
Promise<boolean> |
createAuthToken(timeoutSeconds?) |
POST /auth/tokens |
Promise<ScaniiAuthToken> |
retrieveAuthToken(id) |
GET /auth/tokens/{id} |
Promise<ScaniiAuthToken> |
deleteAuthToken(id) |
DELETE /auth/tokens/{id} |
Promise<boolean> |
processFile / processAsyncFile are Node-only (use node:fs); browsers use process(blob, ...).
content accepts Blob, File, ArrayBuffer, any ArrayBufferView (e.g. Uint8Array, Buffer), or ReadableStream (Web Streams API, Node 22+).
Full API reference: https://scanii.github.io/openapi/v22/.
interface ScaniiProcessingResult {
id: string;
findings: readonly string[];
checksum: string | undefined;
contentLength: number | undefined;
contentType: string | undefined;
metadata: Readonly<Record<string, string>>;
creationDate: string | undefined;
error: string | undefined;
requestId: string | undefined;
hostId: string | undefined;
resourceLocation: string | undefined;
statusCode: number;
rawResponse: string;
}findings is always an array. An empty array means the content is clean.
new ScaniiClient({ key, secret, endpoint: ScaniiTarget.EU1 });The endpoint option accepts either a ScaniiTarget constant or a bare URL string (useful for scanii-cli, e.g. endpoint: 'http://localhost:4000').
| Constant | Endpoint |
|---|---|
ScaniiTarget.US1 |
https://api-us1.scanii.com |
ScaniiTarget.EU1 |
https://api-eu1.scanii.com |
ScaniiTarget.EU2 |
https://api-eu2.scanii.com |
ScaniiTarget.AP1 |
https://api-ap1.scanii.com |
ScaniiTarget.AP2 |
https://api-ap2.scanii.com |
ScaniiTarget.CA1 |
https://api-ca1.scanii.com |
https://api.scanii.com |
import { ScaniiAuthError, ScaniiError, ScaniiRateLimitError } from '@scanii/core';
try {
await client.process(blob);
} catch (err) {
if (err instanceof ScaniiRateLimitError) {
console.log('retry after', err.retryAfter, 'seconds');
} else if (err instanceof ScaniiAuthError) {
// 401/403 — bad credentials
} else if (err instanceof ScaniiError) {
console.error(err.statusCode, err.message, err.requestId);
}
}Per SDK Principle 3, the SDK does not retry on the caller's behalf — backoff and retry policy belong to your application.
The SDK ships integration tests against scanii-cli, a local mock server. No real Scanii credentials are needed for development or CI.
docker run -d --name scanii-cli -p 4000:4000 ghcr.io/scanii/scanii-cli:latest server
npm install
npm testThe integration tests assume endpoint: http://localhost:4000 with key / secret. They self-skip when scanii-cli is not reachable, so npm test is safe to run without it.
The package ships ESM, CommonJS, and .d.ts types. Use import from ESM, require from CommonJS:
// CommonJS
const { ScaniiClient } = require('@scanii/core');Requires Node 22+ for native fetch/FormData/Blob.
Bug reports and PRs welcome at https://github.com/scanii/scanii-node/issues.