Developers

Build on the Credit Watch API

A REST and JSON API for the whole lending lifecycle: clients, loans, repayments, accounting and reports, with scoped tokens, safe retries and clear limits.

StyleREST + JSONVersioned under /api/v1
AuthOAuth 2 and tokensBearer tokens with scopes
Safe retriesIdempotency keysOn every money-moving call
Limits120 requests / minPer token, raised on request
On this page OverviewQuickstartAuthenticationScopesLoan lifecycleEndpoint referenceRequests and responsesIdempotencyRate limitsIntegration patternsEnvironments and go-liveSecurity and auditSupport

Overview

Everything your team does in the Credit Watch screens can be done through the API, so you can connect your own app, core banking system, payment channels or data warehouse to one ledger.

Base URLhttps://creditwatch.online/api/v1
FormatJSON requests and responses. Send Accept: application/json.
AuthenticationBearer token in the Authorization header.
Company dataEvery call runs as your company. A token can never read another company's records.
VersioningThe version is in the path. Breaking changes ship as a new version, and we tell you before anything you use changes.
ClientsCreate and update clients, identification, next of kin and files.
LoansApplications, approvals, disbursement, schedules, balances, restructures and write-offs.
RepaymentsRecord, view and reverse repayments, with the full transaction history.
AccountingChart of accounts, journal entries and financial statements.
ReportsPortfolio and performance reports as data.
Trade financeFacilities, invoices and drawdowns for trade-finance programmes.

Quickstart

From a new account to your first successful call in about five minutes.

  1. Create your companyStart a free trial, or ask us for a sandbox company so you can test without touching live data.
  2. Create a tokenIn Company Settings, open API Integrations and create a personal access token, or an OAuth client for a server-to-server integration. Choose only the scopes you need.
  3. Send your first requestPass the token as a bearer token and ask for JSON.
  4. Watch it happenThe API activity view shows each request, its status and any rate-limit hits.
# List active clients, 20 per page
curl "https://creditwatch.online/api/v1/client?status=active&limit=20" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json"
const res = await fetch("https://creditwatch.online/api/v1/client?status=active&limit=20", {
  headers: {
    Authorization: "Bearer YOUR_TOKEN",
    Accept: "application/json",
  },
});
const clients = await res.json();
console.log(clients);
<?php
$ch = curl_init("https://creditwatch.online/api/v1/client?status=active&limit=20");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer YOUR_TOKEN",
        "Accept: application/json",
    ],
]);
$clients = json_decode(curl_exec($ch), true);
curl_close($ch);
import requests

r = requests.get(
    "https://creditwatch.online/api/v1/client",
    params={"status": "active", "limit": 20},
    headers={"Authorization": "Bearer YOUR_TOKEN", "Accept": "application/json"},
)
print(r.json())

What comes back

200 OK · application/json
[
  {
    "current_page": 1,
    "per_page": 20,
    "total": 134,
    "data": [
      {
        "id": 482,
        "name": "Mary Banda",
        "gender": "female",
        "mobile": "260971234567",
        "email": "mary@example.com",
        "external_id": "CRM-10482",
        "status": "active",
        "branch": "Lusaka Main",
        "staff": "Joseph Mwale"
      }
    ]
  }
]

Authentication

Every request carries a bearer token. Tokens belong to your company, carry only the scopes you gave them, and can be revoked at any time.

Quickest

Personal access tokens

Created in Company Settings, API Integrations. Good for scripts, back-office tools and getting started.

  • Created and revoked by a company administrator
  • Scopes chosen when you create it
  • Shown once, so store it safely
Production

OAuth 2 clients

For server-to-server integrations and apps. Your system requests short-lived access tokens from the token endpoint.

  • Client ID and secret per integration
  • Token endpoint at /oauth/token
  • Tell us the grant type you prefer and we will enable it with you
Every request
Authorization: Bearer YOUR_TOKEN
Accept: application/json
Content-Type: application/json
Keep tokens on your server. Never put a token in a mobile app or in browser code. If one leaks, revoke it in API Integrations and create a new one.

Scopes

A token can only do what its scopes allow. Give each integration the smallest set that works.

