Adjust disbursement date
curl --request POST \
--url https://api.dev.bsa.ai/v1/loans/external/{loan_external_id}/adjust-disbursement-date \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"actualDisbursementDate": "<string>",
"note": "<string>"
}
'import requests
url = "https://api.dev.bsa.ai/v1/loans/external/{loan_external_id}/adjust-disbursement-date"
payload = {
"actualDisbursementDate": "<string>",
"note": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({actualDisbursementDate: '<string>', note: '<string>'})
};
fetch('https://api.dev.bsa.ai/v1/loans/external/{loan_external_id}/adjust-disbursement-date', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.dev.bsa.ai/v1/loans/external/{loan_external_id}/adjust-disbursement-date",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'actualDisbursementDate' => '<string>',
'note' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.dev.bsa.ai/v1/loans/external/{loan_external_id}/adjust-disbursement-date"
payload := strings.NewReader("{\n \"actualDisbursementDate\": \"<string>\",\n \"note\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.dev.bsa.ai/v1/loans/external/{loan_external_id}/adjust-disbursement-date")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"actualDisbursementDate\": \"<string>\",\n \"note\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.dev.bsa.ai/v1/loans/external/{loan_external_id}/adjust-disbursement-date")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"actualDisbursementDate\": \"<string>\",\n \"note\": \"<string>\"\n}"
response = http.request(request)
puts response.read_bodyLoans
Adjust disbursement date
Shift an active loan’s disbursal date when the partner-side wallet credit landed later than the LMS recorded.
POST
/
v1
/
loans
/
external
/
{loan_external_id}
/
adjust-disbursement-date
Adjust disbursement date
curl --request POST \
--url https://api.dev.bsa.ai/v1/loans/external/{loan_external_id}/adjust-disbursement-date \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"actualDisbursementDate": "<string>",
"note": "<string>"
}
'import requests
url = "https://api.dev.bsa.ai/v1/loans/external/{loan_external_id}/adjust-disbursement-date"
payload = {
"actualDisbursementDate": "<string>",
"note": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({actualDisbursementDate: '<string>', note: '<string>'})
};
fetch('https://api.dev.bsa.ai/v1/loans/external/{loan_external_id}/adjust-disbursement-date', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.dev.bsa.ai/v1/loans/external/{loan_external_id}/adjust-disbursement-date",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'actualDisbursementDate' => '<string>',
'note' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.dev.bsa.ai/v1/loans/external/{loan_external_id}/adjust-disbursement-date"
payload := strings.NewReader("{\n \"actualDisbursementDate\": \"<string>\",\n \"note\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.dev.bsa.ai/v1/loans/external/{loan_external_id}/adjust-disbursement-date")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"actualDisbursementDate\": \"<string>\",\n \"note\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.dev.bsa.ai/v1/loans/external/{loan_external_id}/adjust-disbursement-date")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"actualDisbursementDate\": \"<string>\",\n \"note\": \"<string>\"\n}"
response = http.request(request)
puts response.read_bodyShifts the effective disbursal date on an
Active loan. Use this when
the partner’s wallet credit was delayed (e.g. pending → confirmed two
days later) and the LMS-recorded disbursement date no longer matches
the day the customer actually received the money.
Interest re-accrues from the new date, and the
repaymentSchedule is recalculated so the next
due-date math matches reality.
A loan with recorded repayments is rejected with
409 aborted.
The adjustment reverses and re-books the disbursement, which would
cascade-reverse any repayments — so erasing them must be an explicit
choice. Reverse the repayment(s) first, then
adjust.Date constraints
- The new date must not be in the future — pass today or any past day.
- The new date must not be before the loan’s approval date. Because
POST /v1/loansapproves on the same day it disburses, the new date must be on or after the original disbursement date.
Path parameters
string
required
The loan’s externalId. On the
/v1/loans/{loan_id}/adjust-disbursement-date
form, this is the numeric LMS id instead.Request body
string
required
ISO-8601
YYYY-MM-DD. The corrected disbursal date.string
Optional. Reason for the adjustment, captured in the LMS audit log.
Examples
# By loan externalId (recommended)
curl -sf -X POST "$BASE/v1/loans/external/loan-ext-12345/adjust-disbursement-date" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"actualDisbursementDate": "2026-05-30",
"note": "Wallet credit confirmed 2 days after original disbursement"
}'
# Same effect, by LMS id
curl -sf -X POST "$BASE/v1/loans/501/adjust-disbursement-date" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"actualDisbursementDate": "2026-05-30"}'
Response
200 OK returns the loan object with the new
disbursal date, recomputed schedule, and adjusted next-due fields.
How it works
The wrapper performsundo-disbursal then re-disburse against the
LMS with the corrected date. These are two separate LMS commands, so
the wrapper makes them atomic from the partner’s point of view: it
records the current disbursement date first, and if re-disbursing at the
new date fails it automatically rolls the loan back to the original
date. Either the adjustment succeeds (loan Active, new schedule), or
it fails cleanly with the loan left in its original Active state — the
loan is never stranded in Approved.
The only exception is the rare case where the re-disbursal and the
automatic rollback both fail; the response is then a 500 whose message
states the loan is in Approved and names the original date to
re-disburse manually.
Errors
| Code | When |
|---|---|
not_found | No loan with that id or externalId |
failed_precondition | The loan has no disbursement to adjust (not yet disbursed) |
aborted | The loan has recorded repayments — reverse them before adjusting the date |
invalid_argument | actualDisbursementDate missing, not ISO YYYY-MM-DD, in the future, or before the loan’s approval date |
permission_denied | Date in the future, or date before the loan’s approval date |
internal | Re-disbursal failed and automatic rollback also failed — loan is in Approved and needs manual re-disbursal (message names the original date) |

