Warddocs
Client SDKs

JavaScript SDK

npm install @mandatelabs/ward
export WARD_API_KEY="ward_test_..."
import { Ward, type Decision } from "@mandatelabs/ward";

const client = new Ward();                         // or new Ward({ apiKey, baseURL, timeout: 60_000, maxRetries: 2 })
const d: Decision = await client.decide("screen", { name: "Ana Maria Perez", country: "PAN" });
console.log(d.decision, d.score, d.signals);

No dependencies; uses the runtime's fetch (pass { fetch } to use your own). Server-side only.

Methods

Method Endpoint
decide(type, input, { model, subject_ref, subject_consent, session_id, policy_baseline, async, idempotencyKey, timeout }) POST /decide
statement(files, { profile, focus, thresholds, column_map, ... }) statement
credit(files, { profile, requested_instalment, ... }) credit
screen(name, { date_of_birth, country, entity_type }) screen
ask(question, { decision, result, context, session_id }) POST /ask
feedback(decisionId, { correct, right_decision, label, threshold, note }) POST /decide/{id}/feedback
getDecision(id), evidence(id), session(id) GET /decide/{id}, /evidence, /sessions/{id}
models(), balance(), usage(days) GET /models, /billing/*
kyc.sendCode(channel, destination), kyc.confirmCode(challengeId, code) POST /kyc/otp/*
kyc.verify(applicant, { email_challenge_id, phone_challenge_id, policy, locale }) POST /kyc/verify
kyc.outcome(id, outcome), kyc.checkEmail(email), kyc.checkPhone(phone) KYC
kyc.networkAuthStart(phone, redirectUri), kyc.networkAuthComplete(state, code) POST /kyc/network-auth/*
jobs.get(id), jobs.wait(id, { timeout }) GET /jobs/{id}
subjects.get(ref), subjects.update(ref, fields), subjects.delete(ref) /subjects/{ref}

statement() and credit() take file paths (Node), Uint8Arrays, { name, data } or ready { file_base64, file_name }.

Errors

import { APIError, InsufficientBalanceError, UnprocessableEntityError } from "@mandatelabs/ward";

try {
  await client.decide("statement", input);
} catch (e) {
  if (e instanceof UnprocessableEntityError && e.code === "needs_mapping") showReading(e.details.reading);
  else if (e instanceof InsufficientBalanceError) topUp();
  else if (e instanceof APIError) console.error(e.status, e.code, e.requestId);
  else throw e;
}

Classes: AuthenticationError (401), InsufficientBalanceError (402), PermissionDeniedError (403), NotFoundError (404), ConflictError (409), PayloadTooLargeError (413), UnprocessableEntityError (422), RateLimitError (429), InternalServerError (5xx), APIConnectionError / APITimeoutError (no response); all extend WardError.