ScopeWhat it allows
loans:readView loans, applications, schedules and balances
loans:writeCreate, approve, disburse and write off loans
repayments:readView repayments and transactions
repayments:writeRecord and reverse repayments
clients:readView clients
clients:writeCreate and update clients
accounting:readView the chart of accounts, journal entries and reports
accounting:writePost journal entries
reports:readRun reports
tradefinance:readView trade finance facilities, invoices and advances
tradefinance:writeSubmit invoices and request drawdowns
Some examples: a mobile app that shows balances needs loans:read and repayments:read. A payments reconciler needs repayments:write. A BI tool needs reports:read.

The loan lifecycle, as API calls

Most integrations follow this path. Each step is one call, and the loan is always in a known state.

1. ClientCreate the borrowerPOST /client/store
2. QuoteShow the schedulePOST /loan/calculator
3. LoanCreate the loanPOST /loan/store
4. ApproveCredit decisionPOST /loan/{id}/approve_loan
5. DisburseRelease fundsPOST /loan/{id}/disburse_loan
6. RepayPost paymentsPOST /loan/{id}/repayment/store

Create a client, then a loan

curl -X POST https://creditwatch.online/api/v1/client/store \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json" \
  -d first_name=Mary \
  -d last_name=Banda \
  -d gender=female \
  -d dob=1990-04-12 \
  -d branch_id=1 \
  -d created_date=2026-10-15 \
  -d mobile=260971234567
# Required fields include: client_id, loan_product_id, fund_id, loan_purpose_id,
# applied_amount, loan_term, repayment_frequency, repayment_frequency_type,
# interest_rate, expected_disbursement_date, loan_officer_id
curl -X POST https://creditwatch.online/api/v1/loan/store \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: 6f1c0d52-9b7e-4c1a-8d3e-5a2b7c9e1f40" \
  -d client_id=482 \
  -d loan_product_id=3 \
  -d applied_amount=5000 \
  -d loan_term=6 \
  -d repayment_frequency=1 \
  -d repayment_frequency_type=months \
  -d interest_rate=3 \
  -d expected_disbursement_date=2026-10-20
# Approve
curl -X POST https://creditwatch.online/api/v1/loan/910/approve_loan \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Idempotency-Key: a31b6c10-2d8f-4f0e-9a64-7d5c3e8b1a22"

# Disburse
curl -X POST https://creditwatch.online/api/v1/loan/910/disburse_loan \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Idempotency-Key: 0c9d4e77-61aa-43b8-b2f1-9e3a5d7c4b10"

Record a repayment

curl -X POST https://creditwatch.online/api/v1/loan/910/repayment/store \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: mobile-money-TX88213" \
  -d amount=1250.00 \
  -d date=2026-11-05 \
  -d payment_type_id=2 \
  -d receipt=TX88213
await fetch("https://creditwatch.online/api/v1/loan/910/repayment/store", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_TOKEN",
    Accept: "application/json",
    "Idempotency-Key": "mobile-money-TX88213",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ amount: 1250.0, date: "2026-11-05", payment_type_id: 2, receipt: "TX88213" }),
});
import requests

requests.post(
    "https://creditwatch.online/api/v1/loan/910/repayment/store",
    headers={
        "Authorization": "Bearer YOUR_TOKEN",
        "Accept": "application/json",
        "Idempotency-Key": "mobile-money-TX88213",
    },
    json={"amount": 1250.0, "date": "2026-11-05", "payment_type_id": 2, "receipt": "TX88213"},
)

Endpoint reference

The calls most integrations use, grouped by area. Paths are relative to /api/v1. The full reference, including every field, is shared with your team when you get access.

