Developers

Build with Bolehlah

REST endpoints, signed webhooks, and SDKs in TypeScript and PHP. Every Officer's input and output is a documented JSON schema. No SOAP. No surprises.

Quickstart

Your first decision in two snippets

curl
POST /v1/decisions
curl -X POST https://api.bolehlah.ai/v1/decisions \
  -H "Authorization: Bearer sk_live_••••" \
  -H "Content-Type: application/json" \
  -d '{
    "officer": "underwriter",
    "borrower_id": "brw_01HXY7Z3K2N9...",
    "product": {
      "type": "personal_term",
      "principal": 12000,
      "tenure_months": 24,
      "rate_apr": 11.5
    },
    "consent_id": "cns_01HXY7ZA8R..."
  }'
typescript
@bolehlah/sdk
import { Bolehlah } from "@bolehlah/sdk"

const b = new Bolehlah({ apiKey: process.env.BOLEHLAH_KEY! })

const decision = await b.decisions.create({
  officer: "underwriter",
  borrower_id: "brw_01HXY7Z3K2N9...",
  product: {
    type: "personal_term",
    principal: 12_000,
    tenure_months: 24,
    rate_apr: 11.5,
  },
  consent_id: "cns_01HXY7ZA8R...",
})

if (decision.outcome === "approve") {
  await b.disbursements.schedule({
    decision_id: decision.id,
    channel: "duitnow",
    release_at: decision.akad.signed_at,
  })
}

Sandbox keys ship with every workspace. Live keys are issued after KYC and a 30-minute architecture review.

What you get

REST + Webhooks

Versioned REST endpoints over HTTPS. Idempotent writes. Webhook-driven event stream with replay-from-cursor for at-least-once delivery.

TypeScript + PHP SDKs

First-party SDKs cover the full surface area: Officers, decisions, borrowers, payments, webhooks. Generated from the same OpenAPI spec the platform runs on.

Sandbox-first

Every workspace ships with a sandbox tenant. Same code paths, fake CCRIS, fake borrowers, deterministic Officer responses — wire and break things safely.

Integration matrix

What we connect to today

Live connectors are production-graded with SLAs and retries. Beta connectors are functionally complete and used by pilot lenders. Coming soon items have a sandbox stub you can develop against.

Connector
Status
CCRIS pull (BNM)
Live
CTOS direct
Live
DuitNow / FPX
Live
iPay88
Live
Razer Merchant Services
Beta
Stripe (cross-border)
Beta
ANGKASA eSPGA file generator
Live
BIRO Angkasa salary feed
Live
WhatsApp Business Cloud API
Live
Telegram Bot API
Live
MyDigital ID e-KYC
Beta
JPN ID verification
Coming
BNM regulatory return generator
Beta
AMLA / sanctions screening
Live
Xero / SQL Account export
Beta
Custom CRM/HRMS bridge
Coming

Officer schema

Every decision is a structured object

Underwriter responses always carry a confidence score, weighted reasons, and conditions. The audit_chain field is the merkle hash you can present in a regulatory enquiry to prove the decision was not tampered with.

response · application/json
decision.outcome
{
  "id": "dec_01HXY8AAQK7T...",
  "officer": "underwriter",
  "officer_tier": "Director",
  "outcome": "approve",
  "confidence": 0.93,
  "approved_principal": 12000,
  "approved_tenure_months": 24,
  "approved_rate_apr": 11.5,
  "reasons": [
    { "code": "DSR_HEALTHY", "weight": 0.32, "value": 0.41 },
    { "code": "CCRIS_NO_ARREARS_24M", "weight": 0.28 },
    { "code": "ANGKASA_ELIGIBLE", "weight": 0.18 },
    { "code": "TENURE_AGE_FIT", "weight": 0.14 }
  ],
  "conditions": [
    "Salary slip within 60 days of disbursement",
    "ANGKASA deduction code attached at AKAD"
  ],
  "audit_chain": "merkle:0x9af...c12",
  "latency_ms": 1840,
  "created_at": "2026-04-26T03:14:11Z"
}

Webhook events

Subscribe once. React to everything.

Each event ships with an Ed25519 signature, an event_id, and the originating decision_id where applicable. At-least-once delivery, exponential backoff up to 24 hours, replay-from-cursor for outages.

application.created

Borrower submits a fresh loan application.

application.updated

Documents added, KYC results, recomputed DSR.

decision.made

Officer returns approve / refer / reject with reasons.

akad.signed

Borrower signs the loan agreement (Murabahah / Tawarruq / conventional).

disbursement.released

Funds left the lender's account via DuitNow / FPX.

payment.received

Instalment posted, with channel and clearance status.

payment.missed

Due date passed without funds — delinquency clock starts.

borrower.message

Inbound WhatsApp / Telegram from a borrower handled by B.

officer.escalated

B handed a thread off to a human teammate.

compliance.flagged

AMLA, sanctions, or policy violation needs review.

Security & rate limits

Built for regulated production traffic

TLS 1.3 minimum

All endpoints HTTPS-only with HSTS preload. Modern cipher suites enforced; legacy ciphers refused at the edge.

mTLS service-to-service

When a server-side workload calls Bolehlah, optional mutual-TLS is supported via uploaded client certificates per workspace.

Signed webhook payloads

Every webhook ships with an Ed25519 signature header and a replay-resistant nonce. Reject any payload that fails verification.

Rate limits

Default 600 req/min per workspace, burst 60. Decisions endpoint 60 req/min. Limits return 429 with Retry-After. Lifted on Pro+ tiers.

Versioning

Date-pinned API versions

Pin a version with the Bolehlah-Version header (e.g. 2026-04-01). Breaking changes ship as a new dated version with a 12-month sunset window for the previous one. Deprecation notices land in response headers six months ahead.

Onboarding

White-glove today, self-serve next year

We currently onboard every developer with a 30-minute architecture call to scope integration. Self-serve sandbox + key issuance ships in Q3 2026 alongside the public docs site.

Ready to integrate?

Public docs land Q3 2026. Until then, book a 30-minute tech review and we'll send sandbox credentials, schemas, and a Postman collection within the day.

Book a tech reviewRead the docsQ3 2026