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"
}
- Requests send
dateFormat+localeand every date string spelled in exactly that format. - Responses return dates as arrays:
[2026, 8, 19]is year, month, day. - Optional fields are omitted, not sent blank. An empty string where a date or number is optional is a validation error, not a no-op.
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"
}
]
}
400: validation; fix the named parameters.401: bad credentials;403: missing permission.404: the resource id does not exist on this tenant.422: a partner endpoint refused the request under a named rule.409/400domain rules: the body's globalisation code says which rule (e.g. a write-off on an inactive loan).
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