Beneficiaries
Saved recipients for your payouts, shared with the dashboard (Payouts › Beneficiaries). Test and live beneficiaries are separate, by the mode of the key. A destination (number or account) can be saved once per mode, and a business can keep up to 500 beneficiaries per mode. To pay one, create a payout with beneficiary.
/v1/beneficiariesCreate a beneficiaryGET/v1/beneficiaries/{id}Retrieve a beneficiaryPOST/v1/beneficiaries/{id}Update a beneficiaryGET/v1/beneficiariesList beneficiariesDELETE/v1/beneficiaries/{id}Delete a beneficiaryThe beneficiary object
Attributes
Unique identifier (UUID).
true for live objects, false for test objects.
Always beneficiary.
Mobile money wallet or bank account.
mobile_moneybankBeneficiary name, used as the recipient name of payouts.
Your own label, up to 40 characters.
ISO 3166-1 alpha-2 country code.
Currency of payouts to this beneficiary (the currency of the country).
Mobile money only: operator code.
Mobile money only: number in E.164 format.
Bank only: bank name.
Bank only: masked account number.
Time of the last payout created with this beneficiary.
Creation time, ISO 8601 (UTC).
Last change, ISO 8601 (UTC).
{
"id": "4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34",
"object": "beneficiary",
"livemode": false,
"type": "mobile_money",
"name": "Kossi Mensah",
"nickname": "Akwa supplier",
"country": "CM",
"currency": "XAF",
"operator": "MTN",
"phone": "+237670000777",
"bank_code": null,
"bank_name": null,
"account": null,
"last_used_at": null,
"created_at": "2026-10-30T13:47:06.394Z",
"updated_at": "2026-10-30T13:47:06.394Z"
}Create a beneficiary
Checks the details with the same rules as payouts (country open to payouts, operator of the country, international number, test numbers in test mode, exact bank code) and saves them. Nothing is sent to the recipient.
Key roles: Owner, Finance or Approver
Body
mobile_moneybankBeneficiary name, 2 to 80 characters.
ISO 3166-1 alpha-2 code of a country open to payouts.
ISO 4217 code. Defaults to the currency of the country.
Your own label, up to 40 characters.
Mobile money: number in international format (+237670000777).
Bank: account number, 6 to 34 letters or digits.
Returns
Returns the new beneficiary object with 201.
Errors worth handling
| HTTP | Code | Description |
|---|---|---|
400 | country_unsupported | This country is not open for this currency. See Coverage. |
400 | operator_unsupported | Unknown operator, or refused by the payment partner for this currency. |
400 | phone_invalid | The number cannot be read as an international number. |
400 | test_phone_required | Test mode: use one of the test phone numbers of this country. See Testing. |
400 | bank_account_invalid | bank_code does not exactly match a code from List banks, or the account number is too short. |
400 | bank_transfer_unsupported | Bank payouts are not available in this country: pay to a mobile money wallet. |
400 | limit_reached | A limit is reached: 10 webhook endpoints per business (test and live together), or 500 beneficiaries per mode. |
403 | permission_denied | The key’s creator does not have the role required for this operation. |
409 | beneficiary_exists | A beneficiary with this number or account already exists in this mode. |
curl https://api.monerail.com/v1/beneficiaries \
-H "Authorization: Bearer $MONERAIL_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "mobile_money",
"name": "Kossi Mensah",
"nickname": "Akwa supplier",
"country": "CM",
"phone": "+237670000777",
"operator": "MTN"
}'const res = await fetch('https://api.monerail.com/v1/beneficiaries', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.MONERAIL_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'mobile_money',
name: 'Kossi Mensah',
nickname: 'Akwa supplier',
country: 'CM',
phone: '+237670000777',
operator: 'MTN',
}),
});
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/beneficiaries",
headers={"Authorization": f"Bearer {os.environ['MONERAIL_KEY']}"},
json={
"type": "mobile_money",
"name": "Kossi Mensah",
"nickname": "Akwa supplier",
"country": "CM",
"phone": "+237670000777",
"operator": "MTN",
},
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/beneficiaries');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('MONERAIL_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'type' => 'mobile_money',
'name' => 'Kossi Mensah',
'nickname' => 'Akwa supplier',
'country' => 'CM',
'phone' => '+237670000777',
'operator' => 'MTN',
]),
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{
"type": "mobile_money",
"name": "Kossi Mensah",
"nickname": "Akwa supplier",
"country": "CM",
"phone": "+237670000777",
"operator": "MTN",
})
if err != nil {
panic(err)
}
req, err := http.NewRequest(http.MethodPost, "https://api.monerail.com/v1/beneficiaries", bytes.NewReader(payload))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("MONERAIL_KEY"))
req.Header.Set("Content-Type", "application/json")
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 = """
{
"type": "mobile_money",
"name": "Kossi Mensah",
"nickname": "Akwa supplier",
"country": "CM",
"phone": "+237670000777",
"operator": "MTN"
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.monerail.com/v1/beneficiaries"))
.header("Authorization", "Bearer " + System.getenv("MONERAIL_KEY"))
.header("Content-Type", "application/json")
.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/beneficiaries")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("MONERAIL_KEY")}"
req["Content-Type"] = "application/json"
req.body = JSON.generate({
type: "mobile_money",
name: "Kossi Mensah",
nickname: "Akwa supplier",
country: "CM",
phone: "+237670000777",
operator: "MTN",
})
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/beneficiaries");
request.Content = JsonContent.Create(new
{
type = "mobile_money",
name = "Kossi Mensah",
nickname = "Akwa supplier",
country = "CM",
phone = "+237670000777",
@operator = "MTN",
});
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": "4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34",
"object": "beneficiary",
"livemode": false,
"type": "mobile_money",
"name": "Kossi Mensah",
"nickname": "Akwa supplier",
"country": "CM",
"currency": "XAF",
"operator": "MTN",
"phone": "+237670000777",
"bank_code": null,
"bank_name": null,
"account": null,
"last_used_at": null,
"created_at": "2026-10-30T13:47:06.394Z",
"updated_at": "2026-10-30T13:47:06.394Z"
}Retrieve a beneficiary
Key roles: Owner, Finance, Approver or Developer
Path parameters
ID of the beneficiary.
Returns
Returns the beneficiary object.
Errors worth handling
| HTTP | Code | Description |
|---|---|---|
403 | permission_denied | The key’s creator does not have the role required for this operation. |
404 | resource_missing | No object with this ID in this mode. |
curl https://api.monerail.com/v1/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34 \
-H "Authorization: Bearer $MONERAIL_KEY"const res = await fetch('https://api.monerail.com/v1/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34', {
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/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34",
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/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34');
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/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34", 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/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34"))
.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/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34")
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/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34");
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": "4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34",
"object": "beneficiary",
"livemode": false,
"type": "mobile_money",
"name": "Kossi Mensah",
"nickname": "Akwa supplier",
"country": "CM",
"currency": "XAF",
"operator": "MTN",
"phone": "+237670000777",
"bank_code": null,
"bank_name": null,
"account": null,
"last_used_at": null,
"created_at": "2026-10-30T13:47:06.394Z",
"updated_at": "2026-10-30T13:47:06.394Z"
}Update a beneficiary
Changes the parameters you send; the others keep their value. type cannot change. Send nickname: null to remove the nickname. The same checks as at creation apply.
Key roles: Owner, Finance or Approver
Path parameters
ID of the beneficiary.
Body
2 to 80 characters.
Up to 40 characters, or null.
Returns
Returns the beneficiary object.
Errors worth handling
| HTTP | Code | Description |
|---|---|---|
400 | parameter_invalid | A parameter has the wrong type or value. See param. |
403 | permission_denied | The key’s creator does not have the role required for this operation. |
404 | resource_missing | No object with this ID in this mode. |
409 | beneficiary_exists | A beneficiary with this number or account already exists in this mode. |
curl https://api.monerail.com/v1/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34 \
-H "Authorization: Bearer $MONERAIL_KEY" \
-H "Content-Type: application/json" \
-d '{
"nickname": "Douala courier"
}'const res = await fetch('https://api.monerail.com/v1/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.MONERAIL_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
nickname: 'Douala courier',
}),
});
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/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34",
headers={"Authorization": f"Bearer {os.environ['MONERAIL_KEY']}"},
json={
"nickname": "Douala courier",
},
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/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('MONERAIL_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'nickname' => 'Douala courier',
]),
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{
"nickname": "Douala courier",
})
if err != nil {
panic(err)
}
req, err := http.NewRequest(http.MethodPost, "https://api.monerail.com/v1/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34", bytes.NewReader(payload))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("MONERAIL_KEY"))
req.Header.Set("Content-Type", "application/json")
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 = """
{
"nickname": "Douala courier"
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.monerail.com/v1/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34"))
.header("Authorization", "Bearer " + System.getenv("MONERAIL_KEY"))
.header("Content-Type", "application/json")
.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/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("MONERAIL_KEY")}"
req["Content-Type"] = "application/json"
req.body = JSON.generate({
nickname: "Douala courier",
})
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/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34");
request.Content = JsonContent.Create(new
{
nickname = "Douala courier",
});
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": "4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34",
"object": "beneficiary",
"livemode": false,
"type": "mobile_money",
"name": "Kossi Mensah",
"nickname": "Douala courier",
"country": "CM",
"currency": "XAF",
"operator": "MTN",
"phone": "+237670000777",
"bank_code": null,
"bank_name": null,
"account": null,
"last_used_at": null,
"created_at": "2026-10-30T13:47:06.394Z",
"updated_at": "2026-10-30T13:47:09.807Z"
}List beneficiaries
Newest first.
Key roles: Owner, Finance, Approver or Developer
Query parameters
20Number of objects to return, 1 to 100.
Cursor: the ID of the last object of the previous page.
Only this type.
mobile_moneybankOnly this country (ISO 3166-1 alpha-2).
Returns
Returns a list object: data holds up to limit beneficiary objects, and has_more tells whether more follow.
Errors worth handling
| HTTP | Code | Description |
|---|---|---|
403 | permission_denied | The key’s creator does not have the role required for this operation. |
curl "https://api.monerail.com/v1/beneficiaries?limit=10" \
-H "Authorization: Bearer $MONERAIL_KEY"const res = await fetch('https://api.monerail.com/v1/beneficiaries?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/beneficiaries",
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/beneficiaries?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/beneficiaries?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/beneficiaries?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/beneficiaries?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/beneficiaries?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/beneficiaries",
"data": [
{
"id": "4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34",
"object": "beneficiary",
"livemode": false,
"type": "mobile_money",
"name": "Kossi Mensah",
"nickname": "Akwa supplier",
"country": "CM",
"currency": "XAF",
"operator": "MTN",
"phone": "+237670000777",
"bank_code": null,
"bank_name": null,
"account": null,
"last_used_at": null,
"created_at": "2026-10-30T13:47:06.394Z",
"updated_at": "2026-10-30T13:47:06.394Z"
},
{
"id": "4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34",
"object": "beneficiary",
"livemode": false,
"type": "bank",
"name": "Kossi Mensah",
"nickname": null,
"country": "CM",
"currency": "XAF",
"operator": null,
"phone": null,
"bank_code": "10005",
"bank_name": "Example Bank",
"account": "••••4821",
"last_used_at": "2026-10-30T13:47:09.807Z",
"created_at": "2026-10-30T13:47:06.394Z",
"updated_at": "2026-10-30T13:47:06.394Z"
}
],
"has_more": false
}Delete a beneficiary
Removes the beneficiary from the list. Payouts already created are not affected.
Key roles: Owner, Finance or Approver
Path parameters
ID of the beneficiary.
Returns
Returns { id, object, deleted: true }.
Errors worth handling
| HTTP | Code | Description |
|---|---|---|
403 | permission_denied | The key’s creator does not have the role required for this operation. |
404 | resource_missing | No object with this ID in this mode. |
curl -X DELETE https://api.monerail.com/v1/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34 \
-H "Authorization: Bearer $MONERAIL_KEY"const res = await fetch('https://api.monerail.com/v1/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34', {
method: 'DELETE',
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.delete(
"https://api.monerail.com/v1/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34",
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/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
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.MethodDelete, "https://api.monerail.com/v1/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34", 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/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34"))
.header("Authorization", "Bearer " + System.getenv("MONERAIL_KEY"))
.DELETE()
.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/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34")
req = Net::HTTP::Delete.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.Delete, "https://api.monerail.com/v1/beneficiaries/4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34");
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": "4c2e9a17-6b3d-4f58-a0e1-8d7c5b2f9e34",
"object": "beneficiary",
"deleted": true
}