curl --request POST \
--url https://app.microcrop.app/api/determinations/{determinationId}/settlement-report \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"partnerReference": "QK73HG9XYZ",
"settledAmountMinor": "1650000",
"settlementCurrency": "KES",
"settledAt": "2023-11-07T05:31:56Z",
"attestingOfficerName": "<string>",
"attestingOfficerTitle": "<string>",
"attestingOfficerEmail": "jsmith@example.com",
"shortfallReason": "<string>",
"declineReason": "<string>",
"evidenceRef": "<string>",
"evidenceHash": "<string>",
"notes": "<string>",
"supersedesReportId": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
'import requests
url = "https://app.microcrop.app/api/determinations/{determinationId}/settlement-report"
payload = {
"partnerReference": "QK73HG9XYZ",
"settledAmountMinor": "1650000",
"settlementCurrency": "KES",
"settledAt": "2023-11-07T05:31:56Z",
"attestingOfficerName": "<string>",
"attestingOfficerTitle": "<string>",
"attestingOfficerEmail": "jsmith@example.com",
"shortfallReason": "<string>",
"declineReason": "<string>",
"evidenceRef": "<string>",
"evidenceHash": "<string>",
"notes": "<string>",
"supersedesReportId": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
partnerReference: 'QK73HG9XYZ',
settledAmountMinor: '1650000',
settlementCurrency: 'KES',
settledAt: '2023-11-07T05:31:56Z',
attestingOfficerName: '<string>',
attestingOfficerTitle: '<string>',
attestingOfficerEmail: 'jsmith@example.com',
shortfallReason: '<string>',
declineReason: '<string>',
evidenceRef: '<string>',
evidenceHash: '<string>',
notes: '<string>',
supersedesReportId: '3c90c3cc-0d44-4b50-8888-8dd25736052a'
})
};
fetch('https://app.microcrop.app/api/determinations/{determinationId}/settlement-report', 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://app.microcrop.app/api/determinations/{determinationId}/settlement-report",
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([
'partnerReference' => 'QK73HG9XYZ',
'settledAmountMinor' => '1650000',
'settlementCurrency' => 'KES',
'settledAt' => '2023-11-07T05:31:56Z',
'attestingOfficerName' => '<string>',
'attestingOfficerTitle' => '<string>',
'attestingOfficerEmail' => 'jsmith@example.com',
'shortfallReason' => '<string>',
'declineReason' => '<string>',
'evidenceRef' => '<string>',
'evidenceHash' => '<string>',
'notes' => '<string>',
'supersedesReportId' => '3c90c3cc-0d44-4b50-8888-8dd25736052a'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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://app.microcrop.app/api/determinations/{determinationId}/settlement-report"
payload := strings.NewReader("{\n \"partnerReference\": \"QK73HG9XYZ\",\n \"settledAmountMinor\": \"1650000\",\n \"settlementCurrency\": \"KES\",\n \"settledAt\": \"2023-11-07T05:31:56Z\",\n \"attestingOfficerName\": \"<string>\",\n \"attestingOfficerTitle\": \"<string>\",\n \"attestingOfficerEmail\": \"jsmith@example.com\",\n \"shortfallReason\": \"<string>\",\n \"declineReason\": \"<string>\",\n \"evidenceRef\": \"<string>\",\n \"evidenceHash\": \"<string>\",\n \"notes\": \"<string>\",\n \"supersedesReportId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
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://app.microcrop.app/api/determinations/{determinationId}/settlement-report")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"partnerReference\": \"QK73HG9XYZ\",\n \"settledAmountMinor\": \"1650000\",\n \"settlementCurrency\": \"KES\",\n \"settledAt\": \"2023-11-07T05:31:56Z\",\n \"attestingOfficerName\": \"<string>\",\n \"attestingOfficerTitle\": \"<string>\",\n \"attestingOfficerEmail\": \"jsmith@example.com\",\n \"shortfallReason\": \"<string>\",\n \"declineReason\": \"<string>\",\n \"evidenceRef\": \"<string>\",\n \"evidenceHash\": \"<string>\",\n \"notes\": \"<string>\",\n \"supersedesReportId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.microcrop.app/api/determinations/{determinationId}/settlement-report")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"partnerReference\": \"QK73HG9XYZ\",\n \"settledAmountMinor\": \"1650000\",\n \"settlementCurrency\": \"KES\",\n \"settledAt\": \"2023-11-07T05:31:56Z\",\n \"attestingOfficerName\": \"<string>\",\n \"attestingOfficerTitle\": \"<string>\",\n \"attestingOfficerEmail\": \"jsmith@example.com\",\n \"shortfallReason\": \"<string>\",\n \"declineReason\": \"<string>\",\n \"evidenceRef\": \"<string>\",\n \"evidenceHash\": \"<string>\",\n \"notes\": \"<string>\",\n \"supersedesReportId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {}
}{
"success": true,
"data": {}
}{
"success": false,
"error": {
"code": "INVALID_INPUT",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"error": {
"code": "INVALID_INPUT",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"error": {
"code": "INVALID_INPUT",
"message": "<string>",
"details": "<unknown>"
}
}Report what you paid the farmer (DETERMINATION tier only)
Record YOUR statement of how you settled this determination off-platform, off your own balance sheet. MicroCrop stores and echoes the statement and NEVER verifies it: verificationStatus is structurally one-valued (UNVERIFIED) and every response restates verifiedByMicrocrop: false. Nothing here moves money — no Payout, no Transaction, no policy status change. Idempotent on (determinationId, partnerReference): resending a reference returns the stored report with replayed: true. Reports are append-only; a correction is a NEW report carrying supersedesReportId. There is no USDC field in either direction and no exchange rate is ever applied. Requires the settlement:report capability.
curl --request POST \
--url https://app.microcrop.app/api/determinations/{determinationId}/settlement-report \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"partnerReference": "QK73HG9XYZ",
"settledAmountMinor": "1650000",
"settlementCurrency": "KES",
"settledAt": "2023-11-07T05:31:56Z",
"attestingOfficerName": "<string>",
"attestingOfficerTitle": "<string>",
"attestingOfficerEmail": "jsmith@example.com",
"shortfallReason": "<string>",
"declineReason": "<string>",
"evidenceRef": "<string>",
"evidenceHash": "<string>",
"notes": "<string>",
"supersedesReportId": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
'import requests
url = "https://app.microcrop.app/api/determinations/{determinationId}/settlement-report"
payload = {
"partnerReference": "QK73HG9XYZ",
"settledAmountMinor": "1650000",
"settlementCurrency": "KES",
"settledAt": "2023-11-07T05:31:56Z",
"attestingOfficerName": "<string>",
"attestingOfficerTitle": "<string>",
"attestingOfficerEmail": "jsmith@example.com",
"shortfallReason": "<string>",
"declineReason": "<string>",
"evidenceRef": "<string>",
"evidenceHash": "<string>",
"notes": "<string>",
"supersedesReportId": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
partnerReference: 'QK73HG9XYZ',
settledAmountMinor: '1650000',
settlementCurrency: 'KES',
settledAt: '2023-11-07T05:31:56Z',
attestingOfficerName: '<string>',
attestingOfficerTitle: '<string>',
attestingOfficerEmail: 'jsmith@example.com',
shortfallReason: '<string>',
declineReason: '<string>',
evidenceRef: '<string>',
evidenceHash: '<string>',
notes: '<string>',
supersedesReportId: '3c90c3cc-0d44-4b50-8888-8dd25736052a'
})
};
fetch('https://app.microcrop.app/api/determinations/{determinationId}/settlement-report', 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://app.microcrop.app/api/determinations/{determinationId}/settlement-report",
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([
'partnerReference' => 'QK73HG9XYZ',
'settledAmountMinor' => '1650000',
'settlementCurrency' => 'KES',
'settledAt' => '2023-11-07T05:31:56Z',
'attestingOfficerName' => '<string>',
'attestingOfficerTitle' => '<string>',
'attestingOfficerEmail' => 'jsmith@example.com',
'shortfallReason' => '<string>',
'declineReason' => '<string>',
'evidenceRef' => '<string>',
'evidenceHash' => '<string>',
'notes' => '<string>',
'supersedesReportId' => '3c90c3cc-0d44-4b50-8888-8dd25736052a'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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://app.microcrop.app/api/determinations/{determinationId}/settlement-report"
payload := strings.NewReader("{\n \"partnerReference\": \"QK73HG9XYZ\",\n \"settledAmountMinor\": \"1650000\",\n \"settlementCurrency\": \"KES\",\n \"settledAt\": \"2023-11-07T05:31:56Z\",\n \"attestingOfficerName\": \"<string>\",\n \"attestingOfficerTitle\": \"<string>\",\n \"attestingOfficerEmail\": \"jsmith@example.com\",\n \"shortfallReason\": \"<string>\",\n \"declineReason\": \"<string>\",\n \"evidenceRef\": \"<string>\",\n \"evidenceHash\": \"<string>\",\n \"notes\": \"<string>\",\n \"supersedesReportId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
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://app.microcrop.app/api/determinations/{determinationId}/settlement-report")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"partnerReference\": \"QK73HG9XYZ\",\n \"settledAmountMinor\": \"1650000\",\n \"settlementCurrency\": \"KES\",\n \"settledAt\": \"2023-11-07T05:31:56Z\",\n \"attestingOfficerName\": \"<string>\",\n \"attestingOfficerTitle\": \"<string>\",\n \"attestingOfficerEmail\": \"jsmith@example.com\",\n \"shortfallReason\": \"<string>\",\n \"declineReason\": \"<string>\",\n \"evidenceRef\": \"<string>\",\n \"evidenceHash\": \"<string>\",\n \"notes\": \"<string>\",\n \"supersedesReportId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.microcrop.app/api/determinations/{determinationId}/settlement-report")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"partnerReference\": \"QK73HG9XYZ\",\n \"settledAmountMinor\": \"1650000\",\n \"settlementCurrency\": \"KES\",\n \"settledAt\": \"2023-11-07T05:31:56Z\",\n \"attestingOfficerName\": \"<string>\",\n \"attestingOfficerTitle\": \"<string>\",\n \"attestingOfficerEmail\": \"jsmith@example.com\",\n \"shortfallReason\": \"<string>\",\n \"declineReason\": \"<string>\",\n \"evidenceRef\": \"<string>\",\n \"evidenceHash\": \"<string>\",\n \"notes\": \"<string>\",\n \"supersedesReportId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {}
}{
"success": true,
"data": {}
}{
"success": false,
"error": {
"code": "INVALID_INPUT",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"error": {
"code": "INVALID_INPUT",
"message": "<string>",
"details": "<unknown>"
}
}{
"success": false,
"error": {
"code": "INVALID_INPUT",
"message": "<string>",
"details": "<unknown>"
}
}Authorizations
Path Parameters
Body
YOUR settlement reference — M-Pesa code, bank reference, receipt number. With the determination id this is the idempotency key, so it must be stable per payment: a fresh value per attempt posts two attestations that the same money moved once.
3 - 128"QK73HG9XYZ"
SETTLED_FULL, SETTLED_PARTIAL, DECLINED MOBILE_MONEY, BANK_TRANSFER, CASH, ACCOUNT_CREDIT, IN_KIND, OTHER Minor units of settlementCurrency as a canonical decimal STRING — no sign, no decimal point, no exponent, no leading zeros. Never a JSON number: this is an exact integer and a double loses precision at scale.
^(0|[1-9]\d*)$"1650000"
ISO 4217. Must equal the policy's own currency; a mismatch is a 400, never an FX conversion.
3"KES"
Cannot be in the future, and cannot precede the determination itself.
2 - 2002 - 200320Required when and only when outcome is SETTLED_PARTIAL.
2000Required when and only when outcome is DECLINED, which must also record settledAmountMinor "0".
2000A pointer to your own receipt. MicroCrop never fetches, resolves or validates it.
5121282000The live report this one corrects. Reports are append-only: the superseded row is stamped, never rewritten.