ClientsCreate and maintain borrowers, with identification, next of kin and documents. 8 endpoints
Scopes: clients:read, clients:write
GET/clientList clients. Filter with status and branch_id, page with limit.
GET/client/{id}/showOne client with their details.
POST/client/storeCreate a client.
POST/client/{id}/updateUpdate a client.
POST/client/{id}/change_statusActivate, deactivate or otherwise change a client's status.
POST/client/{id}/client_identification/storeAdd an ID document to a client.
POST/client/{id}/client_next_of_kin/storeAdd next of kin.
POST/client/{id}/file/storeAttach a document or file.
LoansThe whole loan lifecycle: calculate, apply, approve, disburse, service and close. 12 endpoints
Scopes: loans:read, loans:write
GET/loanList loans.
GET/loan/{id}/showOne loan with its terms, status and balances.
POST/loan/calculatorWork out a repayment schedule without creating a loan.
POST/loan/storeCreate a loan. Supports Idempotency-Key.
POST/loan/{id}/approve_loanApprove a loan. Supports Idempotency-Key.
POST/loan/{id}/reject_loanReject a loan.
POST/loan/{id}/disburse_loanDisburse an approved loan. Supports Idempotency-Key.
GET/loan/{id}/schedule/showThe repayment schedule.
POST/loan/{id}/charge/storeAdd a charge to a loan. Supports Idempotency-Key.
POST/loan/{id}/waive_interestWaive interest. Supports Idempotency-Key.
POST/loan/{id}/write_off_loanWrite a loan off. Supports Idempotency-Key.
POST/loan/{id}/change_loan_officerReassign the loan officer.
Loan applicationsTake applications from your own app, website or channel and let your credit team decide. 2 endpoints
Scopes: loans:write
POST/loan-applicationsSubmit an application. Supports Idempotency-Key.
GET/loan-applications/{id}Check the status of an application.
RepaymentsPost and reverse repayments, with a full transaction history. 3 endpoints
Scopes: repayments:read, repayments:write
POST/loan/{id}/repayment/storeRecord a repayment (amount, date, payment_type_id). Supports Idempotency-Key.
POST/loan/repayment/{id}/updateCorrect a repayment. Supports Idempotency-Key.
GET/loan/repayment/{id}/reverseReverse a repayment.
Bulk migrationBring existing loans across from a legacy system, one at a time or in batches. 2 endpoints
Scopes: loans:write
POST/loan-migrationsImport one loan with its history. Supports Idempotency-Key.
POST/loan-migrations/batchImport many loans in one request. Supports Idempotency-Key.
Loan productsRead and manage the products your customers can borrow. 4 endpoints
Scopes: loans:read, loans:write
GET/loan/productList loan products.
GET/loan/product/{id}/showOne product with its limits and rules.
POST/loan/product/storeCreate a product.
POST/loan/product/{id}/updateUpdate a product.
AccountingChart of accounts, journals and the financial statements. 8 endpoints
Scopes: accounting:read, accounting:write
GET/accounting/chart_of_accountThe chart of accounts.
GET/accounting/journal_entryList journal entries.
POST/accounting/journal_entry/storePost a journal entry. Supports Idempotency-Key.
GET/accounting/trial_balanceTrial balance.
GET/accounting/ledgerGeneral ledger.
GET/accounting/balance_sheetBalance sheet.
GET/accounting/income_statementIncome statement.
GET/accounting/cash_flowCash flow.
ReportsPortfolio and collections data for your own dashboards and warehouse. 6 endpoints
Scopes: reports:read
GET/report/loan/arrearsLoans in arrears.
GET/report/loan/portfolio_at_riskPortfolio at risk.
GET/report/loan/collection_sheetCollection sheet.
GET/report/loan/repaymentRepayments in a period.
GET/report/loan/expected_repaymentRepayments expected in a period.
GET/report/loan/disbursementDisbursements in a period.
Trade financeFacilities, invoices and advances for trade-finance programmes. 6 endpoints
Scopes: tradefinance:read, tradefinance:write
GET/trade-finance/facilitiesList facilities.
GET/trade-finance/facilities/{id}One facility with its limits.
POST/trade-finance/facilities/{id}/invoicesSubmit an invoice against a facility.
POST/trade-finance/facilities/{id}/advancesRequest an advance.
GET/trade-finance/invoicesList invoices.
GET/trade-finance/advances/{id}One advance.
Branches, messaging and reference dataSupporting resources you will need around the core lending calls. 5 endpoints
Scopes: by area
GET/branchList branches.
GET/currencyCurrencies.
GET/payment_typePayment types, for repayments and disbursements.
GET/communication/campaignMessaging campaigns.
GET/communication/logMessages sent.

Requests and responses

Predictable conventions, so your client code stays small.

Pagination

List calls return a page of results. Ask for a page size with limit (default 20) and move through pages with page. The response includes current_page, per_page and total.

