Titulaires
Un titulaire est la personne à qui une carte est émise : un membre de votre équipe ou l’un de vos clients. L’émetteur vérifie son identité avant toute émission.
Un titulaire est la personne à qui une carte est émise : un membre de votre équipe ou l’un de vos clients. L’émetteur vérifie son identité avant toute émission.
/v1/cardholdersCréer un titulairePOST/v1/cardholders/{id}/verificationEnvoyer la vérification d’identitéGET/v1/cardholders/{id}Consulter un titulaireGET/v1/cardholdersLister les titulairesL’objet titulaire
Attributs
Identifiant unique (UUID).
true en production, false en mode test.
Toujours cardholder.
team pour votre équipe, customer pour vos clients.
teamcustomerFormat international.
ISO 3166-1 alpha-2.
AAAA-MM-JJ.
Type de pièce d’identité.
national_idpassportdriver_licensevoters_card4 derniers caractères du numéro de pièce. Le numéro complet n’est jamais renvoyé.
Vérification d’identité par l’émetteur. Une carte ne peut être émise qu’une fois status à verified.
Voir les attributs
pendingin_reviewverifiedrejectedMotif du refus.
Date de vérification.
true si les photos de la pièce envoyées à la création sont enregistrées : la vérification peut être envoyée sans les renvoyer.
Date de création, ISO 8601 (UTC).
Dernière modification, ISO 8601 (UTC).
{
"id": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"object": "cardholder",
"livemode": false,
"type": "customer",
"first_name": "Awa",
"last_name": "Ndiaye",
"email": "awa@example.com",
"phone": "+237670000999",
"country": "CM",
"city": "Douala",
"birth_date": "1991-02-03",
"id_document": "national_id",
"id_number_last4": "3408",
"verification": {
"status": "pending",
"reason": null,
"verified_at": null,
"documents_on_file": true
},
"created_at": "2026-10-30T13:47:06.394Z",
"updated_at": "2026-10-30T13:47:06.394Z"
}Créer un titulaire
Crée le titulaire avec verification.status à pending. La photo de la pièce d’identité est obligatoire (documents) : elle est contrôlée avant toute création et reprise par la vérification d’identité. Envoyez ensuite la vérification d’identité.
Rôles de la clé : Propriétaire ou Finance
Corps
Exactement comme sur la pièce d’identité. 1 à 50 caractères : lettres (accents acceptés), espaces, apostrophes, points et traits d’union.
Mêmes règles que first_name.
Adresse valide, 200 caractères au plus. Unique pour votre entreprise.
Pays de résidence, ISO 3166-1 alpha-2, parmi : CM, GA, TD, CG, CF, CD, CI, SN, BJ, TG, BF, ML, NE, GN, NG, GH, KE, UG, TZ, RW, ZM, ZA. Sinon country_unsupported.
teamteamcustomerNuméro mobile au format international E.164 (+237670000999). Un numéro national prend l’indicatif de country. La partie nationale doit avoir la longueur en usage dans ce pays, sinon phone_invalid. Renvoyé normalisé.
AAAA-MM-JJ, date réelle, exactement comme sur la pièce. Le titulaire doit avoir au moins 18 ans (cardholder_underage).
national_idPièce utilisée pour la vérification. Au Ghana, national_id désigne la Ghana Card. Un passeport ne demande que la page avec la photo ; les autres pièces, le recto et le verso.
national_idpassportdriver_licensevoters_cardNuméro de la pièce, tel qu’imprimé (mis en majuscules). Passeport : 6 à 9 lettres ou chiffres, sans espace. Autres pièces : 4 à 30 caractères parmi lettres, chiffres, espaces, / et -. Facultatif ici, requis par la vérification. Seuls ses 4 derniers caractères sont renvoyés.
Facultatif. 2 à 60 caractères, sans chiffres.
Adresse du domicile, gardée avec le titulaire : line1, line2, city, state, postal_code. La vérification la redemande.
Photos de la pièce d’identité, en base64 ou en URI data:image/…;base64,. JPEG ou PNG, 4 Mo chacune au plus, au moins 600 × 400 px. Absente : parameter_missing ; illisible, trop lourde ou trop petite : document_invalid. param indique la face.
Voir les attributs
Recto (page avec la photo pour un passeport).
Verso. Requis, sauf pour un passeport.
Retour
Renvoie le nouvel objet titulaire avec 201.
Erreurs à prévoir
| HTTP | Code | Description |
|---|---|---|
400 | parameter_missing | Un paramètre requis manque. Voir param. |
400 | parameter_invalid | Un paramètre a un type ou une valeur incorrects. Voir param. |
400 | document_invalid | Une photo de pièce n’est pas acceptée : JPEG ou PNG uniquement, 4 Mo au plus, au moins 600 × 400 px. param indique la face. |
400 | phone_invalid | Le numéro ne peut pas être lu comme un numéro international. |
400 | country_unsupported | Ce pays n’est pas ouvert pour cette devise. Voir Couverture. |
400 | cardholder_underage | Le titulaire doit avoir au moins 18 ans. |
400 | id_document_unsupported | Type de pièce d’identité non pris en charge. |
403 | permission_denied | Le créateur de la clé n’a pas le rôle requis pour cette opération. |
409 | cardholder_exists | Un titulaire utilise déjà cet e-mail. |
429 | rate_limited | Une limite de débit est atteinte. Attendez Retry-After secondes. Voir Limites de débit. |
curl https://api.monerails.com/v1/cardholders \
-H "Authorization: Bearer $MONERAIL_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45" \
-d '{
"type": "customer",
"first_name": "Awa",
"last_name": "Ndiaye",
"email": "awa@example.com",
"phone": "+237670000999",
"country": "CM",
"city": "Douala",
"birth_date": "1991-02-03",
"id_document": "national_id",
"documents": {
"front": "data:image/jpeg;base64,/9j/4AAQ…",
"back": "data:image/jpeg;base64,/9j/4AAQ…"
}
}'const res = await fetch('https://api.monerails.com/v1/cardholders', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.MONERAIL_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45',
},
body: JSON.stringify({
type: 'customer',
first_name: 'Awa',
last_name: 'Ndiaye',
email: 'awa@example.com',
phone: '+237670000999',
country: 'CM',
city: 'Douala',
birth_date: '1991-02-03',
id_document: 'national_id',
documents: {
front: 'data:image/jpeg;base64,/9j/4AAQ…',
back: 'data:image/jpeg;base64,/9j/4AAQ…',
},
}),
});
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.monerails.com/v1/cardholders",
headers={"Authorization": f"Bearer {os.environ['MONERAIL_KEY']}", "Idempotency-Key": "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45"},
json={
"type": "customer",
"first_name": "Awa",
"last_name": "Ndiaye",
"email": "awa@example.com",
"phone": "+237670000999",
"country": "CM",
"city": "Douala",
"birth_date": "1991-02-03",
"id_document": "national_id",
"documents": {
"front": "data:image/jpeg;base64,/9j/4AAQ…",
"back": "data:image/jpeg;base64,/9j/4AAQ…",
},
},
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.monerails.com/v1/cardholders');
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([
'type' => 'customer',
'first_name' => 'Awa',
'last_name' => 'Ndiaye',
'email' => 'awa@example.com',
'phone' => '+237670000999',
'country' => 'CM',
'city' => 'Douala',
'birth_date' => '1991-02-03',
'id_document' => 'national_id',
'documents' => [
'front' => 'data:image/jpeg;base64,/9j/4AAQ…',
'back' => 'data:image/jpeg;base64,/9j/4AAQ…',
],
]),
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": "customer",
"first_name": "Awa",
"last_name": "Ndiaye",
"email": "awa@example.com",
"phone": "+237670000999",
"country": "CM",
"city": "Douala",
"birth_date": "1991-02-03",
"id_document": "national_id",
"documents": map[string]any{
"front": "data:image/jpeg;base64,/9j/4AAQ…",
"back": "data:image/jpeg;base64,/9j/4AAQ…",
},
})
if err != nil {
panic(err)
}
req, err := http.NewRequest(http.MethodPost, "https://api.monerails.com/v1/cardholders", 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 = """
{
"type": "customer",
"first_name": "Awa",
"last_name": "Ndiaye",
"email": "awa@example.com",
"phone": "+237670000999",
"country": "CM",
"city": "Douala",
"birth_date": "1991-02-03",
"id_document": "national_id",
"documents": {
"front": "data:image/jpeg;base64,/9j/4AAQ…",
"back": "data:image/jpeg;base64,/9j/4AAQ…"
}
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.monerails.com/v1/cardholders"))
.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.monerails.com/v1/cardholders")
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({
type: "customer",
first_name: "Awa",
last_name: "Ndiaye",
email: "awa@example.com",
phone: "+237670000999",
country: "CM",
city: "Douala",
birth_date: "1991-02-03",
id_document: "national_id",
documents: {
front: "data:image/jpeg;base64,/9j/4AAQ…",
back: "data:image/jpeg;base64,/9j/4AAQ…",
},
})
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.monerails.com/v1/cardholders");
request.Headers.Add("Idempotency-Key", "a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45");
request.Content = JsonContent.Create(new
{
type = "customer",
first_name = "Awa",
last_name = "Ndiaye",
email = "awa@example.com",
phone = "+237670000999",
country = "CM",
city = "Douala",
birth_date = "1991-02-03",
id_document = "national_id",
documents = new
{
front = "data:image/jpeg;base64,/9j/4AAQ…",
back = "data:image/jpeg;base64,/9j/4AAQ…",
},
});
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": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"object": "cardholder",
"livemode": false,
"type": "customer",
"first_name": "Awa",
"last_name": "Ndiaye",
"email": "awa@example.com",
"phone": "+237670000999",
"country": "CM",
"city": "Douala",
"birth_date": "1991-02-03",
"id_document": "national_id",
"id_number_last4": "3408",
"verification": {
"status": "pending",
"reason": null,
"verified_at": null,
"documents_on_file": true
},
"created_at": "2026-10-30T13:47:06.394Z",
"updated_at": "2026-10-30T13:47:06.394Z"
}Envoyer la vérification d’identité
Transmet l’identité et les photos de la pièce à l’émetteur. Renvoie 202 avec verification.status à in_review. La décision arrive avec l’événement cardholder.kyc_updated. Après un refus, rappelez-le avec des informations corrigées. Si le titulaire est déjà vérifié, renvoie 200 sans rien changer ; pendant un examen en cours, les pièces ne sont pas renvoyées. Le prénom, le nom et la date de naissance doivent correspondre exactement à la pièce. La vérification est propre à chaque entreprise : une personne déjà vérifiée par une autre entreprise est vérifiée à nouveau pour la vôtre. Limité à 5 appels par titulaire et par 24 heures.
Rôles de la clé : Propriétaire ou Finance
Paramètres de chemin
Identifiant du titulaire.
Corps
Numéro de la pièce, mêmes règles qu’à la création (passeport : 6 à 9 lettres ou chiffres ; autres pièces : 4 à 30 caractères).
AAAA-MM-JJ, 18 ans ou plus. Par défaut, la birth_date du titulaire.
Ville de naissance, comme sur la pièce. 2 à 60 caractères, sans chiffres.
Adresse du domicile. Les accents sont acceptés et transmis sans accent.
Voir les attributs
3 à 100 caractères : lettres, chiffres, espaces et , . - uniquement.
Facultatif. Mêmes caractères que line1, 100 au plus.
2 à 60 caractères, sans chiffres.
Région, province ou État. 2 à 60 caractères, sans chiffres.
Facultatif. 1 à 10 lettres, chiffres, espaces ou traits d’union. À omettre s’il n’en existe pas.
Photos de la pièce, en base64 ou en URI data:image/…;base64,. JPEG ou PNG, 4 Mo chacune au plus, au moins 600 × 400 px (sinon document_invalid). Nettes, non recadrées, sans reflet, pièce entière visible. Facultatives si les photos ont été envoyées à la création (verification.documents_on_file) ; envoyées, elles les remplacent.
Voir les attributs
Recto (page avec la photo pour un passeport).
Verso. Requis, sauf pour un passeport.
Seulement si le titulaire n’en a pas. Mêmes règles qu’à la création.
Retour
Renvoie l’objet titulaire avec 202 : le résultat suit par webhook.
Erreurs à prévoir
| HTTP | Code | Description |
|---|---|---|
400 | parameter_missing | Un paramètre requis manque. Voir param. |
400 | parameter_invalid | Un paramètre a un type ou une valeur incorrects. Voir param. |
400 | phone_invalid | Le numéro ne peut pas être lu comme un numéro international. |
400 | document_invalid | Une photo de pièce n’est pas acceptée : JPEG ou PNG uniquement, 4 Mo au plus, au moins 600 × 400 px. param indique la face. |
400 | cardholder_underage | Le titulaire doit avoir au moins 18 ans. |
402 | identity_already_registered | L’émetteur de cartes détient déjà cette identité pour une vérification en cours ou terminée. Contactez le support. |
402 | verification_declined | L’émetteur de cartes a refusé l’envoi de la vérification. Vérifiez les informations et les photos de la pièce, puis renvoyez-la. |
403 | permission_denied | Le créateur de la clé n’a pas le rôle requis pour cette opération. |
429 | rate_limited | Une limite de débit est atteinte. Attendez Retry-After secondes. Voir Limites de débit. |
curl https://api.monerails.com/v1/cardholders/5df6acd9-4bac-4e19-869c-fcde6b79f389/verification \
-H "Authorization: Bearer $MONERAIL_KEY" \
-H "Content-Type: application/json" \
-d '{
"id_number": "CM12345678",
"birth_date": "1991-02-03",
"place_of_birth": "Douala",
"address": {
"line1": "12 rue Joss",
"city": "Douala",
"state": "Littoral"
},
"documents": {
"front": "data:image/jpeg;base64,/9j/4AAQ…",
"back": "data:image/jpeg;base64,/9j/4AAQ…"
}
}'const res = await fetch('https://api.monerails.com/v1/cardholders/5df6acd9-4bac-4e19-869c-fcde6b79f389/verification', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.MONERAIL_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
id_number: 'CM12345678',
birth_date: '1991-02-03',
place_of_birth: 'Douala',
address: {
line1: '12 rue Joss',
city: 'Douala',
state: 'Littoral',
},
documents: {
front: 'data:image/jpeg;base64,/9j/4AAQ…',
back: 'data:image/jpeg;base64,/9j/4AAQ…',
},
}),
});
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.monerails.com/v1/cardholders/5df6acd9-4bac-4e19-869c-fcde6b79f389/verification",
headers={"Authorization": f"Bearer {os.environ['MONERAIL_KEY']}"},
json={
"id_number": "CM12345678",
"birth_date": "1991-02-03",
"place_of_birth": "Douala",
"address": {
"line1": "12 rue Joss",
"city": "Douala",
"state": "Littoral",
},
"documents": {
"front": "data:image/jpeg;base64,/9j/4AAQ…",
"back": "data:image/jpeg;base64,/9j/4AAQ…",
},
},
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.monerails.com/v1/cardholders/5df6acd9-4bac-4e19-869c-fcde6b79f389/verification');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('MONERAIL_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'id_number' => 'CM12345678',
'birth_date' => '1991-02-03',
'place_of_birth' => 'Douala',
'address' => [
'line1' => '12 rue Joss',
'city' => 'Douala',
'state' => 'Littoral',
],
'documents' => [
'front' => 'data:image/jpeg;base64,/9j/4AAQ…',
'back' => 'data:image/jpeg;base64,/9j/4AAQ…',
],
]),
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{
"id_number": "CM12345678",
"birth_date": "1991-02-03",
"place_of_birth": "Douala",
"address": map[string]any{
"line1": "12 rue Joss",
"city": "Douala",
"state": "Littoral",
},
"documents": map[string]any{
"front": "data:image/jpeg;base64,/9j/4AAQ…",
"back": "data:image/jpeg;base64,/9j/4AAQ…",
},
})
if err != nil {
panic(err)
}
req, err := http.NewRequest(http.MethodPost, "https://api.monerails.com/v1/cardholders/5df6acd9-4bac-4e19-869c-fcde6b79f389/verification", 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 = """
{
"id_number": "CM12345678",
"birth_date": "1991-02-03",
"place_of_birth": "Douala",
"address": {
"line1": "12 rue Joss",
"city": "Douala",
"state": "Littoral"
},
"documents": {
"front": "data:image/jpeg;base64,/9j/4AAQ…",
"back": "data:image/jpeg;base64,/9j/4AAQ…"
}
}
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.monerails.com/v1/cardholders/5df6acd9-4bac-4e19-869c-fcde6b79f389/verification"))
.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.monerails.com/v1/cardholders/5df6acd9-4bac-4e19-869c-fcde6b79f389/verification")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("MONERAIL_KEY")}"
req["Content-Type"] = "application/json"
req.body = JSON.generate({
id_number: "CM12345678",
birth_date: "1991-02-03",
place_of_birth: "Douala",
address: {
line1: "12 rue Joss",
city: "Douala",
state: "Littoral",
},
documents: {
front: "data:image/jpeg;base64,/9j/4AAQ…",
back: "data:image/jpeg;base64,/9j/4AAQ…",
},
})
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.monerails.com/v1/cardholders/5df6acd9-4bac-4e19-869c-fcde6b79f389/verification");
request.Content = JsonContent.Create(new
{
id_number = "CM12345678",
birth_date = "1991-02-03",
place_of_birth = "Douala",
address = new
{
line1 = "12 rue Joss",
city = "Douala",
state = "Littoral",
},
documents = new
{
front = "data:image/jpeg;base64,/9j/4AAQ…",
back = "data:image/jpeg;base64,/9j/4AAQ…",
},
});
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": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"object": "cardholder",
"livemode": false,
"type": "customer",
"first_name": "Awa",
"last_name": "Ndiaye",
"email": "awa@example.com",
"phone": "+237670000999",
"country": "CM",
"city": "Douala",
"birth_date": "1991-02-03",
"id_document": "national_id",
"id_number_last4": "3408",
"verification": {
"status": "in_review",
"reason": null,
"verified_at": null,
"documents_on_file": true
},
"created_at": "2026-10-30T13:47:06.394Z",
"updated_at": "2026-10-30T13:47:09.807Z"
}Consulter un titulaire
Rôles de la clé : Tous les rôles
Paramètres de chemin
Identifiant du titulaire.
Retour
Renvoie l’objet titulaire.
curl https://api.monerails.com/v1/cardholders/5df6acd9-4bac-4e19-869c-fcde6b79f389 \
-H "Authorization: Bearer $MONERAIL_KEY"const res = await fetch('https://api.monerails.com/v1/cardholders/5df6acd9-4bac-4e19-869c-fcde6b79f389', {
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.monerails.com/v1/cardholders/5df6acd9-4bac-4e19-869c-fcde6b79f389",
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.monerails.com/v1/cardholders/5df6acd9-4bac-4e19-869c-fcde6b79f389');
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.monerails.com/v1/cardholders/5df6acd9-4bac-4e19-869c-fcde6b79f389", 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.monerails.com/v1/cardholders/5df6acd9-4bac-4e19-869c-fcde6b79f389"))
.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.monerails.com/v1/cardholders/5df6acd9-4bac-4e19-869c-fcde6b79f389")
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.monerails.com/v1/cardholders/5df6acd9-4bac-4e19-869c-fcde6b79f389");
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": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"object": "cardholder",
"livemode": false,
"type": "customer",
"first_name": "Awa",
"last_name": "Ndiaye",
"email": "awa@example.com",
"phone": "+237670000999",
"country": "CM",
"city": "Douala",
"birth_date": "1991-02-03",
"id_document": "national_id",
"id_number_last4": "3408",
"verification": {
"status": "verified",
"reason": null,
"verified_at": "2026-10-30T13:47:09.807Z"
},
"created_at": "2026-10-30T13:47:06.394Z",
"updated_at": "2026-10-30T13:47:06.394Z"
}Lister les titulaires
Du plus récent au plus ancien.
Rôles de la clé : Tous les rôles
Paramètres de requête
20Nombre d’objets à renvoyer, de 1 à 100.
Curseur : l’identifiant du dernier objet de la page précédente.
Retour
Renvoie un objet liste : data contient jusqu’à limit objets cardholder, et has_more indique s’il en reste.
curl "https://api.monerails.com/v1/cardholders?limit=10" \
-H "Authorization: Bearer $MONERAIL_KEY"const res = await fetch('https://api.monerails.com/v1/cardholders?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.monerails.com/v1/cardholders",
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.monerails.com/v1/cardholders?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.monerails.com/v1/cardholders?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.monerails.com/v1/cardholders?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.monerails.com/v1/cardholders?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.monerails.com/v1/cardholders?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/cardholders",
"data": [
{
"id": "5df6acd9-4bac-4e19-869c-fcde6b79f389",
"object": "cardholder",
"livemode": false,
"type": "customer",
"first_name": "Awa",
"last_name": "Ndiaye",
"email": "awa@example.com",
"phone": "+237670000999",
"country": "CM",
"city": "Douala",
"birth_date": "1991-02-03",
"id_document": "national_id",
"id_number_last4": "3408",
"verification": {
"status": "pending",
"reason": null,
"verified_at": null,
"documents_on_file": true
},
"created_at": "2026-10-30T13:47:06.394Z",
"updated_at": "2026-10-30T13:47:06.394Z"
}
],
"has_more": false
}