JavaScript SDK
@regsn/api is the official JavaScript / TypeScript client for the Regulatory Snapshot API. It is an ESM-only package with no runtime dependencies — it uses the built-in fetch and AbortController, which means it works on Node 18+, Deno, Bun, and modern browsers.
This page is the full reference. For your first request, start with the Quickstart.
Install
npm install @regsn/api
# or
pnpm add @regsn/api
# or
yarn add @regsn/apiRequires Node 18+ (for the built-in fetch). TypeScript types ship in the package — no @types/regsn-api needed.
[!WARNING] The package is ESM-only. CommonJS
require('@regsn/api')will not work. If you’re on a CommonJS codebase, either migrate to ESM or use a dynamicawait import('@regsn/api').
Authenticate
The SDK reads REGSN_API_KEY from process.env by default:
export REGSN_API_KEY="regsn_live_aBcD1234eFgH5678iJkL9012mNoP3456"import { RegSn } from '@regsn/api';
const client = new RegSn();Or pass it explicitly:
const client = new RegSn({ apiKey: process.env.REGSN_API_KEY });Constructor options:
| Option | Default | Notes |
|---|---|---|
apiKey | process.env.REGSN_API_KEY | Bearer key. Required (env or arg). |
baseUrl | https://api.regsn.app | Override for staging / local dev. |
timeoutMs | 180_000 | Per-request timeout. |
[!WARNING] Never instantiate the SDK in browser code with a raw key. Anything in the browser bundle is visible to your users. Put the SDK behind a backend route that holds the key server-side; in the browser, talk to your own backend.
The four resources
client.scans // POST/GET /v1/scans, GET /v1/scans/:id
client.snapshots // GET /v1/snapshots, GET /v1/snapshots/:id (+ sub-resources)
client.exports // POST/GET /v1/exports
client.usage // GET /v1/usageFull TypeScript types are in index.d.ts.
client.scans
create(config, opts?) -> Promise<ScanResult>
Run a scan; defaults to sync mode with auto-polling.
const result = await client.scans.create({
jurisdictions: ['UK', 'EU'],
areas: ['AML', 'Sanctions'],
horizon: 12,
engine: 'v4.5-beta',
verificationMode: 'in-analyst',
});
// For a deterministic envelope shape, re-fetch the snapshot.
const snapshot = await client.snapshots.get(result.snapshot_id);
console.log(snapshot.data.executive_narrative);Behaviour matches the Python SDK:
- Sends
POST /v1/scans?mode=syncwith an auto-generatedIdempotency-Key. - If the response is
200, returns directly — the envelope is flat underresult.snapshot. - If the response is
202(timed out the 120s ceiling), polls until terminal (pollUntilDone: truedefault), then returns the full envelope nested underresult.snapshot.data(becausewait()re-fetches viaGET /v1/snapshots/{id}). - Calling
client.snapshots.get(result.snapshot_id)after the scan always returns the stable nested shape — that’s what the rest of the docs use.
opts:
| Option | Default | Notes |
|---|---|---|
mode | 'sync' | 'sync' or 'async'. |
idempotencyKey | crypto.randomUUID() | Pass to use a deterministic key. |
pollUntilDone | true | Set false to return the 202 envelope and poll yourself. |
createAsync(config, opts?) -> Promise<ScanResult>
Convenience for ?mode=async. Returns immediately with scan_id + status_url + stream_url.
const job = await client.scans.createAsync({
jurisdictions: ['UK'], areas: ['AML'], horizon: 12,
});
console.log(job.scan_id);get(scanId) -> Promise<ScanResult>
Returns GET /v1/scans/{id}.
wait(scanId, opts?) -> Promise<ScanResult>
Polls until the scan reaches a terminal state, then fetches the full snapshot.
const result = await client.scans.wait(scanId, { pollMs: 5000, timeoutMs: 600_000 });Throws RegSnError({ code: 'scan_failed' }) on failed, or RegSnError({ code: 'wait_timeout' }) if the timeout elapses.
client.snapshots
const list = await client.snapshots.list({ starred: 'true', limit: 20 });
const full = await client.snapshots.get(snapshotId);
const items = await client.snapshots.getItems(snapshotId);
const trends = await client.snapshots.getTrends(snapshotId);
const summary = await client.snapshots.getExecutiveSummary(snapshotId);
const narrative = await client.snapshots.getExecutiveNarrative(snapshotId, { language: 'en' });
const drift = await client.snapshots.getDrift(snapshotId);list() accepts every query param from GET /v1/snapshots.
client.exports
const job = await client.exports.create({
snapshot_id: snapshotId,
artifact_type: 'pdf',
provider: 'internal-pdf',
options: {},
});
console.log(job.export_job_id);
// Poll until done.
let status;
do {
await new Promise(r => setTimeout(r, 5000));
status = await client.exports.get(job.export_job_id);
} while (status.status === 'pending' || status.status === 'running');(provider, artifact_type) matrix on the Exports page.
client.usage
const data = await client.usage.get({ group_by: 'day' });
console.log(data.totals);
for (const b of data.buckets) console.log(b.key, b.cost_cents);Errors
import { RegSn, RegSnError } from '@regsn/api';
const client = new RegSn();
try {
await client.scans.create({ jurisdictions: ['UK'], areas: ['AML'], horizon: 13 });
} catch (err) {
if (err instanceof RegSnError) {
console.error(err.status); // 422
console.error(err.code); // 'validation_error'
console.error(err.requestId); // 'req_…'
console.error(err.body); // the full problem-details body
}
throw err;
}| Property | Type | Notes |
|---|---|---|
status | number | HTTP status. |
code | string | Machine-readable error code. |
requestId | string | The X-Request-Id. Include in bug reports. |
body | object | Parsed problem-details body. |
Retries
The SDK retries automatically on:
- 5xx (3 attempts, exponential backoff with ±1s jitter)
- 429 (honors
Retry-After, capped at 60 seconds) - Network / abort errors
After 3 retries it throws RegSnError({ code: 'retry_exceeded' }). Idempotency keys are preserved across retries — the server replays the cached response instead of re-running a scan.
TypeScript
The package ships hand-written types:
import type {
RegSnOptions,
ScanConfig,
ScanResult,
SnapshotEnvelope,
ApiError,
} from '@regsn/api';
const config: ScanConfig = {
jurisdictions: ['UK'],
areas: ['AML'],
horizon: 12,
};ScanConfig carries enum types for horizon (3 | 6 | 12 | 18 | 24 | 36), engine, and auditorModel — your editor will autocomplete the valid values.
See also
- Scans — request body, modes, streaming.
- Snapshots — the data model the SDK returns.
- Python SDK — same surface, different language.
- Errors — codes you’ll see on
RegSnError.code. - Glossary — bearer key, idempotency key, request ID.