Configuration
SladeIDConfig
| Field | Type | Default | Notes |
|---|---|---|---|
middlewareUrl | string | required | Base URL of the Slade ID backend service. |
auth | SladeIDAuth | required | Keycloak auth strategy — see Authentication and below. |
integratorId | string | optional | Tenant id; sent as X-Integrator-Id on orchestrator dispatch. Required with keycloakClientCredentials. |
fetchImpl | typeof fetch | globalThis.fetch | For Node test harnesses. |
timeoutMs | number | 15000 | Per network call. |
readerServiceUrl | string | http://localhost:18065 | Local hardware-service base URL used by sladeId.reader for device discovery (/status) and the testCapture diagnostic. |
SladeIDAuth
How the SDK obtains its Keycloak bearer. See Authentication for the full flow and a reference backend broker.
type SladeIDAuth =
// Recommended for embedded / browser use. Your backend mints the token
// (see Authentication); the SDK calls getToken() on first use and again
// after a 401 to refresh. The secret never reaches the browser.
| { type: 'tokenProvider'; getToken: () => Promise<string> }
// Server / kiosk only — BROWSER-UNSAFE (embeds a client secret). The SDK
// runs the client_credentials exchange itself.
| {
type: 'keycloakClientCredentials';
clientId: string;
clientSecret: string;
issuerUrl?: string; // default: SIL identity issuer
realm?: string; // default: 'slade360'
audience?: string; // default: 'biometrics-middleware'
scope?: string;
};FingerprintReaderConfig
Passed to createFingerprintReader when you build a standalone reader. sladeId.reader needs none of this — it reuses the SladeID instance’s middleware URL, auth, and orchestrator.
| Field | Type | Default | Notes |
|---|---|---|---|
getToken | () => Promise<string> | string | required | Returns a middleware (Keycloak) bearer — not a local hardware-service token. Called on demand and again after a 401. Throwing surfaces as a ReaderAuthError. |
middlewareUrl | string | required | Base URL of the middleware. Enroll / verify / search are dispatched to its orchestrator; fetchEnrolled reads its biometrics endpoint. |
integratorId | string | optional | Sent as X-Integrator-Id on orchestrator dispatch. Optional for tenant-scoped tokens. |
localServiceUrl | string | http://localhost:18065 | Local hardware-service base URL, used only for device discovery (/status) and the testCapture diagnostic. |
workstationId | string | optional | Pin the dispatch target. Must be supplied with deviceId. See below. |
deviceId | string | optional | Device to name on dispatch. Must be supplied with workstationId. |
fetchImpl | typeof fetch | globalThis.fetch | For Node test harnesses. |
Pinning a dispatch target
Enroll, verify, and search never touch loopback: they are dispatched through the middleware orchestrator, which routes them to a workstation. The local hardware service is consulted only to learn which workstation and device to name. So if you already know both ids, there is nothing left to discover.
Supply workstationId and deviceId together and the reader skips loopback entirely — no /status polling starts, and the ids you gave are used verbatim on every dispatch. That is what lets a host with no companion application (a developer machine, a server-side batch job, a tablet driving a shared scanner) run the flows.
Supplying exactly one of the pair throws a TypeError at construction. Half a pinned target would silently fall back to loopback discovery for the missing half, which fails in a way that looks nothing like a config mistake.
[!WARNING] This does not remove the need for a live workstation. Capture still happens on that remote machine; when it is offline the middleware answers
503 "Target workstation is not currently live."It is not a no-hardware mode. Read Pin a dispatch target for the full set of tradeoffs.