Lender API integration

UMRA Digital Lending Supervision · API v1

Lender-scoped accessJSON over HTTPSServer-to-server only

1. Obtain access

Sign in with your company’s lender account. UMRA must link the account to your company before a key can be issued.

2. Connect your system

Create a key below. Store it in your server’s secret store and send it in the X-API-Key header; never expose it in an app or browser.

3. Test, then go live

Read case status or products first. Response submissions change real records in this preview. Use the published site address for production after deployment.

Company API keys

The guide is available to everyone. Only a signed-in lender account can create and revoke its own keys. UMRA staff cannot issue keys for another company here.

Available endpoints

GET/api/public/lender/cases

Case status

Your referred cases: reference, category, urgency, status and response deadline. No borrower identities or complaint text.

GET/api/public/lender/products

Declared products

Your active products, declared rates, fees, repayment periods and legal assessments.

POST/api/public/lender/responses

Submit a response

Respond to a case with status with_lender. UMRA reviews the response; it does not automatically resolve the case.

Reads return the latest 100 records without pagination. Declare or update rates and fees in the lender portal; product writes, webhooks and automatic synchronisation are not available in this version.

Try a request

Integration example

Current base URL: Loading…

This app is not published yet. The tester uses the current site; do not use a preview address for production.

curl -X GET '/api/public/lender/cases' \
  -H 'X-API-Key: YOUR_LENDER_API_KEY'

Response and error handling

200
Read successful; JSON includes cases or products.
201
Response saved; status is lender_responded.
400
Invalid JSON, fields or unsupported query parameters.
401/403
Missing, revoked key or withdrawn lender access.
404
Case not found for your company.
409
Case cannot accept a response. Read its status before retrying.
429
Request limit reached. Wait one minute.
503
Service unavailable. Retry reads with backoff.

Send one request at a time and avoid blind retries of POST requests. Revoke exposed keys immediately. Do not send borrower phone numbers or identities in response text.

Authentication errors and fixes

These are example responses from the lender API. A portal sign-in session does not replace X-API-Key. Fix the credentials or access before retrying a 401 or 403.

HTTP 401Missing or incorrectly formatted key

The X-API-Key header is absent, empty or malformed. Sending only Authorization: Bearer does not authenticate a lender API request.

HTTP 401
{
  "error": "A valid X-API-Key is required."
}

How to resolve

  1. Send the company key in X-API-Key, without a Bearer prefix, quotes or surrounding whitespace.
  2. Use the full issued key: dls_ followed by 64 lowercase hexadecimal characters. A key ID, account password or webhook signing secret is not an API key.
  3. Check that LENDER_API_KEY is set in your server environment and that your proxy forwards X-API-Key.

HTTP 401Unknown, rotated or revoked key

The key has the correct format but does not match an active credential. Rotating a key immediately invalidates the old one; revoked keys cannot be restored.

HTTP 401
{
  "error": "Invalid or revoked API key."
}

How to resolve

  1. Check Company API keys above and the credential audit history for recent rotation or revocation.
  2. After rotation, replace the old key in every service’s secret store with the one-time replacement and reload the affected services.
  3. If the active key was lost, rotate it; if it was revoked, create a new key. Revoke any exposed key immediately.

HTTP 403Lender access is no longer authorised

The key exists, but the account that created it no longer has lender access linked to that company.

HTTP 403
{
  "error": "Lender access is no longer authorised."
}

How to resolve

  1. Ask UMRA to verify the issuing account’s lender role and company association.
  2. Once authorised access is restored, use a key issued by an authorised account for your company.
  3. Do not retry repeatedly or use another company’s credentials to bypass the restriction.

Verify authentication with a read-only request

Expected result: HTTP 200 with a cases array, which may be empty. This check does not submit a response or change a case. Never share keys in screenshots, logs or support messages.

# Run on your server with LENDER_API_KEY supplied by your secret store.
# Stop if the environment variable is missing; never print the key.
: "${LENDER_API_KEY:?Set LENDER_API_KEY in your server environment}"
curl --silent --show-error --include \
  'https://YOUR-SITE-DOMAIN/api/public/lender/cases' \
  --header "X-API-Key: ${LENDER_API_KEY}"

A 404 “Case not found” is not an authentication error: confirm the case belongs to your company. A webhook receiver’s 401 is separate: verify X-Webhook-Signature using UMRA_WEBHOOK_SECRET and the exact raw body, not your API key. See the receiver examples below.

Copy-and-paste code samples

Samples follow the endpoint selected in “Try a request” above and read the key from a LENDER_API_KEY environment variable — never hard-code it. Replace YOUR_LENDER_API_KEY with your company key when testing.

curl 'https://YOUR-SITE-DOMAIN/api/public/lender/cases' \
  -H 'X-API-Key: YOUR_LENDER_API_KEY'

Event notifications (webhooks)

When UMRA refers a case to your company, or a case you were involved in changes status, UMRA POSTs a signed JSON notification to every active endpoint you register here. Each event is delivered once; if your endpoint is unreachable, read GET /api/public/lender/cases to reconcile. Never expose the signing secret outside your server.

Delivery format

  • POST with Content-Type: application/json and the payload shown on the right.
  • Headers: X-UMRA-Event (event name), X-UMRA-Delivery (unique delivery id) and X-Webhook-Signature: sha256=<hex> — an HMAC-SHA256 of the raw body using your endpoint secret.
  • Always verify the signature against the raw bytes of the request before trusting the payload.
  • Reply 2xx within 5 seconds. Notifications carry metadata only — no borrower identities or complaint text.

Sample payload

{
  "event": "case.assigned",
  "created_at": "2026-10-22T07:46:00.000Z",
  "data": {
    "reference": "UMRA-2026-0142",
    "category": "contact_list_shaming",
    "urgency": "high",
    "status": "with_lender",
    "due_at": "2026-11-05T09:00:00.000Z"
  }
}

Events

case.assigned
A case has been referred to your company; includes the reference, category, urgency and response deadline.
case.status_changed
A case you were involved in changed status (resolved, closed or under investigation).
ping
Test delivery sent when you verify an endpoint from this page.

Sign in with a lender account to register your company's webhook endpoints. UMRA staff cannot register an endpoint on a company's behalf.

Receiver code samples

Copy a ready-made receiver that verifies the signature and handles both case events. Store the endpoint secret in a UMRA_WEBHOOK_SECRET environment variable — never in code.

import crypto from "node:crypto";
import express from "express";

const app = express();
const SECRET = process.env.UMRA_WEBHOOK_SECRET;

// Capture the raw body: the signature covers the exact bytes UMRA sent.
app.post("/umra/webhook", express.json({ verify: (req, res, buf) => { req.rawBody = buf; } }), (req, res) => {
  const expected = "sha256=" + crypto.createHmac("sha256", SECRET).update(req.rawBody).digest("hex");
  if (req.get("X-Webhook-Signature") !== expected) return res.status(401).end();

  const { event, data } = req.body;
  if (event === "case.assigned") console.log("New case assigned:", data.reference, "due", data.due_at);
  else if (event === "case.status_changed") console.log("Case", data.reference, "is now", data.status);

  res.status(200).end(); // Answer within 5 seconds; do slower work afterwards.
});

app.listen(3000, () => console.log("Webhook receiver listening on :3000"));