Filtering

List calls accept filters such as status and branch_id. Dates use YYYY-MM-DD.

Status codes

CodeMeaning
200The request worked.
400Validation failed. The body lists each field that needs fixing.
401The token is missing, expired or revoked.
403The token does not have the scope, or the user may not do this.
404That record does not exist in your company.
409A request with the same Idempotency-Key is still running.
429You are over the rate limit. Wait for the time in Retry-After.

Validation errors

400 Bad Request
{
  "success": false,
  "errors": {
    "amount": ["The amount field is required."],
    "payment_type_id": ["The payment type id field is required."]
  }
}

Idempotency

Networks fail. When a request that moves money times out, you need to retry without paying someone twice. Add an Idempotency-Key header and we make sure the action runs once.

  • First request with a key runs normally, and its response is stored for 24 hours.
  • A retry with the same key gets the stored response back. The action does not run again.
  • A retry while the first is still running returns 409, so you know to wait and try again.
  • Failed requests are not stored, so you can correct them and retry freely.
  • Choose a key you can rebuild, such as a payment reference or a UUID you saved before sending. Keys are scoped to your token.
The header is optional, but we strongly recommend it on every call marked Supports Idempotency-Key in the reference: creating loans, approving, disbursing, recording repayments, charges, write-offs and journal entries.

Rate limits

Limits keep the platform fast for everyone. The default is 120 requests per minute for each token, and we can raise it for busy integrations.

Response headers
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117

# when you go over
HTTP/1.1 429 Too Many Requests
Retry-After: 23
{ "message": "Too many requests. Slow down." }

Read X-RateLimit-Remaining to pace yourself, and on a 429 wait for Retry-After seconds before you try again. For bulk loads, use the batch migration endpoint instead of many single calls.

Integration patterns

Common ways teams use the API, and where we help.

Channels

Your own app or USSD front end

Quote with the calculator, submit an application, then show status and schedules. Your app owns the experience, Credit Watch owns the loan.

Payments

Repayment reconciliation

Post each mobile-money or bank payment as a repayment using the provider reference as the Idempotency-Key, so duplicates are harmless.

Core systems

Core banking and ERP sync

Push journal entries to your ledger and pull trial balance and statements on a schedule.

Data

BI and data warehouse

Pull arrears, portfolio-at-risk, disbursement and repayment reports into your analytics tools each night.

Migration

Moving off a legacy system

Import open loans and history with the batch migration endpoint, then reconcile balances with our team.

Events

Callbacks and notifications

Payment providers call back into the platform to confirm repayments. For events to your own systems, we set up notifications with you during implementation.

Environments and go-live

Test safely first, then switch to production with a short checklist.

Test

Sandbox company

Ask us for a sandbox company with sample products and clients. Your tokens and data there are separate from production.

Live

Production

Create production tokens in your live company, with narrower scopes than you used while building.

Go-live checklist

  • Tokens stored on your server, one per integration, with the smallest scopes.
  • Idempotency-Key on every money-moving call, built from something you can rebuild after a crash.
  • 429 and 5xx handling with a wait and retry, not a tight loop.
  • Balances reconciled between your system and Credit Watch on a sample of loans.
  • Someone watching the API activity view for the first days.

Security and audit

What your risk and security teams will ask about.

Encrypted in transitAll API traffic uses HTTPS.
Scoped, revocable tokensEach token carries only the scopes you chose, and an administrator can revoke it instantly.
Your company's data onlyCalls are tied to your company, so a token never sees another company's records.
Audit trailChanges made through the API are recorded in the activity log, with the person or token behind them.
Rate limitingPer-token limits protect your account and the platform. Every request is visible in API activity.
Data portabilityExport your data whenever you need it, so you are never locked in. See Security.

Support for your engineers

Talk to people who know the platform and the lending behind it.

  • Implementation help. We walk through your first integration with your engineers and credit team.
  • Fast answers. Raise a ticket from the support pop-up and we respond with someone who can read your request logs.
  • Limits and access. Ask for a sandbox, higher rate limits or the full field-level reference.

Ready to build?

Create an account, make your first call today, and tell us what you want to build.

Get started for free Talk to our team
Or call us on +260 953 436 602