Python SDK
pip install mandate-ward
export WARD_API_KEY="ward_test_..."
from ward import Ward
client = Ward() # or Ward(api_key="...", timeout=60, max_retries=2)
d = client.decide("screen", {"name": "Ana Maria Perez", "country": "PAN"})
print(d.decision, d.score, d.signals) # attribute or key access: d["decision"]
Async
import asyncio
from ward import AsyncWard
async def main():
async with AsyncWard() as client:
d = await client.decide("payment", {"amount": 120, "currency": "USD", "mcc": "5411"})
asyncio.run(main())
Methods
| Method | Endpoint |
|---|---|
decide(type, input, *, model, subject_ref, subject_consent, session_id, policy_baseline, run_async, idempotency_key, timeout) |
POST /decide |
statement(files, *, profile, focus, thresholds, column_map, …) |
POST /decide (statement) |
credit(files, *, profile, requested_instalment, …) |
POST /decide (credit) |
screen(name, *, date_of_birth, country, entity_type) |
POST /decide (screen) |
ask(question, *, decision=None, result=None, context=None, session_id=None) |
POST /ask |
feedback(decision_id, *, correct, right_decision, label, threshold, note) |
POST /decide/{id}/feedback |
get_decision(id), evidence(id), session(id) |
GET /decide/{id}, /evidence, /sessions/{id} |
models(), balance(), usage(days=30) |
GET /models, /billing/* |
kyc.send_code(channel, destination), kyc.confirm_code(challenge_id, code) |
POST /kyc/otp/* |
kyc.verify(applicant, *, email_challenge_id, phone_challenge_id, policy, locale) |
POST /kyc/verify |
kyc.outcome(verification_id, outcome), kyc.check_email(email), kyc.check_phone(phone) |
POST /kyc/outcomes, /email/check, /phone/check |
kyc.network_auth_start(phone, redirect_uri), kyc.network_auth_complete(state, code) |
POST /kyc/network-auth/* |
jobs.get(id), jobs.wait(id, timeout=300) |
GET /jobs/{id} |
subjects.get(ref), subjects.update(ref, **fields), subjects.delete(ref) |
/subjects/{ref} |
statement() and credit() take paths, bytes, (name, bytes) tuples or ready {"file_base64", "file_name"} dicts.
Errors
import ward
try:
d = client.decide("statement", inp)
except ward.UnprocessableEntityError as e:
if e.code == "needs_mapping":
reading = e.details["reading"] # show it, then resend with column_map
except ward.InsufficientBalanceError:
top_up()
except ward.APIError as e:
log.error("ward %s %s (request %s)", e.status, e.code, e.request_id)
| Class | Status |
|---|---|
AuthenticationError |
401 |
InsufficientBalanceError |
402 |
PermissionDeniedError |
403 |
NotFoundError |
404 |
ConflictError |
409 |
PayloadTooLargeError |
413 |
UnprocessableEntityError |
422 |
RateLimitError |
429 |
InternalServerError |
5xx |
APIConnectionError, APITimeoutError |
no response |
All inherit from ward.WardError. Configuration: WARD_API_KEY, WARD_BASE_URL (default https://api.mandatelabs.ai/api/v1).