Settlements
A settlement moves money from your Monerail balance to your own bank or mobile money account, as saved for that currency by an Owner in the dashboard (Settings › Settlements).
/v1/settlementsCreate a settlementGET/v1/settlements/{id}Retrieve a settlementGET/v1/settlementsList settlementsThe settlement object
Attributes
Unique identifier (UUID).
true for live objects, false for test objects.
Always settlement.
succeeded and failed are final.
pendingprocessingsucceededfailedAmount sent to your settlement account, in minor units.
ISO 4217 currency code.
Monerail fee.
Your settlement account for this currency, as saved in the dashboard (same shape as on payouts: mobile_money or bank).
Always null for settlements.
Your own reference, as sent at creation.
Key-value pairs you attached at creation.
Why it failed, when status is failed or expired.
Detail from the payment partner, when available.
Creation time, ISO 8601 (UTC).
Last change, ISO 8601 (UTC).
{
"id": "575f3a4b-ccd5-4949-9c4d-158127ccccd1",
"object": "settlement",
"livemode": false,
"status": "pending",
"amount": 2500000,
"currency": "XAF",
"fee": 0,
"recipient": {
"type": "bank",
"name": "Acme SARL",
"bank_code": "10005",
"account": "••••0193",
"country": "CM"
},
"description": null,
"client_reference": null,
"metadata": {},
"failure_code": null,
"failure_message": null,
"created_at": "2026-10-30T13:47:06.394Z",
"updated_at": "2026-10-30T13:47:06.394Z"
}Create a settlement
The destination is always your saved settlement account: it cannot be changed through the API.
Key roles: Owner or Finance
Body
Amount in minor units of currency (whole francs for XAF, XOF and GNF; centimes for CDF, in multiples of 100). Integer only.
ISO 4217 code.
XAFXOFGNFCDFNGNKESGHSUGXTZSRWFReturns
Returns the new settlement object with 201, or 202 when the outcome is not final yet.
Errors worth handling
| HTTP | Code | Description |
|---|---|---|
400 | settlement_ | No settlement account saved for this currency. |
400 | settlement_ | The saved settlement account is not valid for the payment partner. |
402 | balance_ | Your balance (or cards balance) does not cover the amount and the fee. |
403 | permission_ | The key’s creator does not have the role required for this operation. |
429 | rate_ | A rate limit was reached. Wait for Retry-After seconds. See Rate limits. |
curl https://api.monerail.com/v1/settlements \
-H "Authorization: Bearer $MONERAIL_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45" \
-d '{
"amount": 2500000,
"currency": "XAF"
}'const res = await fetch('https://api.monerail.com/v1/settlements', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.MONERAIL_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45',
},
body: JSON.stringify({
amount: 2500000,
currency: 'XAF',
}),
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
console.log(data);import os
import requests
res = requests.post(
"https://api.monerail.com/v1/settlements",
headers={"Authorization": f"Bearer {os.environ['MONERAIL_KEY']}", "Idempotency-Key": "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45"},
json={
"amount": 2500000,
"currency": "XAF",
},
timeout=30,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
print(data)<?php
$ch = curl_init('https://api.monerail.com/v1/settlements');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('MONERAIL_KEY'),
'Content-Type: application/json',
'Idempotency-Key: a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45',
],
CURLOPT_POSTFIELDS => json_encode([
'amount' => 2500000,
'currency' => 'XAF',
]),
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException($data['error']['code'] . ': ' . $data['error']['message']);
}
print_r($data);package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
payload, err := json.Marshal(map[string]any{
"amount": 2500000,
"currency": "XAF",
})
if err != nil {
panic(err)
}
req, err := http.NewRequest(http.MethodPost, "https://api.monerail.com/v1/settlements", bytes.NewReader(payload))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("MONERAIL_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var data map[string]any
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(fmt.Sprint(data["error"]))
}
fmt.Println(data)
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
String body = """
{
"amount": 2500000,
"currency": "XAF"
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.monerail.com/v1/settlements"))
.header("Authorization", "Bearer " + System.getenv("MONERAIL_KEY"))
.header("Content-Type", "application/json")
.header("Idempotency-Key", "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
throw new RuntimeException(response.body());
}
System.out.println(response.body()); // parse with your JSON library (Jackson, Gson…)
}
}require "json"
require "net/http"
uri = URI("https://api.monerail.com/v1/settlements")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("MONERAIL_KEY")}"
req["Content-Type"] = "application/json"
req["Idempotency-Key"] = "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45"
req.body = JSON.generate({
amount: 2500000,
currency: "XAF",
})
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
raise "#{data["error"]["code"]}: #{data["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
puts datausing System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("MONERAIL_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.monerail.com/v1/settlements");
request.Headers.Add("Idempotency-Key", "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45");
request.Content = JsonContent.Create(new
{
amount = 2500000,
currency = "XAF",
});
using var response = await http.SendAsync(request);
var data = await response.Content.ReadFromJsonAsync<JsonElement>();
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(data.GetProperty("error").GetProperty("message").GetString());
}
Console.WriteLine(data);{
"id": "575f3a4b-ccd5-4949-9c4d-158127ccccd1",
"object": "settlement",
"livemode": false,
"status": "pending",
"amount": 2500000,
"currency": "XAF",
"fee": 0,
"recipient": {
"type": "bank",
"name": "Acme SARL",
"bank_code": "10005",
"account": "••••0193",
"country": "CM"
},
"description": null,
"client_reference": null,
"metadata": {},
"failure_code": null,
"failure_message": null,
"created_at": "2026-10-30T13:47:06.394Z",
"updated_at": "2026-10-30T13:47:06.394Z"
}Retrieve a settlement
Key roles: Every role
Path parameters
ID of the settlement.
Returns
Returns the settlement object.
curl https://api.monerail.com/v1/settlements/575f3a4b-ccd5-4949-9c4d-158127ccccd1 \
-H "Authorization: Bearer $MONERAIL_KEY"const res = await fetch('https://api.monerail.com/v1/settlements/575f3a4b-ccd5-4949-9c4d-158127ccccd1', {
headers: {
Authorization: `Bearer ${process.env.MONERAIL_KEY}`,
},
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
console.log(data);import os
import requests
res = requests.get(
"https://api.monerail.com/v1/settlements/575f3a4b-ccd5-4949-9c4d-158127ccccd1",
headers={"Authorization": f"Bearer {os.environ['MONERAIL_KEY']}"},
timeout=30,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
print(data)<?php
$ch = curl_init('https://api.monerail.com/v1/settlements/575f3a4b-ccd5-4949-9c4d-158127ccccd1');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('MONERAIL_KEY'),
],
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException($data['error']['code'] . ': ' . $data['error']['message']);
}
print_r($data);package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest(http.MethodGet, "https://api.monerail.com/v1/settlements/575f3a4b-ccd5-4949-9c4d-158127ccccd1", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("MONERAIL_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var data map[string]any
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(fmt.Sprint(data["error"]))
}
fmt.Println(data)
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.monerail.com/v1/settlements/575f3a4b-ccd5-4949-9c4d-158127ccccd1"))
.header("Authorization", "Bearer " + System.getenv("MONERAIL_KEY"))
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
throw new RuntimeException(response.body());
}
System.out.println(response.body()); // parse with your JSON library (Jackson, Gson…)
}
}require "json"
require "net/http"
uri = URI("https://api.monerail.com/v1/settlements/575f3a4b-ccd5-4949-9c4d-158127ccccd1")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("MONERAIL_KEY")}"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
raise "#{data["error"]["code"]}: #{data["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
puts datausing System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("MONERAIL_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.monerail.com/v1/settlements/575f3a4b-ccd5-4949-9c4d-158127ccccd1");
using var response = await http.SendAsync(request);
var data = await response.Content.ReadFromJsonAsync<JsonElement>();
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(data.GetProperty("error").GetProperty("message").GetString());
}
Console.WriteLine(data);{
"id": "575f3a4b-ccd5-4949-9c4d-158127ccccd1",
"object": "settlement",
"livemode": false,
"status": "succeeded",
"amount": 2500000,
"currency": "XAF",
"fee": 0,
"recipient": {
"type": "bank",
"name": "Acme SARL",
"bank_code": "10005",
"account": "••••0193",
"country": "CM"
},
"description": null,
"client_reference": null,
"metadata": {},
"failure_code": null,
"failure_message": null,
"created_at": "2026-10-30T13:47:06.394Z",
"updated_at": "2026-10-30T13:47:06.394Z"
}List settlements
Newest first.
Key roles: Every role
Query parameters
20Number of objects to return, 1 to 100.
Cursor: the ID of the last object of the previous page.
Returns
Returns a list object: data holds up to limit settlement objects, and has_more tells whether more follow.
curl "https://api.monerail.com/v1/settlements?limit=10" \
-H "Authorization: Bearer $MONERAIL_KEY"const res = await fetch('https://api.monerail.com/v1/settlements?limit=10', {
headers: {
Authorization: `Bearer ${process.env.MONERAIL_KEY}`,
},
});
const data = await res.json();
if (!res.ok) throw new Error(`${data.error.code}: ${data.error.message}`);
console.log(data);import os
import requests
res = requests.get(
"https://api.monerail.com/v1/settlements",
headers={"Authorization": f"Bearer {os.environ['MONERAIL_KEY']}"},
params={"limit": 10},
timeout=30,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
print(data)<?php
$ch = curl_init('https://api.monerail.com/v1/settlements?limit=10');
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('MONERAIL_KEY'),
],
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($status >= 400) {
throw new RuntimeException($data['error']['code'] . ': ' . $data['error']['message']);
}
print_r($data);package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest(http.MethodGet, "https://api.monerail.com/v1/settlements?limit=10", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("MONERAIL_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var data map[string]any
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
panic(err)
}
if res.StatusCode >= 400 {
panic(fmt.Sprint(data["error"]))
}
fmt.Println(data)
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.monerail.com/v1/settlements?limit=10"))
.header("Authorization", "Bearer " + System.getenv("MONERAIL_KEY"))
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
throw new RuntimeException(response.body());
}
System.out.println(response.body()); // parse with your JSON library (Jackson, Gson…)
}
}require "json"
require "net/http"
uri = URI("https://api.monerail.com/v1/settlements?limit=10")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("MONERAIL_KEY")}"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
raise "#{data["error"]["code"]}: #{data["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
puts datausing System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Text.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("MONERAIL_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Get, "https://api.monerail.com/v1/settlements?limit=10");
using var response = await http.SendAsync(request);
var data = await response.Content.ReadFromJsonAsync<JsonElement>();
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(data.GetProperty("error").GetProperty("message").GetString());
}
Console.WriteLine(data);{
"object": "list",
"url": "/v1/settlements",
"data": [
{
"id": "575f3a4b-ccd5-4949-9c4d-158127ccccd1",
"object": "settlement",
"livemode": false,
"status": "pending",
"amount": 2500000,
"currency": "XAF",
"fee": 0,
"recipient": {
"type": "bank",
"name": "Acme SARL",
"bank_code": "10005",
"account": "••••0193",
"country": "CM"
},
"description": null,
"client_reference": null,
"metadata": {},
"failure_code": null,
"failure_message": null,
"created_at": "2026-10-30T13:47:06.394Z",
"updated_at": "2026-10-30T13:47:06.394Z"
}
],
"has_more": false
}