API Get API credentialsGet access

Conventions

Rules that hold across every endpoint in the Reference. Read once. The per-endpoint pages assume all of this.

Base URL & tenant

All paths hang off https://default.lokta.tech/lokta-lms/api/v1. The platform is multi-tenant: every request names its tenant with the Tenant-Identifier header (this instance's default tenant is default). A missing or wrong tenant header fails the request before authentication is even considered.

Authentication

HTTP Basic with an application user's credentials, on every request. There is no session or token handshake to keep alive.

curl 'https://default.lokta.tech/lokta-lms/api/v1/loans' \
  -u '{username}:{password}' \
  -H 'Tenant-Identifier: default'

What a user may call is governed by their roles' permissions (see Roles & Permissions in the reference); a valid login without the right permission gets a 403 with the missing permission named in the error body.

Dates & locale

The write contract is explicit about how it should be read: every body that carries a date also carries the format that date is written in.

{
  "locale": "en",
  "dateFormat": "dd MMMM yyyy",
  "expectedDisbursementDate": "19 August 2026"
}

Commands

State changes are commands, not bare updates: POST to the resource with a ?command= query parameter. The same URL performs different transitions depending on the command.

POST /v1/loans/{loanId}?command=approve
POST /v1/loans/{loanId}?command=disburse
POST /v1/loans/{loanId}/transactions?command=repayment
POST /v1/loans/{loanId}/transactions/{transactionId}?command=undowriteoff

Command bodies follow the date convention above; the response echoes the affected ids (resourceId, sometimes subResourceId and a changes map).

Pagination & sorting

List endpoints take offset and limit (plus orderBy / sortOrder where the reference shows them). Paged responses wrap results as:

{ "totalFilteredRecords": 240, "pageItems": [ … ] }

Endpoints without those parameters return the full list. Field filtering with ?fields=a,b,c trims response payloads.

Errors

Failures return a consistent envelope. The outer message summarises; the errors array names each offending parameter with a stable globalisation code you can key translations or handling off.

{
  "developerMessage": "The request was invalid…",
  "httpStatusCode": "400",
  "defaultUserMessage": "Validation errors exist.",
  "userMessageGlobalisationCode": "validation.msg.validation.errors.exist",
  "errors": [
    {
      "developerMessage": "The parameter `dueDate` is mandatory.",
      "defaultUserMessage": "The parameter `dueDate` is mandatory.",
      "userMessageGlobalisationCode": "validation.msg.loancharge.dueDate.cannot.be.blank",
      "parameterName": "dueDate"
    }
  ]
}

Idempotency

Some endpoints list an Idempotency-Key header in the reference. Send one on each of them. Four say they require it: creating a partner, revising a partner's terms, running fees and approving a draft invoice. On creating a partner and revising terms, reusing a key with a different body returns 409.

For any other write, read the resource back before you retry a request that may have been applied. The errors guide covers what to do for each status code.

This is the API reference for Lokta, the agentic loan servicing platform. Go to lokta.ai