Démarrer
Environnement URL de base Usage
Sandbox https://sandbox.api.linc.cdDéveloppement et tests. Clés sk_test_…, aucun argent réel, partenaires simulés.
Production https://api.linc.cdOpérations réelles. Clés sk_live_…, ouvertes après validation de votre dossier.
Toutes les routes commencent par /v1. Le corps des requêtes et des réponses est en JSON (UTF-8). Vous pouvez appeler l'API depuis n'importe quel langage capable de faire une requête HTTPS : les exemples ci-dessous sont en cURL , PHP , Python et JavaScript (Node.js 18+) .
Ouvrez un compte marchand sur merchant.linc.cd . Vos clés de test sont disponibles tout de suite.
Récupérez vos clés dans Espace marchand › API & webhooks . La clé secrète s'affiche une seule fois : conservez-la dans un coffre ou une variable d'environnement.
Déclarez l'URL de votre webhook au même endroit, puis testez sur la sandbox.
Passez en production quand votre dossier (KYB) est validé : remplacez l'URL de base et la clé.
Quelle intégration choisir ?
Vous voulez… Authentification Routes principales
Encaisser les paiements de vos clients (site, application, facture) Clé secrète marchand sk_ /v1/payment-links
Agir au nom d'un client Linc : transferts, paiements, carte virtuelle, rechargement Jeton client (JWT 15 min + jeton de renouvellement) /v1/auth, /v1/quotes, /v1/transfers, /v1/cards
Construire une application pour un marchand ou un agent Linc Jeton pro (mot de passe + TOTP) /v1/pro/auth
Relier la plateforme d'un réseau d'agents, de serveur à serveur Bientôt : clés à portée limitée, requêtes signées et adresses IP autorisées. Écrivez à sales@linc.cd .
L'API client agit toujours pour un client identifié, qui confirme lui-même chaque opération sensible avec son second facteur. Linc ne délivre jamais de jeton client à un tiers sans le consentement du client.
Authentification
Clé secrète marchand
Envoyez la clé dans l'en-tête Authorization. Une clé absente ou invalide répond 401 api_key_invalid. N'utilisez jamais la clé secrète dans un navigateur ou une application mobile : elle reste sur votre serveur.
curl https://sandbox.api.linc.cd/v1/payment-links/INV-7K2Q4F \
-H "Authorization: Bearer $LINC_SECRET_KEY"
Adresses IP autorisées
Les clés secrètes ne fonctionnent que depuis les adresses IP de vos serveurs. Déclarez-les dans l'étape « Intégration technique » de votre dossier, puis gérez-les dans votre espace marchand, « API & webhooks › Adresses IP autorisées ». Chaque modification est confirmée par votre application d'authentification.
Production (sk_live_) : la liste est obligatoire pour générer les clés. Un appel depuis une autre adresse répond 403 ip_not_allowed.
Sandbox (sk_test_) : la liste est facultative. Vide, toute adresse est acceptée, l'espace de test de cette page compris.
Jusqu'à 10 adresses IPv4 (203.0.113.10) ou IPv6 (2001:db8::10), ou plages CIDR (198.51.100.0/28 ; de /8 à /32 en IPv4, de /32 à /128 en IPv6).
L'adresse contrôlée est celle qui se connecte à Linc : l'adresse de sortie de votre serveur, ou de votre passerelle NAT ou proxy sortant. Un en-tête X-Forwarded-For envoyé par votre code n'est pas pris en compte.
Vous changez d'hébergement ? Ajoutez la nouvelle adresse avant la bascule, puis retirez l'ancienne.
HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
{"type": "https://docs.linc.cd/erreurs/ip_not_allowed", "status": 403, "code": "ip_not_allowed",
"title": "Adresse IP non autorisée pour cette clé. Ajoutez l’adresse de votre serveur dans « API & webhooks › Adresses IP autorisées »."}
Jeton client : connexion en deux temps
POST /v1/auth/login avec l'identifiant (téléphone ou e-mail) et le mot de passe, et l'en-tête X-Device-Id (identifiant stable de l'installation).
Appareil connu : réponse 200 avec les jetons. Nouvel appareil : réponse 202 two_factor_required avec un pendingLoginId et les méthodes proposées (totp, sms, backup_code).
Pour le SMS, demandez d'abord le code : POST /v1/auth/login/{pendingLoginId}/sms. Puis envoyez le code : POST /v1/auth/login/{pendingLoginId}/verify.
Utilisez accessToken (valable 15 minutes) dans Authorization: Bearer …. Avant expiration, appelez POST /v1/auth/refresh : le jeton de renouvellement est rotatif , conservez le nouveau et jetez l'ancien.
cURL PHP Python JavaScript
# 1. Mot de passe
curl -X POST https://sandbox.api.linc.cd/v1/auth/login \
-H "Content-Type: application/json" -H "X-Device-Id: $DEVICE_ID" \
-d '{"identifier": "+243810000000", "password": "…"}'
# → 202 {"status":"two_factor_required","pendingLoginId":"0192…","methods":["totp","sms"],"expiresAt":"…"}
# 2. Second facteur
curl -X POST https://sandbox.api.linc.cd/v1/auth/login/$PENDING_ID/verify \
-H "Content-Type: application/json" -H "X-Device-Id: $DEVICE_ID" \
-d '{"method": "totp", "code": "123456"}'
# → 200 {"tokenType":"Bearer","accessToken":"eyJ…","expiresIn":900,"refreshToken":"…","refreshExpiresIn":…}
# 3. Renouvellement
curl -X POST https://sandbox.api.linc.cd/v1/auth/refresh \
-H "Content-Type: application/json" -d '{"refreshToken": "…"}'
<?php
function linc(string $method, string $path, array $body = null, array $headers = []): array
{
$ch = curl_init('https://sandbox.api.linc.cd'.$path);
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array_merge(['Content-Type: application/json', 'Accept: application/json'], $headers),
CURLOPT_POSTFIELDS => null === $body ? null : json_encode($body),
]);
$raw = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
return [$status, json_decode($raw, true)];
}
$device = ['X-Device-Id: '.getenv('LINC_DEVICE_ID')];
[$status, $login] = linc('POST', '/v1/auth/login', ['identifier' => '+243810000000', 'password' => $password], $device);
if (202 === $status) {
[, $login] = linc('POST', "/v1/auth/login/{$login['pendingLoginId']}/verify", ['method' => 'totp', 'code' => $totpCode], $device);
}
$auth = ['Authorization: Bearer '.$login['accessToken']];
import os, requests
API = "https://sandbox.api.linc.cd"
device = {"X-Device-Id": os.environ["LINC_DEVICE_ID"]}
r = requests.post(f"{API}/v1/auth/login", json={"identifier": "+243810000000", "password": password}, headers=device, timeout=30)
if r.status_code == 202:
pending = r.json()["pendingLoginId"]
r = requests.post(f"{API}/v1/auth/login/{pending}/verify", json={"method": "totp", "code": totp_code}, headers=device, timeout=30)
r.raise_for_status()
tokens = r.json()
auth = {"Authorization": f"Bearer {tokens['accessToken']}"}
const API = "https://sandbox.api.linc.cd";
const device = { "Content-Type": "application/json", "X-Device-Id": process.env.LINC_DEVICE_ID };
let res = await fetch(`${API}/v1/auth/login`, {
method: "POST", headers: device,
body: JSON.stringify({ identifier: "+243810000000", password }),
});
if (res.status === 202) {
const { pendingLoginId } = await res.json();
res = await fetch(`${API}/v1/auth/login/${pendingLoginId}/verify`, {
method: "POST", headers: device,
body: JSON.stringify({ method: "totp", code: totpCode }),
});
}
const { accessToken, refreshToken } = await res.json();
const auth = { Authorization: `Bearer ${accessToken}` };
Conventions
Idempotence Chaque POST financier exige l'en-tête Idempotency-Key (8 à 255 caractères, un UUID par opération). La clé est conservée 24 heures : renvoyer la même requête avec la même clé ne crée pas de doublon. La même clé avec un corps différent répond idempotency_key_reused.
Montants En entrée, une chaîne décimale : "150.00". En sortie, un objet {"amount": 15000, "currency": "USD", "display": "150,00 $"} où amount est un entier en unités mineures. N'utilisez jamais de nombre à virgule flottante pour de l'argent.
Devises et pays Codes ISO 4217 (USD, CDF) et ISO 3166 alpha-2 (CI, SN…). Les pays et modes de réception ouverts se lisent sur GET /v1/corridors (public).
Second facteur Les opérations sensibles (transfert, paiement, carte, bénéficiaire) prennent un objet "twoFactor": {"method": "totp", "code": "••••••"}. Sans lui, la réponse est two_factor_required : demandez le code au client, puis renvoyez la requête avec la même Idempotency-Key.
Applications mobiles Envoyez X-Device-Id, X-App-Id, X-App-Platform et X-App-Version. Quand la politique l'exige, les opérations sensibles demandent aussi X-Linc-Attestation (appareil attesté).
Asynchrone Un transfert ou un paiement est accepté (202) puis traité : suivez son état par webhook ou par GET, jamais en supposant qu'il a réussi.
Faire un transfert
Exemple : 150 USD depuis Airtel Money (RDC) vers un Orange Money en Côte d'Ivoire.
1 Montant et pays Le client choisit le pays et le mode de réception.
2 Devis Frais, taux, total débité, montant reçu. Valable 60 s.
3 Bénéficiaire Numéro mobile money, compte bancaire ou carte.
4 Confirmation Source de fonds et code à 6 chiffres (2FA).
5 Suivi Collecte, versement, livraison, en temps réel.
POST /v1/quotes : montant, devise, pays et mode de réception. Réponse : id, send, fee, vat, levy, total, receive, rate, expiresAt. Affichez-les tels quels au client.
POST /v1/beneficiaries (une seule fois par bénéficiaire) : nom, pays, mode et coordonnées dans details.
POST /v1/transfers avant l'expiration du devis : quoteId, beneficiaryId, source, purpose et twoFactor. Réponse 202 avec la référence LP-XXXXXX.
GET /v1/transfers/{reference} : status vaut in_progress, delivered, failed, refunded ou on_hold, avec les étapes.
cURL PHP Python JavaScript
# 1. Devis
curl -X POST https://sandbox.api.linc.cd/v1/quotes \
-H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"amount": "150.00", "currency": "USD", "destinationCountry": "CI", "payoutMethod": "mobile_money", "sourceType": "mobile_money"}'
# 2. Bénéficiaire
curl -X POST https://sandbox.api.linc.cd/v1/beneficiaries \
-H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" \
-d '{"fullName": "Bastian Kelyan", "country": "CI", "payoutMethod": "mobile_money",
"details": {"msisdn": "+2250700000000", "provider": "orange", "relationship": "family"}}'
# 3. Envoi, confirmé par le second facteur
curl -X POST https://sandbox.api.linc.cd/v1/transfers \
-H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"quoteId": "'$QUOTE_ID'", "beneficiaryId": "'$BENEFICIARY_ID'",
"source": {"type": "mobile_money", "provider": "airtel", "msisdn": "+243970000000"},
"purpose": "family_support",
"twoFactor": {"method": "totp", "code": "••••••"}}'
# → 202 {"reference": "LP-8QK2ZD", "status": "in_progress", "steps": […], …}
# 4. Suivi
curl https://sandbox.api.linc.cd/v1/transfers/LP-8QK2ZD -H "Authorization: Bearer $ACCESS_TOKEN"
<?php
// linc() : voir l'exemple d'authentification
$idem = fn () => 'Idempotency-Key: '.bin2hex(random_bytes(16));
[, $quote] = linc('POST', '/v1/quotes', [
'amount' => '150.00', 'currency' => 'USD',
'destinationCountry' => 'CI', 'payoutMethod' => 'mobile_money', 'sourceType' => 'mobile_money',
], [...$auth, $idem()]);
// Afficher $quote['fee']['display'], $quote['total']['display'], $quote['receive']['display']
[$status, $transfer] = linc('POST', '/v1/transfers', [
'quoteId' => $quote['id'],
'beneficiaryId' => $beneficiaryId,
'source' => ['type' => 'mobile_money', 'provider' => 'airtel', 'msisdn' => '+243970000000'],
'purpose' => 'family_support',
'twoFactor' => ['method' => 'totp', 'code' => $code],
], [...$auth, $idem()]);
if (202 !== $status) {
throw new RuntimeException($transfer['code'].' : '.$transfer['title']);
}
echo $transfer['reference']; // LP-XXXXXX
import uuid
def post(path, body):
headers = {**auth, "Idempotency-Key": str(uuid.uuid4())}
return requests.post(f"{API}{path}", json=body, headers=headers, timeout=30)
quote = post("/v1/quotes", {
"amount": "150.00", "currency": "USD",
"destinationCountry": "CI", "payoutMethod": "mobile_money", "sourceType": "mobile_money",
}).json()
print(quote["fee"]["display"], quote["total"]["display"], quote["receive"]["display"])
r = post("/v1/transfers", {
"quoteId": quote["id"],
"beneficiaryId": beneficiary_id,
"source": {"type": "mobile_money", "provider": "airtel", "msisdn": "+243970000000"},
"purpose": "family_support",
"twoFactor": {"method": "totp", "code": code},
})
if r.status_code != 202:
problem = r.json()
raise RuntimeError(f"{problem['code']} : {problem['title']}")
reference = r.json()["reference"] # LP-XXXXXX
import { randomUUID } from "node:crypto";
const post = (path, body) => fetch(`${API}${path}`, {
method: "POST",
headers: { ...auth, "Content-Type": "application/json", "Idempotency-Key": randomUUID() },
body: JSON.stringify(body),
});
const quote = await (await post("/v1/quotes", {
amount: "150.00", currency: "USD",
destinationCountry: "CI", payoutMethod: "mobile_money", sourceType: "mobile_money",
})).json();
const res = await post("/v1/transfers", {
quoteId: quote.id,
beneficiaryId,
source: { type: "mobile_money", provider: "airtel", msisdn: "+243970000000" },
purpose: "family_support",
twoFactor: { method: "totp", code },
});
if (res.status !== 202) {
const problem = await res.json();
throw new Error(`${problem.code} : ${problem.title}`);
}
const { reference } = await res.json(); // LP-XXXXXX
Sources possibles : mobile_money (Airtel Money, M-Pesa, Orange Money, Afrimoney), wallet (solde Linc, compte en mode wallet) et card quand ce parcours est ouvert. Destinations : mobile_money, bank_account ou card. Les pays et modes proposés dépendent des corridors ouverts : lisez-les sur GET /v1/corridors plutôt que de les coder en dur.
Encaisser un paiement (marchand)
1 Votre site Votre serveur crée le lien de paiement.
2 Page Linc Le client ouvre app.linc.cd/pay/INV-… ou scanne le QR.
3 Paiement Solde, mobile money ou carte, confirmé par le client.
4 Reçu Vous recevez payment.succeeded.
POST /v1/payment-links avec votre clé secrète : amount, description, expires_in (24h, 7d ou 30d). La réponse contient id (INV-XXXXXX), url et qr.
Redirigez le client vers url, affichez le QR ou envoyez le lien par SMS.
Livrez la commande à la réception du webhook payment.succeeded (et non au retour du client sur votre site). En secours, lisez l'état avec GET /v1/payment-links/{id} : open, paid, expired ou cancelled.
cURL PHP Python JavaScript
curl -X POST https://sandbox.api.linc.cd/v1/payment-links \
-H "Authorization: Bearer $LINC_SECRET_KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: order-10452" \
-d '{"amount": "25.00", "description": "Commande n° 10452", "expires_in": "24h"}'
# → 201 {"id": "INV-7K2Q4F", "object": "payment_link", "status": "open", "livemode": false,
# "amount": {"amount": 2500, "currency": "USD", "display": "25,00 $"},
# "url": "https://app.linc.cd/pay/INV-7K2Q4F", "qr": "…", "expires_at": "…"}
<?php
[$status, $link] = linc('POST', '/v1/payment-links',
['amount' => '25.00', 'description' => 'Commande n° 10452', 'expires_in' => '24h'],
['Authorization: Bearer '.getenv('LINC_SECRET_KEY'), 'Idempotency-Key: order-10452'],
);
header('Location: '.$link['url'], true, 303);
r = requests.post(f"{API}/v1/payment-links",
json={"amount": "25.00", "description": "Commande n° 10452", "expires_in": "24h"},
headers={"Authorization": f"Bearer {os.environ['LINC_SECRET_KEY']}", "Idempotency-Key": "order-10452"},
timeout=30)
r.raise_for_status()
link = r.json()
redirect_to(link["url"]) # https://app.linc.cd/pay/INV-…
const res = await fetch(`${API}/v1/payment-links`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.LINC_SECRET_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": "order-10452",
},
body: JSON.stringify({ amount: "25.00", description: "Commande n° 10452", expires_in: "24h" }),
});
const link = await res.json();
response.redirect(303, link.url);
Un lien créé avec une clé de test (livemode: false) n'est jamais payable en réel. Côté application client, le paiement d'un lien ou d'un QR se fait avec POST /v1/merchant-payments/resolve (lire le QR ou le lien) puis POST /v1/merchant-payments (payer, avec le second facteur). Le paiement par carte bancaire passe par une page carte hébergée, avec 3-D Secure : vous ne manipulez jamais le numéro de carte.
Créer une carte virtuelle
Disponible pour un client en mode wallet avec un KYC de niveau 2 . La carte est alimentée par le solde Linc.
1 Réseau Visa ou Mastercard, nom sur la carte.
2 Confirmation Code à 6 chiffres (2FA).
3 Carte 4 derniers chiffres, statut, plafonds.
4 Détails Affichés par le widget sécurisé de l'émetteur.
cURL PHP Python JavaScript
curl -X POST https://sandbox.api.linc.cd/v1/cards \
-H "Authorization: Bearer $ACCESS_TOKEN" -H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"network": "visa", "embossedName": "AMANI K", "twoFactor": {"method": "totp", "code": "••••••"}}'
# → 201 {"id": "0192…", "last4": "4821", "network": "visa", "currency": "USD", "status": "active", "limits": {…}, …}
# Geler, dégeler
curl -X POST https://sandbox.api.linc.cd/v1/cards/$CARD_ID/freeze -H "Authorization: Bearer $ACCESS_TOKEN"
curl -X POST https://sandbox.api.linc.cd/v1/cards/$CARD_ID/unfreeze -H "Authorization: Bearer $ACCESS_TOKEN"
<?php
[$status, $card] = linc('POST', '/v1/cards', [
'network' => 'visa',
'embossedName' => 'AMANI K',
'twoFactor' => ['method' => 'totp', 'code' => $code],
], [...$auth, $idem()]);
echo $card['network'].' •••• '.$card['last4'];
card = post("/v1/cards", {
"network": "visa",
"embossedName": "AMANI K",
"twoFactor": {"method": "totp", "code": code},
}).json()
print(card["network"], "••••", card["last4"])
const card = await (await post("/v1/cards", {
network: "visa",
embossedName: "AMANI K",
twoFactor: { method: "totp", code },
})).json();
console.log(`${card.network} •••• ${card.last4}`);
Linc ne renvoie jamais le numéro complet, le CVV ni la date d'expiration. Pour les afficher, POST /v1/cards/{id}/reveal (avec le second facteur) ouvre une session de 60 secondes pour le widget ou le SDK de l'émetteur, qui affiche les détails directement au client. Autres routes : GET /v1/cards, GET /v1/cards/{id}/transactions, /replace, /terminate.
Recevoir les webhooks
Linc envoie un POST JSON à l'URL déclarée dans Espace marchand › API & webhooks (HTTPS obligatoire) à chaque évènement :
Évènement Quand
payment.succeededUn paiement est confirmé par le partenaire. Livrez la commande.
payment.refundedUn paiement est remboursé, en tout ou en partie.
payment.disputedUn paiement par carte fait l'objet d'une contestation.
settlement.paidLe règlement du jour est versé sur votre compte bancaire, commission déduite.
En-têtes envoyés : X-Linc-Event (type), X-Linc-Delivery (identifiant unique de l'évènement) et X-Linc-Signature :
X-Linc-Signature: t=1790712000,v1=5f1c…e9a2
# v1 = HMAC-SHA256 en hexadécimal, clé = secret du webhook (whsec_…), message = "{t}.{corps brut}"
{
"id": "evt_0192a7c4…",
"type": "payment.succeeded",
"created": 1790712000,
"merchant": "M-4K7Q2",
"data": {
"id": "…", "object": "payment", "status": "succeeded",
"amount": "25.00", "currency": "USD", "commission": "0.38",
"payment_link": "INV-7K2Q4F", "method": "mobile_money", "provider": "airtel", …
}
}
Vérifiez toujours la signature sur le corps brut, avant de le décoder, et refusez un horodatage de plus de 5 minutes :
PHP Python JavaScript
<?php
$body = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_LINC_SIGNATURE'] ?? '';
$secret = getenv('LINC_WEBHOOK_SECRET');
if (1 !== preg_match('/^t=(\d+),v1=([a-f0-9]{64})$/', $header, $m)
|| abs(time() - (int) $m[1]) > 300
|| !hash_equals(hash_hmac('sha256', $m[1].'.'.$body, $secret), $m[2])) {
http_response_code(400);
exit;
}
$event = json_decode($body, true);
// Ignorer un évènement déjà traité ($event['id']), puis traiter en file d'attente
http_response_code(200);
import hashlib, hmac, os, re, time
from flask import Flask, abort, request
app = Flask(__name__)
SECRET = os.environ["LINC_WEBHOOK_SECRET"].encode()
@app.post("/webhooks/linc")
def linc_webhook():
body = request.get_data() # corps brut
m = re.fullmatch(r"t=(\d+),v1=([a-f0-9]{64})", request.headers.get("X-Linc-Signature", ""))
if not m or abs(time.time() - int(m[1])) > 300:
abort(400)
expected = hmac.new(SECRET, m[1].encode() + b"." + body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, m[2]):
abort(400)
event = request.get_json()
# Ignorer un évènement déjà traité (event["id"]), puis traiter en file d'attente
return "", 200
import crypto from "node:crypto";
import express from "express";
const app = express();
app.post("/webhooks/linc", express.raw({ type: "application/json" }), (req, res) => {
const m = /^t=(\d+),v1=([a-f0-9]{64})$/.exec(req.get("X-Linc-Signature") ?? "");
if (!m || Math.abs(Date.now() / 1000 - Number(m[1])) > 300) return res.sendStatus(400);
const expected = crypto.createHmac("sha256", process.env.LINC_WEBHOOK_SECRET)
.update(`${m[1]}.`).update(req.body).digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(m[2]))) return res.sendStatus(400);
const event = JSON.parse(req.body);
// Ignorer un évènement déjà traité (event.id), puis traiter en file d'attente
res.sendStatus(200);
});
Répondez 2xx en moins de 10 secondes, puis traitez en arrière-plan.
Sans réponse 2xx, Linc renvoie l'évènement après 1 min, 5 min, 30 min, 2 h et 6 h.
Un même évènement peut arriver deux fois : dédoublonnez sur id (ou X-Linc-Delivery).
L'ordre d'arrivée n'est pas garanti : fiez-vous à l'état contenu dans data.
Le secret du webhook se renouvelle dans l'espace marchand ; les clés API aussi (rotation).
Espace de test
Vérifiez votre clé et voyez les vraies réponses de l'API, sans écrire de code. Les appels partent de votre navigateur vers la sandbox https://sandbox.api.linc.cd, qui n'accepte que les clés de test : aucun argent réel, aucun lien payable.
Saisissez uniquement une clé sk_test_…. Une clé sk_live_… est refusée avant tout envoi. La clé reste dans cette page : elle n'est ni enregistrée, ni journalisée, ni placée dans l'adresse. Fermez l'onglet pour l'effacer.
Résultat
Saisissez votre clé de test, puis cliquez sur « Vérifier la clé ».
Requête équivalente
Signer et vérifier un webhook
Testez votre code de vérification : collez le corps brut reçu et l'en-tête X-Linc-Signature, ou générez un en-tête pour un corps de test. Le calcul se fait dans votre navigateur : rien n'est envoyé. Utilisez de préférence le secret de votre webhook de test.
Fichiers JSON
Exemples de requêtes et de réponses, conformes au contrat de l'API. Téléchargez-les pour vos tests, vos maquettes d'écran ou vos simulateurs.
Collection Postman de la sandbox
Importez la collection dans Postman, puis renseignez secretKey (clé de test) ou les identifiants d'un compte de test, et deviceId. Les jetons, devis, bénéficiaires et références sont enregistrés automatiquement d'une requête à l'autre.
Erreurs
Les erreurs suivent le format application/problem+json (RFC 9457), avec un code stable à tester dans votre code et un title lisible, en français :
HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json
{"type": "https://docs.linc.cd/erreurs/validation_failed", "title": "Certains champs sont invalides. Corrigez-les puis réessayez.",
"status": 422, "code": "validation_failed",
"violations": [{"field": "amount", "message": "Saisissez un montant valide."}]}
Code Que faire
validation_failedCorrigez les champs listés dans violations.
api_key_invalidVérifiez la clé et l'environnement (sk_test_ sur la sandbox, sk_live_ en production).
ip_not_allowedL'appel vient d'une adresse IP absente de vos adresses autorisées : ajoutez celle de votre serveur dans « API & webhooks ».
two_factor_requiredDemandez le code au client et renvoyez la requête avec twoFactor.
quote_expiredLe devis a plus de 60 secondes : demandez-en un nouveau et affichez-le au client.
quote_already_usedCe devis a déjà servi : suivez le transfert existant.
idempotency_key_requiredAjoutez l'en-tête Idempotency-Key.
idempotency_key_reusedMême clé, corps différent : générez une nouvelle clé pour une nouvelle opération.
idempotency_in_progressLa première requête est encore en cours : réessayez dans quelques secondes.
attestation_requiredEnvoyez l'assertion X-Linc-Attestation de l'appareil.
app_update_requiredMettez l'application à jour (minimumVersion).
rate_limitedTrop de requêtes : attendez, puis réessayez avec un délai croissant.
Aide et sécurité
Ne mettez jamais une clé secrète, un secret de webhook ou un jeton dans le code source, une application mobile ou un navigateur.
Journalisez le code et la référence (LP-…, INV-…), jamais les données personnelles.
La documentation complète, générée depuis le contrat OpenAPI, et l'espace développeur arrivent bientôt.
Questions techniques : support@linc.cd . Partenariats et accès production : sales@linc.cd .
POST /v1/auth/register
Créer un compte client
Crée le compte et envoie un code SMS de vérification du téléphone.
Authentification : Aucune (route publique)
Paramètres Nom Où Type Obligatoire Description X-Device-Iden-tête string non Identifiant d'installation de l'application. Un appareil inconnu déclenche la double authentification.
Corps de la requête Nom Type Obligatoire Description fullNamestring oui phonestring oui Numéro de téléphone, par exemple +243812345678.
emailstring (email) oui passwordstring oui 8 caractères au moins avec un chiffre. Refusé s'il figure dans une fuite connue.
acceptTermsboolean oui Case « J'ai lu et j'accepte les Conditions générales d'utilisation » (versions : GET /v1/legal).
acceptPrivacyboolean oui Case « J'ai lu la Politique de confidentialité et j'accepte le traitement de mes données décrit ».
acceptAmlboolean oui Case « J'ai lu la Politique LBC/FT et je m'engage à respecter mes obligations » (informations exactes, compte utilisé pour soi-même, fonds d'origine licite). Les trois cases sont distinctes, non cochées par défaut, et le serveur refuse l'inscription sans les trois (422 validation_failed, un champ par case manquante). La preuve de chaque acceptation (version, date, canal, adresse IP, appareil, session) est conservée ; le canal est la plateforme de l'application (X-App-Platform : android, ios).
residenceCountrystring non Pays de résidence (ISO 3166 alpha-2) parmi GET /v1/origin-countries. Par défaut, le pays du téléphone. Un autre pays est refusé (residence_not_allowed, « Linc est disponible pour les résidents de la RD Congo. »), un téléphone d'un autre pays aussi (phone_not_residence).
Exemple de requête {
"fullName": "texte",
"phone": "+243810000000",
"email": "client@example.com",
"password": "••••••••",
"acceptTerms": true,
"acceptPrivacy": true,
"acceptAml": true
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/auth/register" \
-H "Content-Type: application/json" \
-d '{
"fullName": "texte",
"phone": "+243810000000",
"email": "client@example.com",
"password": "••••••••",
"acceptTerms": true,
"acceptPrivacy": true,
"acceptAml": true
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/auth/register');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"fullName": "texte",
"phone": "+243810000000",
"email": "client@example.com",
"password": "••••••••",
"acceptTerms": true,
"acceptPrivacy": true,
"acceptAml": true
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/auth/register",
json={
"fullName": "texte",
"phone": "+243810000000",
"email": "client@example.com",
"password": "••••••••",
"acceptTerms": True,
"acceptPrivacy": True,
"acceptAml": True
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/auth/register", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"fullName": "texte",
"phone": "+243810000000",
"email": "client@example.com",
"password": "••••••••",
"acceptTerms": true,
"acceptPrivacy": true,
"acceptAml": true
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"purpose": "phone_verification",
"sentTo": "texte",
"expiresAt": "2026-10-01T09:30:00Z",
"remainingAttempts": 0
}
Réponses et erreurs Statut Signification 201Compte créé. Code SMS envoyé.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/origin-countries
Lister les pays de résidence acceptés à l'inscription
Pays d'origine autorisés : l'agrément de la BCC couvre les envois depuis la RD Congo, seule proposée par défaut (default). Le téléphone doit être un numéro du pays de résidence (callingCode). Public.
Authentification : Aucune (route publique)
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/origin-countries"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/origin-countries');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/origin-countries",
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/origin-countries", {
method: "GET",
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"countries": [
{
"country": "CD",
"name": "Congo-Kinshasa",
"callingCode": "+243",
"default": true
}
]
}
Réponses et erreurs Statut Signification 200Pays de résidence acceptés.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/auth/register/resend
Renvoyer le code de vérification
Envoie un nouveau code SMS pour la vérification du téléphone.
Authentification : Aucune (route publique)
Corps de la requête Nom Type Obligatoire Description challengeIdstring (uuid) oui
Exemple de requête {
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f"
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/auth/register/resend" \
-H "Content-Type: application/json" \
-d '{
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/auth/register/resend');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/auth/register/resend",
json={
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/auth/register/resend", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"purpose": "phone_verification",
"sentTo": "texte",
"expiresAt": "2026-10-01T09:30:00Z",
"remainingAttempts": 0
}
Réponses et erreurs Statut Signification 201Nouveau code envoyé.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/auth/verify-phone
Vérifier le téléphone
Valide le code SMS, active le compte et ouvre une session mobile.
Authentification : Aucune (route publique)
Paramètres Nom Où Type Obligatoire Description X-Device-Iden-tête string non Identifiant d'installation de l'application. Un appareil inconnu déclenche la double authentification.
Corps de la requête Nom Type Obligatoire Description challengeIdstring (uuid) oui codestring oui Code à 6 chiffres reçu par SMS.
Exemple de requête {
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"code": "••••••"
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/auth/verify-phone" \
-H "Content-Type: application/json" \
-d '{
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"code": "••••••"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/auth/verify-phone');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"code": "••••••"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/auth/verify-phone",
json={
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"code": "••••••"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/auth/verify-phone", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"code": "••••••"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"tokenType": "Bearer",
"accessToken": "…",
"expiresIn": 0,
"refreshToken": "…",
"refreshExpiresIn": 0
}
Réponses et erreurs Statut Signification 200Téléphone vérifié. Jetons de session.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/auth/login
Se connecter
Connexion par téléphone ou e-mail. Sur un appareil connu : jetons de session (200). Sur un nouvel appareil : double authentification requise (202), à terminer avec POST /v1/auth/login/{pendingLoginId}/verify.
Authentification : Aucune (route publique)
Paramètres Nom Où Type Obligatoire Description X-Device-Iden-tête string non Identifiant d'installation de l'application. Un appareil inconnu déclenche la double authentification.
Corps de la requête Nom Type Obligatoire Description identifierstring oui Téléphone ou e-mail.
passwordstring oui
Exemple de requête {
"identifier": "+243810000000",
"password": "••••••••"
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/auth/login" \
-H "Content-Type: application/json" \
-d '{
"identifier": "+243810000000",
"password": "••••••••"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/auth/login');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"identifier": "+243810000000",
"password": "••••••••"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/auth/login",
json={
"identifier": "+243810000000",
"password": "••••••••"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"identifier": "+243810000000",
"password": "••••••••"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"status": "two_factor_required",
"pendingLoginId": "0192a7c4-2c9d-7e41-a3b5-6f7e8d9c0b12",
"methods": [
"totp",
"sms",
"backup_code"
],
"expiresAt": "2026-09-29T14:05:00+00:00"
}
Réponses et erreurs Statut Signification 200Connexion réussie.
202Double authentification requise.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/auth/login/{pendingLoginId}/sms
Recevoir le code de connexion par SMS
Envoie un code SMS pour terminer une connexion en attente.
Authentification : Aucune (route publique)
Paramètres Nom Où Type Obligatoire Description pendingLoginIdchemin string oui Identifiant de la connexion en attente.
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/auth/login/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/sms"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/auth/login/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/sms');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/auth/login/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/sms",
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/auth/login/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/sms", {
method: "POST",
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"purpose": "phone_verification",
"sentTo": "texte",
"expiresAt": "2026-10-01T09:30:00Z",
"remainingAttempts": 0
}
Réponses et erreurs Statut Signification 201Code envoyé.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/auth/login/{pendingLoginId}/verify
Terminer la connexion avec le second facteur
Vérifie le code TOTP, SMS ou de secours et ouvre la session sur ce nouvel appareil.
Authentification : Aucune (route publique)
Paramètres Nom Où Type Obligatoire Description pendingLoginIdchemin string oui Identifiant de la connexion en attente.
X-Device-Iden-tête string non Identifiant d'installation de l'application. Un appareil inconnu déclenche la double authentification.
Corps de la requête Nom Type Obligatoire Description methodstring oui totp · sms · backup_code
codestring oui challengeIdstring (uuid) non
Exemple de requête {
"method": "totp",
"code": "••••••"
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/auth/login/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/verify" \
-H "Content-Type: application/json" \
-d '{
"method": "totp",
"code": "••••••"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/auth/login/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/verify');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"method": "totp",
"code": "••••••"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/auth/login/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/verify",
json={
"method": "totp",
"code": "••••••"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/auth/login/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/verify", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"method": "totp",
"code": "••••••"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"tokenType": "Bearer",
"accessToken": "eyJ…",
"expiresIn": 900,
"refreshToken": "…",
"refreshExpiresIn": 2592000
}
Réponses et erreurs Statut Signification 200Connexion réussie.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/auth/refresh
Renouveler les jetons
Échange le jeton de rafraîchissement contre une nouvelle paire (rotation). Un jeton réutilisé révoque la session.
Authentification : Aucune (route publique)
Corps de la requête Nom Type Obligatoire Description refreshTokenstring oui
Exemple de requête {
"refreshToken": "…"
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/auth/refresh" \
-H "Content-Type: application/json" \
-d '{
"refreshToken": "…"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/auth/refresh');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"refreshToken": "…"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/auth/refresh",
json={
"refreshToken": "…"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/auth/refresh", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"refreshToken": "…"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"tokenType": "Bearer",
"accessToken": "eyJ…",
"expiresIn": 900,
"refreshToken": "…",
"refreshExpiresIn": 2592000
}
Réponses et erreurs Statut Signification 200Nouvelle paire de jetons.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/auth/logout
Se déconnecter
Révoque le jeton de rafraîchissement.
Authentification : Aucune (route publique)
Corps de la requête Nom Type Obligatoire Description refreshTokenstring oui
Exemple de requête {
"refreshToken": "…"
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/auth/logout" \
-H "Content-Type: application/json" \
-d '{
"refreshToken": "…"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/auth/logout');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"refreshToken": "…"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/auth/logout",
json={
"refreshToken": "…"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/auth/logout", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
"refreshToken": "…"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 204
Session fermée.
Réponses et erreurs Statut Signification 204Session fermée.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/me
Afficher mon profil
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/me" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/me",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"fullName": "texte",
"phone": "+243810000000",
"email": "client@example.com",
"status": "pending_verification",
"kycLevel": 1,
"accountMode": "wallet",
"twoFactor": {
"totp": true,
"sms": true,
"backupCodesRemaining": true
},
"consents": {
"termsAcceptanceRequired": true,
"pending": [
{
"document": "terms",
"version": "texte"
}
],
"biometric": true
}
}
Réponses et erreurs Statut Signification 200Profil du client connecté.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
PUT /v1/me/locale
Choisir la langue du compte
Langue choisie dans le profil de l'application (fr ou en). Les e-mails et SMS sont écrits dans cette langue. Les messages d'erreur de l'API suivent l'en-tête Accept-Language.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Corps de la requête Nom Type Obligatoire Description localestring oui fr · en
Exemple de requête {
"locale": "fr"
}
Exemple de code cURL PHP Python JavaScript
curl -X PUT "https://sandbox.api.linc.cd/v1/me/locale" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"locale": "fr"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/locale');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"locale": "fr"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.put(
"https://sandbox.api.linc.cd/v1/me/locale",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"locale": "fr"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/locale", {
method: "PUT",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"locale": "fr"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"locale": "fr"
}
Réponses et erreurs Statut Signification 200Langue enregistrée.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/me/consents/contract
Accepter la nouvelle version des documents du contrat
Accepte les versions actuelles des documents dont une nouvelle version attend l'acceptation (GET /v1/me, consents.pending) : une case par document en attente (Conditions générales, Politique de confidentialité, Politique LBC/FT), jamais cochée à la place du client. Le contrat d'utilisation qui les liste est accepté avec eux ; il a sa propre case (acceptContract) quand il est seul à avoir changé. Sans acceptation, le client peut lire (solde, historique) mais ne peut lancer aucune opération (403 contract_acceptance_required). Restent ouverts : la session, les appareils, le KYC, les réclamations et le retrait de ses propres fonds (POST /v1/wallet/withdrawal-codes, son annulation et le code SMS purpose: withdrawal).
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Corps de la requête Nom Type Obligatoire Description acceptTermsboolean non Case des Conditions générales, obligatoire si elles sont en attente.
acceptPrivacyboolean non Case de la Politique de confidentialité, obligatoire si elle est en attente.
acceptAmlboolean non Case de la Politique LBC/FT, obligatoire si elle est en attente.
acceptContractboolean non Case du contrat d'utilisation, obligatoire seulement s'il est seul en attente.
Exemple de requête {
"acceptTerms": false,
"acceptPrivacy": false,
"acceptAml": false,
"acceptContract": false
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/me/consents/contract" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"acceptTerms": false,
"acceptPrivacy": false,
"acceptAml": false,
"acceptContract": false
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/consents/contract');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"acceptTerms": false,
"acceptPrivacy": false,
"acceptAml": false,
"acceptContract": false
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/me/consents/contract",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"acceptTerms": False,
"acceptPrivacy": False,
"acceptAml": False,
"acceptContract": False
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/consents/contract", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"acceptTerms": false,
"acceptPrivacy": false,
"acceptAml": false,
"acceptContract": false
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"termsAcceptanceRequired": true,
"pending": [
{
"document": "terms",
"version": "texte"
}
],
"biometric": true
}
Réponses et erreurs Statut Signification 200Consentements à jour.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/me/consents/terms
Accepter les documents du contrat (ancien nom)
Ancien nom de POST /v1/me/consents/contract, conservé pour les premières versions des applications : même corps, mêmes cases à cocher par le client, mêmes réponses. Sans case cochée, la réponse est 422 contract_not_accepted (le serveur n'accepte jamais à la place du client). Réponse marquée Deprecation: true.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Corps de la requête Nom Type Obligatoire Description acceptTermsboolean non Case des Conditions générales, obligatoire si elles sont en attente.
acceptPrivacyboolean non Case de la Politique de confidentialité, obligatoire si elle est en attente.
acceptAmlboolean non Case de la Politique LBC/FT, obligatoire si elle est en attente.
acceptContractboolean non Case du contrat d'utilisation, obligatoire seulement s'il est seul en attente.
Exemple de requête {
"acceptTerms": false,
"acceptPrivacy": false,
"acceptAml": false,
"acceptContract": false
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/me/consents/terms" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"acceptTerms": false,
"acceptPrivacy": false,
"acceptAml": false,
"acceptContract": false
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/consents/terms');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"acceptTerms": false,
"acceptPrivacy": false,
"acceptAml": false,
"acceptContract": false
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/me/consents/terms",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"acceptTerms": False,
"acceptPrivacy": False,
"acceptAml": False,
"acceptContract": False
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/consents/terms", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"acceptTerms": false,
"acceptPrivacy": false,
"acceptAml": false,
"acceptContract": false
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"termsAcceptanceRequired": true,
"pending": [
{
"document": "terms",
"version": "texte"
}
],
"biometric": true
}
Réponses et erreurs Statut Signification 200Consentements à jour.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/me/consents/biometric
Consentir au traitement biométrique
Consentement explicite au traitement du visage, requis avant l'envoi d'un selfie ou d'images de vivacité.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/me/consents/biometric" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/consents/biometric');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/me/consents/biometric",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/consents/biometric", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"termsAcceptanceRequired": true,
"pending": [
{
"document": "terms",
"version": "texte"
}
],
"biometric": true
}
Réponses et erreurs Statut Signification 200Consentements à jour.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/me/documents
Mes documents
Les documents du contrat d'utilisation en vigueur (Conditions générales, Politique de confidentialité, Politique LBC/FT, contrat) avec, pour chacun, la version acceptée par le client, la date et le canal, le contrat accepté avec les versions des trois documents, et les documents dont une nouvelle version attend l'acceptation (POST /v1/me/consents/contract).
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/me/documents" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/documents');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/me/documents",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/documents", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"documents": [
{
"document": "terms",
"title": "texte",
"version": "texte",
"draft": true,
"accepted": {
"version": "texte",
"acceptedAt": "2026-10-01T09:30:00Z",
"channel": "web",
"agent": true
},
"upToDate": true
}
],
"contract": {
"version": "texte",
"acceptedAt": "2026-10-01T09:30:00Z",
"channel": "web",
"agent": true,
"documents": {},
"upToDate": true,
"reference": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f"
},
"pending": [
"terms"
]
}
Réponses et erreurs Statut Signification 200Documents et preuves d'acceptation.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
PUT /v1/me/account-mode
Choisir le mode de compte
wallet conserve un solde chez Linc. pass_through débite directement le mobile money.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Corps de la requête Nom Type Obligatoire Description modestring oui wallet · pass_through
Exemple de requête {
"mode": "wallet"
}
Exemple de code cURL PHP Python JavaScript
curl -X PUT "https://sandbox.api.linc.cd/v1/me/account-mode" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"mode": "wallet"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/account-mode');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"mode": "wallet"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.put(
"https://sandbox.api.linc.cd/v1/me/account-mode",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"mode": "wallet"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/account-mode", {
method: "PUT",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"mode": "wallet"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"accountMode": "wallet"
}
Réponses et erreurs Statut Signification 200Mode enregistré.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/me/communications
Afficher les choix de communication
Nouveautés de Linc par e-mail et par SMS, envoyées seulement avec l'accord du client. Les codes, reçus et alertes de sécurité sont toujours envoyés.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/me/communications" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/communications');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/me/communications",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/communications", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"email": true,
"sms": true
}
Réponses et erreurs Statut Signification 200Choix en cours.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
PUT /v1/me/communications
Choisir les communications
Oui ou non pour chaque canal. Chaque choix est conservé comme preuve du consentement.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Corps de la requête Nom Type Obligatoire Description emailboolean oui Nouveautés par e-mail (à une adresse vérifiée seulement).
smsboolean oui Nouveautés par SMS, de 8 h à 20 h (heure de Kinshasa). Répondre STOP les arrête.
Exemple de requête {
"email": true,
"sms": true
}
Exemple de code cURL PHP Python JavaScript
curl -X PUT "https://sandbox.api.linc.cd/v1/me/communications" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email": true,
"sms": true
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/communications');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"email": true,
"sms": true
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.put(
"https://sandbox.api.linc.cd/v1/me/communications",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"email": True,
"sms": True
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/communications", {
method: "PUT",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"email": true,
"sms": true
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"email": true,
"sms": true
}
Réponses et erreurs Statut Signification 200Choix enregistrés.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/me/security/two-factor
Afficher l'état de la double authentification
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/me/security/two-factor" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/security/two-factor');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/me/security/two-factor",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/security/two-factor", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"totp": true,
"sms": true,
"backupCodesRemaining": true,
"availableMethods": [
"totp"
]
}
Réponses et erreurs Statut Signification 200Méthodes actives et méthodes utilisables.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/me/security/otp
Recevoir un code SMS de confirmation
Envoie un code SMS pour confirmer une opération sensible. Utilisez le challengeId retourné dans twoFactor.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Corps de la requête Nom Type Obligatoire Description purposestring oui security_change · transfer · payment · withdrawal · card_reveal · card_management · card_add · beneficiary_add
Exemple de requête {
"purpose": "security_change"
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/me/security/otp" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"purpose": "security_change"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/security/otp');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"purpose": "security_change"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/me/security/otp",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"purpose": "security_change"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/security/otp", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"purpose": "security_change"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"purpose": "phone_verification",
"sentTo": "texte",
"expiresAt": "2026-10-01T09:30:00Z",
"remainingAttempts": 0
}
Réponses et erreurs Statut Signification 201Code envoyé.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/me/security/password
Changer le mot de passe
Exige le mot de passe actuel et un second facteur. Les autres sessions sont fermées.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Corps de la requête Nom Type Obligatoire Description currentPasswordstring oui newPasswordstring oui twoFactorobject oui Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring oui totp · sms · backup_code
twoFactor.codestring oui twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"currentPassword": "••••••••",
"newPassword": "••••••••",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/me/security/password" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"currentPassword": "••••••••",
"newPassword": "••••••••",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/security/password');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"currentPassword": "••••••••",
"newPassword": "••••••••",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/me/security/password",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"currentPassword": "••••••••",
"newPassword": "••••••••",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/security/password", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"currentPassword": "••••••••",
"newPassword": "••••••••",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 204
Mot de passe changé.
Réponses et erreurs Statut Signification 204Mot de passe changé.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/me/security/totp/setup
Commencer l'activation TOTP
Retourne le secret et l'URI otpauth:// à afficher en QR code. Second facteur requis.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Corps de la requête Nom Type Obligatoire Description twoFactorobject non Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring non totp · sms · backup_code
twoFactor.codestring non twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/me/security/totp/setup" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/security/totp/setup');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/me/security/totp/setup",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"twoFactor": {
"method": "totp",
"code": "••••••"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/security/totp/setup", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"secret": "••••••••",
"uri": "texte"
}
Réponses et erreurs Statut Signification 201Secret généré, en attente de confirmation.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/me/security/totp/confirm
Confirmer l'activation TOTP
Valide un premier code de l'application. Retourne les codes de secours, affichés une seule fois.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Corps de la requête Nom Type Obligatoire Description codestring oui Code à 6 chiffres de l'application d'authentification.
Exemple de requête {
"code": "••••••"
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/me/security/totp/confirm" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"code": "••••••"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/security/totp/confirm');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"code": "••••••"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/me/security/totp/confirm",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"code": "••••••"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/security/totp/confirm", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"code": "••••••"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"backupCodes": [
"123456"
]
}
Réponses et erreurs Statut Signification 200TOTP activé.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/me/security/totp/disable
Désactiver TOTP
Second facteur requis.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Corps de la requête Nom Type Obligatoire Description twoFactorobject non Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring non totp · sms · backup_code
twoFactor.codestring non twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/me/security/totp/disable" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/security/totp/disable');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/me/security/totp/disable",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"twoFactor": {
"method": "totp",
"code": "••••••"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/security/totp/disable", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 204
TOTP désactivé.
Réponses et erreurs Statut Signification 204TOTP désactivé.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
PUT /v1/me/security/sms
Activer ou désactiver la double authentification par SMS
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Corps de la requête Nom Type Obligatoire Description enabledboolean oui twoFactorobject non Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring non totp · sms · backup_code
twoFactor.codestring non twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"enabled": true
}
Exemple de code cURL PHP Python JavaScript
curl -X PUT "https://sandbox.api.linc.cd/v1/me/security/sms" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"enabled": true
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/security/sms');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"enabled": true
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.put(
"https://sandbox.api.linc.cd/v1/me/security/sms",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"enabled": True
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/security/sms", {
method: "PUT",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"enabled": true
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"totp": true,
"sms": true,
"backupCodesRemaining": true
}
Réponses et erreurs Statut Signification 200Nouvel état de la double authentification.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/me/security/backup-codes
Régénérer les codes de secours
Invalide les anciens codes. TOTP actif et second facteur requis.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Corps de la requête Nom Type Obligatoire Description twoFactorobject non Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring non totp · sms · backup_code
twoFactor.codestring non twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/me/security/backup-codes" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/security/backup-codes');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/me/security/backup-codes",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"twoFactor": {
"method": "totp",
"code": "••••••"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/security/backup-codes", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"backupCodes": [
"123456"
]
}
Réponses et erreurs Statut Signification 200Nouveaux codes, affichés une seule fois.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/legal
Lister les documents légaux en vigueur
Versions à accepter à l'inscription (public).
Authentification : Aucune (route publique)
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/legal"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/legal');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/legal",
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/legal", {
method: "GET",
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"documents": [
{
"document": "terms",
"title": "texte",
"version": "texte",
"date": "1990-01-31",
"draft": true,
"url": "https://example.com"
}
]
}
Réponses et erreurs Statut Signification 200Documents légaux.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/kyc/cases
Ouvrir un dossier KYC
Ouvre un dossier pour le niveau 2 (identité vérifiée) ou 3 (vigilance renforcée).
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Opération financière : envoyez un Idempotency-Key unique par opération (rejoué 24 h).
Paramètres Nom Où Type Obligatoire Description Idempotency-Keyen-tête string oui Identifiant unique de l'opération (par exemple un UUID), conservé 24 h. Une même clé avec le même corps rejoue la réponse d'origine. Avec un autre corps : 422 idempotency_key_reused. Pendant le traitement : 409 idempotency_in_progress.
Corps de la requête Nom Type Obligatoire Description targetLevelinteger oui 2 · 3
documentTypestring non voter_card · passport · driving_license · national_id
documentNumberstring non issuingCountrystring non residenceCountrystring non Pays de résidence (ISO 3166 alpha-2), niveau 2. Une fois le dossier approuvé, il remplace l'indicatif du téléphone pour les services ouverts par pays.
birthDatestring (date) non addressstring non occupationstring non sourceOfFundsstring non expectedMonthlyAmountstring non Montant mensuel attendu en USD (décimal en texte), par exemple 1500.00.
documentExpiresOnstring (date) non Date d'expiration imprimée sur la pièce (niveau 2). Aucune lecture automatique en mode manual_review ; une pièce expirée est refusée.
nationalitystring non Nationalité (ISO 3166 alpha-2), niveau 2. Par défaut, le pays qui a délivré la pièce.
residencePermitNumberstring non Numéro du titre de séjour (carte de résident). Exigé quand la nationalité ou la pièce n'est pas celle du pays de résidence (étranger résidant) : requiredDocuments comprend alors son recto et son verso, et la conformité vérifie le dossier.
residencePermitExpiresOnstring (date) non Date d'expiration du titre de séjour ; son renouvellement suit celui de la pièce.
Exemple de requête {
"targetLevel": 2
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/kyc/cases" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"targetLevel": 2
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/kyc/cases');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"targetLevel": 2
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import uuid
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/kyc/cases",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"targetLevel": 2
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/kyc/cases", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json" },
body: JSON.stringify({
"targetLevel": 2
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"reference": "LP-7K2Q4F",
"targetLevel": 2,
"status": "draft",
"message": "texte",
"requiredDocuments": [
"id_front"
],
"optionalDocuments": [
"id_front"
],
"uploadedDocuments": [
"id_front"
],
"livenessChallenges": [
{
"code": "turn_left",
"instruction": "texte"
}
],
"captureSteps": [
{
"kind": "id_front",
"challenge": "turn_left",
"label": "texte",
"done": true
}
],
"documentExpiresOn": "1990-01-31",
"reviewHours": 0,
"submittedAt": "2026-10-01T09:30:00Z",
"decidedAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 201Dossier ouvert.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/kyc/cases/current
Afficher mon dossier KYC en cours
Niveau actuel et dernier dossier. Interrogez cette route pour suivre la décision.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/kyc/cases/current" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/kyc/cases/current');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/kyc/cases/current",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/kyc/cases/current", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"kycLevel": 1,
"case": {
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"reference": "LP-7K2Q4F",
"targetLevel": 2,
"status": "draft",
"message": "texte",
"requiredDocuments": [
"id_front"
],
"optionalDocuments": [
"id_front"
],
"uploadedDocuments": [
"id_front"
],
"livenessChallenges": [
{
"code": "turn_left",
"instruction": "texte"
}
],
"captureSteps": [
{
"kind": "id_front",
"challenge": "turn_left",
"label": "texte",
"done": true
}
],
"documentExpiresOn": "1990-01-31",
"reviewHours": 0,
"submittedAt": "2026-10-01T09:30:00Z",
"decidedAt": "2026-10-01T09:30:00Z"
}
}
Réponses et erreurs Statut Signification 200Niveau KYC et dossier (ou null).
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/kyc/cases/{id}/documents/{kind}
Ajouter un document au dossier KYC
Envoie une photo dans le champ multipart file (capture guidée). Au niveau 2, la pièce et le visage viennent de la caméra (captureSource=camera) : un fichier choisi est refusé (kyc_camera_required). Chaque image du vivant indique sa consigne (challenge). Taille minimale (côté long) : 1000 px pour la pièce, 480 px pour le visage (kyc_image_too_small). Le selfie et les images du vivant exigent le consentement biométrique.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui Identifiant du dossier.
kindchemin string oui Type de document.
Corps de la requête Fichier envoyé en multipart/form-data.
Nom Type Obligatoire Description filestring oui Photo du document (JPEG, PNG ou PDF).
captureSourcestring non Origine de l'image ; camera obligatoire pour la pièce et le visage au niveau 2.
camera · handoff · upload
challengestring non Consigne du contrôle du vivant actif.
turn_left · turn_right · blink · smile · look_up
brightnessinteger non Luminosité moyenne mesurée par l'application avant l'envoi.
sharpnessinteger non Netteté mesurée par l'application (variance du laplacien).
glareinteger non Part de pixels brûlés (reflet), en millièmes.
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/kyc/cases/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/documents/id_front" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-F "file=@document.jpg"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/kyc/cases/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/documents/id_front');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_POSTFIELDS => ['file' => new CURLFile('document.jpg')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/kyc/cases/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/documents/id_front",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
files={"file": open("document.jpg", "rb")},
timeout=30,
)
print(answer.status_code, answer.text)import { openAsBlob } from "node:fs";
const form = new FormData();
form.append("file", await openAsBlob("document.jpg"), "document.jpg");
const answer = await fetch("https://sandbox.api.linc.cd/v1/kyc/cases/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/documents/id_front", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
body: form,
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"document": {
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"kind": "id_front",
"size": 0
},
"case": {
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"reference": "LP-7K2Q4F",
"targetLevel": 2,
"status": "draft",
"message": "texte",
"requiredDocuments": [
"id_front"
],
"optionalDocuments": [
"id_front"
],
"uploadedDocuments": [
"id_front"
],
"livenessChallenges": [
{
"code": "turn_left",
"instruction": "texte"
}
],
"captureSteps": [
{
"kind": "id_front",
"challenge": "turn_left",
"label": "texte",
"done": true
}
],
"documentExpiresOn": "1990-01-31",
"reviewHours": 0,
"submittedAt": "2026-10-01T09:30:00Z",
"decidedAt": "2026-10-01T09:30:00Z"
}
}
Réponses et erreurs Statut Signification 201Document ajouté.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/kyc/cases/{id}/submit
Envoyer le dossier KYC
Lance la vérification. Le résultat arrive de façon asynchrone (SMS et GET /v1/kyc/cases/current).
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Opération financière : envoyez un Idempotency-Key unique par opération (rejoué 24 h).
Paramètres Nom Où Type Obligatoire Description idchemin string oui Identifiant du dossier.
Idempotency-Keyen-tête string oui Identifiant unique de l'opération (par exemple un UUID), conservé 24 h. Une même clé avec le même corps rejoue la réponse d'origine. Avec un autre corps : 422 idempotency_key_reused. Pendant le traitement : 409 idempotency_in_progress.
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/kyc/cases/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/submit" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/kyc/cases/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/submit');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16))],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import uuid
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/kyc/cases/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/submit",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/kyc/cases/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/submit", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Idempotency-Key": crypto.randomUUID() },
});
console.log(answer.status, await answer.text());
Exemple de réponse 202
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"reference": "LP-7K2Q4F",
"targetLevel": 2,
"status": "draft",
"message": "texte",
"requiredDocuments": [
"id_front"
],
"optionalDocuments": [
"id_front"
],
"uploadedDocuments": [
"id_front"
],
"livenessChallenges": [
{
"code": "turn_left",
"instruction": "texte"
}
],
"captureSteps": [
{
"kind": "id_front",
"challenge": "turn_left",
"label": "texte",
"done": true
}
],
"documentExpiresOn": "1990-01-31",
"reviewHours": 0,
"submittedAt": "2026-10-01T09:30:00Z",
"decidedAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 202Dossier envoyé, vérification en cours.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/corridors
Lister les corridors ouverts
Pays de destination, devises et modes de réception ouverts (public). Un pays fermé, ou dont tous les corridors sont fermés, n'apparaît pas ; un corridor fermé (mode de réception d'un pays) n'est pas dans payoutMethods (« Partenaires › Pays et corridors », docs/adr/0068). Les devis suivent aussitôt.
Authentification : Aucune (route publique)
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/corridors"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/corridors');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/corridors",
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/corridors", {
method: "GET",
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"corridors": [
{
"country": "CI",
"name": "Côte d’Ivoire",
"currency": "XOF",
"currencies": [
"XOF"
],
"payoutMethods": [
"mobile_money",
"bank_account",
"card"
]
},
{
"country": "CA",
"name": "Canada",
"currency": "CAD",
"currencies": [
"CAD",
"USD"
],
"payoutMethods": [
"bank_account",
"card"
]
}
]
}
Réponses et erreurs Statut Signification 200Corridors ouverts.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/journeys
Lister les parcours ouverts pour le client
Parcours de paiement (source → destination) ouverts pour le client authentifié vers un pays, et une devise de réception si elle est donnée (« Partenaires › Parcours », docs/adr/0083). Seuls ces parcours sont à proposer : ils tiennent compte de l'état du parcours, du pays, du niveau KYC, de la population (liste pilote, segment) et du mode de compte. Les autres verrous (corridors, partenaires) restent ceux de listCorridors et du devis ; chaque devis, envoi et paiement revérifie le parcours et refuse sinon avec operation_unavailable.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description countryrequête string oui Pays de destination (le pays du marchand pour un paiement, CD pour le solde).
currencyrequête string non Devise reçue ; absente, toute devise.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/journeys?country=KE" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/journeys?country=KE');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/journeys?country=KE",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/journeys?country=KE", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"country": "KE",
"currency": "USD",
"journeys": [
{
"source": "card_visa_aft",
"destination": "card_visa"
}
]
}
Réponses et erreurs Statut Signification 200Parcours ouverts pour ce client.
422journey_query_invalid : country n'est pas un code pays ISO à deux lettres, ou currency n'est pas une devise connue de Linc.
Erreur au format application/problem+json : voir « Erreurs ».
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/quotes
Demander un devis
Frais, taux, total débité et montant reçu, verrouillés 60 s. Au plus 20 devis par minute et par client (renouvellements compris) : au-delà, 429 too_many_quotes.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Opération financière : envoyez un Idempotency-Key unique par opération (rejoué 24 h).
Paramètres Nom Où Type Obligatoire Description Idempotency-Keyen-tête string oui Identifiant unique de l'opération (par exemple un UUID), conservé 24 h. Une même clé avec le même corps rejoue la réponse d'origine. Avec un autre corps : 422 idempotency_key_reused. Pendant le traitement : 409 idempotency_in_progress.
Corps de la requête Nom Type Obligatoire Description amountstring non Montant envoyé en décimal (texte), par exemple 150.00. Ancien nom de sendAmount.
sendAmountstring non Montant envoyé en décimal (texte), par exemple 150.00.
receiveAmountstring non Montant à recevoir dans la devise reçue, avec ses décimales (XOF 0, KWD 3), par exemple 50000.
totalAmountstring non Total payé par le client dans la devise envoyée, frais déduits, par exemple 100.00.
operatorstring non Facultatif (mobile_money) : opérateur du wallet du bénéficiaire, son nom ou son code (operators de GET /v1/reference/destination-formats). La ligne de la grille du partenaire pour cet opérateur s'applique au devis. Inconnu : ignoré.
msisdnstring non Facultatif (mobile_money) : numéro du bénéficiaire, l'opérateur est déduit de son préfixe quand operator est absent.
currencystring oui Code devise ISO 4217.
destinationCountrystring oui payoutMethodstring oui cash_pickup : retrait d'espèces avec un code dans le réseau Mastercard, là où il est ouvert (bénéficiaire : nom exactement comme sur sa pièce et téléphone).
mobile_money · bank_account · card · cash_pickup
receiveCurrencystring non Une des devises du corridor. Vide = devise principale du corridor.
sourceTypestring non Source des fonds. card (carte bancaire, AFT) a ses propres frais ; le devis ne sert alors qu'à un envoi par carte. card_interswitch : carte sur la page de paiement Interswitch, frais propres, parcours fermé par défaut.
· mobile_money · wallet · card · card_interswitch
Exemple de requête {
"amount": "150.00",
"currency": "USD",
"destinationCountry": "CI",
"payoutMethod": "mobile_money",
"sourceType": "mobile_money"
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/quotes" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"amount": "150.00",
"currency": "USD",
"destinationCountry": "CI",
"payoutMethod": "mobile_money",
"sourceType": "mobile_money"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/quotes');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"amount": "150.00",
"currency": "USD",
"destinationCountry": "CI",
"payoutMethod": "mobile_money",
"sourceType": "mobile_money"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import uuid
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/quotes",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"amount": "150.00",
"currency": "USD",
"destinationCountry": "CI",
"payoutMethod": "mobile_money",
"sourceType": "mobile_money"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/quotes", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json" },
body: JSON.stringify({
"amount": "150.00",
"currency": "USD",
"destinationCountry": "CI",
"payoutMethod": "mobile_money",
"sourceType": "mobile_money"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"id": "0192a7c4-5b1e-7c3a-9f10-3d2e8b6a4c11",
"send": {
"amount": 15000,
"currency": "USD",
"display": "150,00 $"
},
"fee": {
"amount": 325,
"currency": "USD",
"display": "3,25 $"
},
"vat": {
"amount": 52,
"currency": "USD",
"display": "0,52 $"
},
"levy": {
"amount": 30,
"currency": "USD",
"display": "0,30 $"
},
"total": {
"amount": 15407,
"currency": "USD",
"display": "154,07 $"
},
"receive": {
"amount": 84900,
"currency": "XOF",
"display": "84 900 FCFA"
},
"rate": "566.00",
"destinationCountry": "CI",
"payoutMethod": "mobile_money",
"createdAt": "2026-09-29T14:00:00+00:00",
"expiresAt": "2026-09-29T14:01:00+00:00",
"consumed": false,
"sourceType": null
}
Réponses et erreurs Statut Signification 201Devis créé.
422Refus métier (Problem.code), dont journey_limit_exceeded : le montant dépasse un plafond du parcours de paiement (par envoi, par jour ou par mois, en USD quelle que soit la devise envoyée, docs/adr/0083). detail donne le plafond atteint (« 30.00 USD »). Un parcours fermé répond operation_unavailable (403), sans motif.
Erreur au format application/problem+json : voir « Erreurs ».
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/quotes/preview
Aperçu du prix pendant la saisie
Prix indicatif dans tous les sens : sendAmount (ou amount), receiveAmount ou totalAmount (« frais déduits », là où le corridor l'offre) — deux ou aucun → 422 amount_ambiguous. Un total qui ne couvre pas les frais → 422 total_below_fees ; un prix à perte → 422 margin_too_low. Rien n'est enregistré, aucun taux n'est verrouillé ; les plafonds du client sont vérifiés pour le dire tout de suite. Le devis (POST /v1/quotes) est demandé quand le client continue. Plus de 12 chiffres avant la virgule, ou un montant trop grand pour être calculé → 422 amount_too_large.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description destinationCountryrequête string oui payoutMethodrequête string oui currencyrequête string non Devise envoyée (USD par défaut).
sendAmountrequête string non amountrequête string non Ancien nom de sendAmount.
receiveAmountrequête string non totalAmountrequête string non Total payé par le client dans la devise envoyée
receiveCurrencyrequête string non sourceTyperequête string non operatorrequête string non Opérateur du wallet du bénéficiaire (nom ou code), pour sa ligne de la grille du partenaire.
msisdnrequête string non Numéro du bénéficiaire : opérateur déduit du préfixe sans operator.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/quotes/preview?destinationCountry=KE&payoutMethod=mobile_money" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/quotes/preview?destinationCountry=KE&payoutMethod=mobile_money');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/quotes/preview?destinationCountry=KE&payoutMethod=mobile_money",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/quotes/preview?destinationCountry=KE&payoutMethod=mobile_money", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"typed": "send",
"send": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"fee": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"vat": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"levy": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"total": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"receive": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"rate": "texte"
}
Réponses et erreurs Statut Signification 200Prix indicatif.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/quotes/{id}
Afficher un devis
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui Identifiant du devis.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/quotes/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/quotes/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/quotes/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/quotes/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"send": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"fee": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"vat": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"levy": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"total": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"receive": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"rate": "texte",
"destinationCountry": "KE",
"payoutMethod": "mobile_money",
"createdAt": "2026-10-01T09:30:00Z",
"expiresAt": "2026-10-01T09:30:00Z",
"consumed": true,
"sourceType": "card"
}
Réponses et erreurs Statut Signification 200Devis.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/reference/banks
Chercher une banque du pays pendant la frappe
Banques du référentiel du pays, cherchées par nom, sigle, BIC ou code national (sort code, code banque) ; au plus 20, une par banque, à partir de 2 caractères (liste vide avant). « Autre banque » reste possible : nom et BIC saisis. Public, limité par adresse (429 au-delà).
Authentification : Aucune (route publique)
Paramètres Nom Où Type Obligatoire Description countryrequête string oui Pays de la banque (ISO 3166-1 alpha-2).
qrequête string non Début ou partie du nom, du sigle, du BIC ou du code de la banque ; 2 caractères au moins.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/reference/banks?country=KE"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/reference/banks?country=KE');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/reference/banks?country=KE",
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/reference/banks?country=KE", {
method: "GET",
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"banks": [
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"name": "texte"
}
]
}
Réponses et erreurs Statut Signification 200Banques trouvées (vide pour un pays inconnu).
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/reference/destination-formats
Formats de destination d'un pays
Opérateurs de mobile money avec les préfixes et longueurs de leurs numéros (l'opérateur est détecté d'après le numéro : un seul possible → présélectionné, plusieurs → proposés en premier, aucun → message) et longueur de l'IBAN du pays (registre officiel) pour dire exactement ce qui manque, et schémas de compte du pays (IBAN, RIB, sort code…, le schéma par défaut en premier) avec leurs champs : l'application affiche les champs du schéma choisi et envoie scheme avec eux. Le serveur revérifie tout à l'enregistrement du bénéficiaire. Public, limité par adresse (429 au-delà).
Authentification : Aucune (route publique)
Paramètres Nom Où Type Obligatoire Description countryrequête string oui Pays du bénéficiaire (ISO 3166-1 alpha-2).
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/reference/destination-formats?country=KE"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/reference/destination-formats?country=KE');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/reference/destination-formats?country=KE",
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/reference/destination-formats?country=KE", {
method: "GET",
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"country": "KE",
"name": "texte",
"operators": [
{
"code": "mpesa",
"name": "M-Pesa",
"prefixes": [
"texte"
],
"lengths": [
0
]
}
],
"accountSchemes": [
{
"code": "rib",
"label": "RIB (UEMOA)",
"fields": [
{
"detail": "accountNumber",
"label": "texte",
"required": true,
"maxLength": 0,
"numeric": true,
"iban": true,
"choices": []
}
]
}
]
}
Réponses et erreurs Statut Signification 200Formats du pays (listes vides pour un pays inconnu).
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/beneficiaries
Lister mes bénéficiaires
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/beneficiaries" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/beneficiaries');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/beneficiaries",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/beneficiaries", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"beneficiaries": [
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"fullName": "texte",
"country": "KE",
"payoutMethod": "mobile_money",
"destination": "texte"
}
]
}
Réponses et erreurs Statut Signification 200Bénéficiaires enregistrés.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/beneficiaries
Ajouter un bénéficiaire
Les coordonnées complètes restent chez Linc. La réponse les affiche masquées. Selon les contrôles de sécurité de l'opération, la réponse peut être two_factor_required : redemandez avec twoFactor (code de l'application d'authentification, ou code SMS obtenu par POST /v1/me/security/otp avec purpose = beneficiary_add). Une opération qui ne peut pas aboutir répond operation_unavailable (403), sans motif : ce code est commun à plusieurs refus.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Corps de la requête Nom Type Obligatoire Description fullNamestring oui countrystring oui payoutMethodstring oui cash_pickup : retrait d'espèces avec un code dans le réseau Mastercard, là où il est ouvert (bénéficiaire : nom exactement comme sur sa pièce et téléphone).
mobile_money · bank_account · card · cash_pickup
detailsobject non Coordonnées selon le mode (msisdn, provider, bankName, accountNumber, bankCode, cardToken…). Compte bancaire : de préférence scheme (code d'un schéma de GET /v1/reference/destination-formats) et les champs de ce schéma (accountNumber pour un RIB, bankCode + accountNumber pour un sort code…), bankId d'une banque de la liste ; sans scheme, iban ou accountNumber comme avant. bankCode (compte bancaire, facultatif) : sort code (Royaume-Uni, 6 chiffres), ABA (États-Unis, 9 chiffres) ou code banque ou guichet (3 à 15 lettres ou chiffres) ; espaces et tirets ignorés. Facultatif pour tous les modes : relationship (lien avec l'expéditeur : family, friend, self, business, other), exigé par certains corridors.
twoFactorobject non Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring non totp · sms · backup_code
twoFactor.codestring non twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"fullName": "Bastian Kelyan",
"country": "CI",
"payoutMethod": "mobile_money",
"details": {
"msisdn": "+2250700000000",
"provider": "orange",
"relationship": "family"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/beneficiaries" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"fullName": "Bastian Kelyan",
"country": "CI",
"payoutMethod": "mobile_money",
"details": {
"msisdn": "+2250700000000",
"provider": "orange",
"relationship": "family"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/beneficiaries');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"fullName": "Bastian Kelyan",
"country": "CI",
"payoutMethod": "mobile_money",
"details": {
"msisdn": "+2250700000000",
"provider": "orange",
"relationship": "family"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/beneficiaries",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"fullName": "Bastian Kelyan",
"country": "CI",
"payoutMethod": "mobile_money",
"details": {
"msisdn": "+2250700000000",
"provider": "orange",
"relationship": "family"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/beneficiaries", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"fullName": "Bastian Kelyan",
"country": "CI",
"payoutMethod": "mobile_money",
"details": {
"msisdn": "+2250700000000",
"provider": "orange",
"relationship": "family"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"id": "0192a7c4-6f02-7a55-8e21-7b4c0d9e2f33",
"fullName": "Bastian Kelyan",
"country": "CI",
"payoutMethod": "mobile_money",
"destination": "Orange Money •• 0000"
}
Réponses et erreurs Statut Signification 201Bénéficiaire ajouté.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
PATCH /v1/beneficiaries/{id}
Compléter le code banque d'un bénéficiaire
Ajoute le code banque (bankCode) d'un bénéficiaire à compte bancaire enregistré sans lui, quand l'envoi répond corridor_fields_missing avec bank_code. Contrôle selon le pays : sort code au Royaume-Uni (6 chiffres), ABA aux États-Unis (9 chiffres), 3 à 15 lettres ou chiffres ailleurs ; espaces et tirets ignorés. Un code déjà enregistré n'est jamais remplacé (beneficiary_bank_code_set, 409 : une autre banque est un autre bénéficiaire) ; le même code ne change rien. Contrôles de sécurité de l'ajout d'un bénéficiaire : la réponse peut être two_factor_required, redemandez avec twoFactor (purpose = beneficiary_add).
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui Identifiant du bénéficiaire.
Corps de la requête Nom Type Obligatoire Description bankCodestring oui Sort code (Royaume-Uni), ABA (États-Unis) ou code banque ou guichet.
twoFactorobject non Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring non totp · sms · backup_code
twoFactor.codestring non twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"bankCode": "123456"
}
Exemple de code cURL PHP Python JavaScript
curl -X PATCH "https://sandbox.api.linc.cd/v1/beneficiaries/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"bankCode": "123456"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/beneficiaries/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"bankCode": "123456"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.patch(
"https://sandbox.api.linc.cd/v1/beneficiaries/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"bankCode": "123456"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/beneficiaries/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f", {
method: "PATCH",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"bankCode": "123456"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"fullName": "texte",
"country": "KE",
"payoutMethod": "mobile_money",
"destination": "texte"
}
Réponses et erreurs Statut Signification 200Bénéficiaire complété (coordonnées masquées).
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
DELETE /v1/beneficiaries/{id}
Supprimer un bénéficiaire
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui Identifiant du bénéficiaire.
Exemple de code cURL PHP Python JavaScript
curl -X DELETE "https://sandbox.api.linc.cd/v1/beneficiaries/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/beneficiaries/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.delete(
"https://sandbox.api.linc.cd/v1/beneficiaries/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/beneficiaries/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 204
Bénéficiaire supprimé.
Réponses et erreurs Statut Signification 204Bénéficiaire supprimé.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/beneficiaries/{id}/purposes
Motifs d'envoi proposés pour ce bénéficiaire
Motifs que le corridor accepte : sur Visa Direct et Mastercard Cross-Border, seuls ceux qui ont un code partenaire pour le pays (rail principal, ou secours s'il prend le relais) ; tous sur les autres rails. Liste vide : ne demandez pas de motif. Avec quoteId, la devise reçue du devis.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui Identifiant du bénéficiaire.
quoteIdrequête string non Devis en cours (devise reçue). Par défaut, la devise principale du corridor.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/beneficiaries/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/purposes" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/beneficiaries/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/purposes');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/beneficiaries/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/purposes",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/beneficiaries/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/purposes", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"purposes": [
{
"code": "family_support",
"label": "texte"
}
]
}
Réponses et erreurs Statut Signification 200Motifs proposés, dans l'ordre d'affichage.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/transfers
Lister mes envois
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/transfers" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/transfers');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/transfers",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/transfers", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"transfers": [
{
"reference": "LP-7K2Q4F",
"status": "in_progress",
"steps": [
{
"label": "texte",
"done": true
}
],
"beneficiary": "texte",
"destination": "texte",
"country": "KE",
"source": "texte",
"sourceType": "mobile_money",
"send": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"fee": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"vat": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"levy": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"total": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"receive": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"rate": "texte",
"createdAt": "2026-10-01T09:30:00Z",
"deliveredAt": "2026-10-01T09:30:00Z",
"refundedAt": "2026-10-01T09:30:00Z"
}
]
}
Réponses et erreurs Statut Signification 200Envois du client, du plus récent au plus ancien.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/transfers
Envoyer de l'argent
Confirme un devis vers un bénéficiaire. Second facteur requis. Le traitement est asynchrone (suivez les étapes). Un client dont le pays de résidence n'est pas un pays d'origine autorisé est refusé (origin_not_allowed, 403) avant tout prélèvement ; la conformité est alertée.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Opération financière : envoyez un Idempotency-Key unique par opération (rejoué 24 h).
Paramètres Nom Où Type Obligatoire Description Idempotency-Keyen-tête string oui Identifiant unique de l'opération (par exemple un UUID), conservé 24 h. Une même clé avec le même corps rejoue la réponse d'origine. Avec un autre corps : 422 idempotency_key_reused. Pendant le traitement : 409 idempotency_in_progress.
X-Linc-Attestationen-tête string non Assertion de l'installation attestée, pour une opération sensible. Hachage de la requête : base64url(SHA-256(METHOD "\n" PATH "\n" Idempotency-Key "\n" hex(SHA-256(corps)))). Android : jeton Play Integrity (requête standard) avec ce requestHash. iOS : assertion App Attest (CBOR en base64) sur le SHA-256 de ce hachage. Absente ou invalide quand la politique l'exige : 403 attestation_required.
Corps de la requête Nom Type Obligatoire Description quoteIdstring (uuid) oui beneficiaryIdstring (uuid) oui sourceobject oui source.typestring oui wallet : mode wallet uniquement. card : carte bancaire du client (KYC niveau 2), payée ensuite sur la page carte (GET /v1/transfers/{reference}/card-checkout) avec 3-D Secure ; le devis doit être un devis carte. card_interswitch : carte (ou mobile money) payée sur la page d'Interswitch (Web Checkout), option fermée par défaut et ouverte parcours par parcours ; KYC niveau 2, devis sourceType=card_interswitch, puis GET /v1/transfers/{reference}/checkout.
mobile_money · wallet · card · card_interswitch
source.providerstring non airtel · mpesa · orange · afrimoney
source.msisdnstring non source.savedWalletIdstring (uuid) non Source mobile_money : porte-monnaie enregistré vérifié (GET /v1/saved-wallets) ; opérateur et numéro en sont lus, provider et msisdn sont ignorés. Refusé (saved_wallet_not_verified, saved_wallet_not_found) s'il n'est pas au client ou pas vérifié.
source.savedCardIdstring (uuid) non Source card : carte enregistrée choisie dans le devis (GET /v1/saved-cards), proposée sur la page carte sans ressaisie.
purposestring non Motif de l'envoi déclaré par le client, parmi ceux de GET /v1/beneficiaries/{id}/purposes (sinon transfer_purpose_not_offered). Facultatif quand la liste est vide ; un corridor qui exige un motif refuse la création sans lui (corridor_fields_missing).
family_support · education · medical · gift · savings · bills · business · salary · goods_services · other
twoFactorobject oui Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring oui totp · sms · backup_code
twoFactor.codestring oui twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"quoteId": "0192a7c4-5b1e-7c3a-9f10-3d2e8b6a4c11",
"beneficiaryId": "0192a7c4-6f02-7a55-8e21-7b4c0d9e2f33",
"source": {
"type": "mobile_money",
"provider": "airtel",
"msisdn": "+243970000000"
},
"purpose": "family_support",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/transfers" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"quoteId": "0192a7c4-5b1e-7c3a-9f10-3d2e8b6a4c11",
"beneficiaryId": "0192a7c4-6f02-7a55-8e21-7b4c0d9e2f33",
"source": {
"type": "mobile_money",
"provider": "airtel",
"msisdn": "+243970000000"
},
"purpose": "family_support",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/transfers');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"quoteId": "0192a7c4-5b1e-7c3a-9f10-3d2e8b6a4c11",
"beneficiaryId": "0192a7c4-6f02-7a55-8e21-7b4c0d9e2f33",
"source": {
"type": "mobile_money",
"provider": "airtel",
"msisdn": "+243970000000"
},
"purpose": "family_support",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import uuid
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/transfers",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"quoteId": "0192a7c4-5b1e-7c3a-9f10-3d2e8b6a4c11",
"beneficiaryId": "0192a7c4-6f02-7a55-8e21-7b4c0d9e2f33",
"source": {
"type": "mobile_money",
"provider": "airtel",
"msisdn": "+243970000000"
},
"purpose": "family_support",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/transfers", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json" },
body: JSON.stringify({
"quoteId": "0192a7c4-5b1e-7c3a-9f10-3d2e8b6a4c11",
"beneficiaryId": "0192a7c4-6f02-7a55-8e21-7b4c0d9e2f33",
"source": {
"type": "mobile_money",
"provider": "airtel",
"msisdn": "+243970000000"
},
"purpose": "family_support",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 202
{
"reference": "LP-8QK2ZD",
"status": "in_progress",
"steps": [
{
"label": "Envoi initié",
"done": true
},
{
"label": "Fonds prélevés sur votre mobile money",
"done": false
},
{
"label": "Versement au bénéficiaire en cours",
"done": false
},
{
"label": "Fonds reçus par le bénéficiaire",
"done": false
}
],
"beneficiary": "Bastian Kelyan",
"destination": "Orange Money •• 0000",
"country": "CI",
"source": "Airtel Money •• 0000",
"sourceType": "mobile_money",
"send": {
"amount": 15000,
"currency": "USD",
"display": "150,00 $"
},
"fee": {
"amount": 325,
"currency": "USD",
"display": "3,25 $"
},
"vat": {
"amount": 52,
"currency": "USD",
"display": "0,52 $"
},
"levy": {
"amount": 30,
"currency": "USD",
"display": "0,30 $"
},
"total": {
"amount": 15407,
"currency": "USD",
"display": "154,07 $"
},
"receive": {
"amount": 84900,
"currency": "XOF",
"display": "84 900 FCFA"
},
"rate": "566.00",
"createdAt": "2026-09-29T14:00:20+00:00",
"deliveredAt": null,
"refundedAt": null
}
Réponses et erreurs Statut Signification 202Envoi accepté, en cours de traitement.
422Refus métier (Problem.code), dont journey_limit_exceeded : le montant dépasse un plafond du parcours de paiement (par envoi, par jour ou par mois, en USD quelle que soit la devise envoyée, docs/adr/0083). detail donne le plafond atteint (« 30.00 USD »). Un parcours fermé répond operation_unavailable (403), sans motif.
Erreur au format application/problem+json : voir « Erreurs ».
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/transfers/{reference}/repeat
Renvoyer un transfert (valeurs pré-remplies)
« Renvoyer » : bénéficiaire, moyen de paiement, destination et montant d'un transfert terminé (livré, remboursé ou échoué), pour remplir l'écran d'envoi. Aucune écriture : l'envoi demande un nouveau devis (jamais l'ancien taux), puis suit le parcours normal (2FA, nouvelle clé d'idempotence, filtrage AML, plafonds, parcours ouvert). Bénéficiaire supprimé, corridor ou parcours fermé : complete à faux, beneficiaryId nul et issue dit quoi choisir. Transfert en cours (y compris un remboursement pas encore terminé) : 409 transfer_in_progress ; référence d'un autre client : 404 transfer_not_found. Le solde n'est repris que si le compte est en mode wallet, le motif que s'il est encore proposé pour ce bénéficiaire.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/repeat" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/repeat');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/repeat",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/repeat", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"reference": "LP-7K2Q4F",
"beneficiaryId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"beneficiaryName": "texte",
"country": "KE",
"payoutMethod": "mobile_money",
"sendAmount": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"receiveCurrency": "USD",
"complete": true,
"issue": {
"code": "beneficiary_deleted",
"message": "texte"
}
}
Réponses et erreurs Statut Signification 200Valeurs de l'écran d'envoi.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/transfers/{reference}
Suivre un envoi
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui Référence publique de l'envoi.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"reference": "LP-7K2Q4F",
"status": "in_progress",
"steps": [
{
"label": "texte",
"done": true
}
],
"beneficiary": "texte",
"destination": "texte",
"country": "KE",
"source": "texte",
"sourceType": "mobile_money",
"send": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"fee": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"vat": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"levy": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"total": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"receive": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"rate": "texte",
"createdAt": "2026-10-01T09:30:00Z",
"deliveredAt": "2026-10-01T09:30:00Z",
"refundedAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 200Envoi et étapes de suivi.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/transfers/{reference}/cash-pickup/code
Afficher le code de retrait
Retrait d'espèces : le code à donner au bénéficiaire, après un second facteur ; jamais mis en cache, jamais renvoyé par le support. 409 cash_pickup_not_pending une fois retiré, annulé ou remboursé.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui Référence publique de l'envoi.
X-Linc-Attestationen-tête string non Assertion de l'installation attestée, pour une opération sensible. Hachage de la requête : base64url(SHA-256(METHOD "\n" PATH "\n" Idempotency-Key "\n" hex(SHA-256(corps)))). Android : jeton Play Integrity (requête standard) avec ce requestHash. iOS : assertion App Attest (CBOR en base64) sur le SHA-256 de ce hachage. Absente ou invalide quand la politique l'exige : 403 attestation_required.
Corps de la requête Nom Type Obligatoire Description twoFactorobject non Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring non totp · sms · backup_code
twoFactor.codestring non twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/cash-pickup/code" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/cash-pickup/code');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/cash-pickup/code",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"twoFactor": {
"method": "totp",
"code": "••••••"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/cash-pickup/code", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"code": "••••••"
}
Réponses et erreurs Statut Signification 200Code de retrait.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/transfers/{reference}/cash-pickup/sms
Renvoyer le code au bénéficiaire par SMS
Au plus 3 renvois par envoi (429 cash_pickup_resend_limit au-delà) ; chaque envoi est journalisé.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui Référence publique de l'envoi.
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/cash-pickup/sms" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/cash-pickup/sms');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/cash-pickup/sms",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/cash-pickup/sms", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"sent": true,
"cashPickup": {
"status": "pending",
"expiresAt": "2026-10-01T09:30:00Z",
"smsUndelivered": true,
"resendsLeft": 0,
"amendmentsLeft": 0,
"nameUnderReview": true,
"cancelledBy": "expired",
"refundable": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"refundIfCancelled": {
"amount": 10000,
"currency": "USD",
"display": "texte"
}
}
}
Réponses et erreurs Statut Signification 200SMS parti ou non (sent) et état du retrait.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/transfers/{reference}/cash-pickup/cancel
Annuler un retrait d'espèces
Tant que l'argent n'est pas retiré, après un second facteur : Mastercard annule le paiement, puis le montant envoyé est remboursé (frais et marge de change conservés). 409 cash_pickup_cancel_refused si l'argent est déjà retiré : rien n'est remboursé.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui Référence publique de l'envoi.
X-Linc-Attestationen-tête string non Assertion de l'installation attestée, pour une opération sensible. Hachage de la requête : base64url(SHA-256(METHOD "\n" PATH "\n" Idempotency-Key "\n" hex(SHA-256(corps)))). Android : jeton Play Integrity (requête standard) avec ce requestHash. iOS : assertion App Attest (CBOR en base64) sur le SHA-256 de ce hachage. Absente ou invalide quand la politique l'exige : 403 attestation_required.
Corps de la requête Nom Type Obligatoire Description twoFactorobject non Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring non totp · sms · backup_code
twoFactor.codestring non twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/cash-pickup/cancel" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/cash-pickup/cancel');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/cash-pickup/cancel",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"twoFactor": {
"method": "totp",
"code": "••••••"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/cash-pickup/cancel", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"outcome": "cancelled",
"transfer": {
"reference": "LP-7K2Q4F",
"status": "in_progress",
"steps": [
{
"label": "texte",
"done": true
}
],
"beneficiary": "texte",
"destination": "texte",
"country": "KE",
"source": "texte",
"sourceType": "mobile_money",
"send": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"fee": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"vat": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"levy": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"total": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"receive": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"rate": "texte",
"createdAt": "2026-10-01T09:30:00Z",
"deliveredAt": "2026-10-01T09:30:00Z",
"refundedAt": "2026-10-01T09:30:00Z"
}
}
Réponses et erreurs Statut Signification 200Issue de l'annulation et envoi à jour.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/transfers/{reference}/cash-pickup/name
Corriger le nom du bénéficiaire d'un retrait
Une fois par envoi, avant le retrait, après un second facteur. Une faute de frappe est corrigée chez Mastercard aussitôt (amended: true) ; au-delà, la conformité valide d'abord (amended: false). 409 cash_pickup_amend_limit, 409 cash_pickup_amend_refused (refusée par Mastercard), 503 cash_pickup_amend_unknown (Mastercard n'a pas répondu : le nom n'est pas modifié, les opérations vérifient).
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui Référence publique de l'envoi.
X-Linc-Attestationen-tête string non Assertion de l'installation attestée, pour une opération sensible. Hachage de la requête : base64url(SHA-256(METHOD "\n" PATH "\n" Idempotency-Key "\n" hex(SHA-256(corps)))). Android : jeton Play Integrity (requête standard) avec ce requestHash. iOS : assertion App Attest (CBOR en base64) sur le SHA-256 de ce hachage. Absente ou invalide quand la politique l'exige : 403 attestation_required.
Corps de la requête Nom Type Obligatoire Description namestring oui Nom complet du bénéficiaire, exactement comme sur sa pièce d'identité.
twoFactorobject oui Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring oui totp · sms · backup_code
twoFactor.codestring oui twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"name": "texte",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/cash-pickup/name" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "texte",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/cash-pickup/name');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"name": "texte",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/cash-pickup/name",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"name": "texte",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/cash-pickup/name", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"name": "texte",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"amended": true
}
Réponses et erreurs Statut Signification 200Corrigé ou en attente de la conformité.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/transfers/{reference}/card-checkout
Ouvrir la page carte d'un envoi
Envoi financé par carte bancaire : page carte, ouverte une fois la vérification de l'envoi passée. Chaque appel donne un nouveau lien à usage unique. 409 card_checkout_not_ready pendant la vérification (réessayez), ou card_payment_closed une fois le paiement par carte terminé.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui Référence publique de l'envoi.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/card-checkout" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/card-checkout');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/card-checkout",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/card-checkout", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"reference": "LP-7K2Q4F",
"status": "pending",
"url": "https://example.com",
"expiresAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 200Page carte à ouvrir.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/transfers/{reference}/checkout
Ouvrir la page de paiement Interswitch d'un envoi
Envoi payé sur la page de paiement d'Interswitch (Web Checkout) : lien signé qui ouvre cette page dans la vue web de l'application. Le client y choisit son moyen de paiement puis revient par linc-client://envoi/retour ; la redirection ne prouve rien, suivez l'envoi avec GET /v1/transfers/{reference} (la collecte est confirmée de serveur à serveur). 409 checkout_not_ready pendant la vérification de l'envoi (réessayez), checkout_unavailable quand aucun paiement n'attend le client sur cette page (envoi payé autrement, ou déjà confirmé).
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui Référence publique de l'envoi.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/checkout" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/checkout');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/checkout",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/checkout", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"url": "https://example.com",
"expiresAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 200Page de paiement à ouvrir.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/card-payments/{reference}
Suivre un paiement par carte
Issue du paiement par carte d'un envoi ou d'un paiement marchand du client (après la page carte).
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui Référence du paiement par carte.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/card-payments/LP-7K2Q4F" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/card-payments/LP-7K2Q4F');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/card-payments/LP-7K2Q4F",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/card-payments/LP-7K2Q4F", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"reference": "LP-7K2Q4F",
"status": "pending",
"statusLabel": "texte",
"purpose": "merchant_payment",
"subject": "texte",
"amount": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"card": "texte",
"message": "texte",
"attemptsLeft": 0,
"expiresAt": "2026-10-01T09:30:00Z",
"approvedAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 200Paiement par carte.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/saved-cards
Lister mes cartes bancaires enregistrées
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/saved-cards" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/saved-cards');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/saved-cards",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/saved-cards", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"cards": [
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"label": "texte",
"network": "visa",
"last4": "texte",
"expiry": "texte",
"issuerCountry": "KE",
"createdAt": "2026-10-01T09:30:00Z"
}
],
"verificationHold": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"verificationNotice": "texte"
}
Réponses et erreurs Statut Signification 200Cartes enregistrées (réseau, 4 derniers chiffres, expiration).
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/saved-cards
Ajouter une carte bancaire sans paiement
Second facteur requis (purpose card_add), KYC niveau 2. Ouvre la page carte d'une vérification (CV-XXXXXX) : la carte est saisie dans le formulaire hébergé de l'acquéreur, contrôlée comme une carte qui finance un envoi, puis vérifiée par une autorisation de 1 USD (verificationHold de GET /v1/saved-cards, paramétrable) SANS capture, avec 3-D Secure obligatoire. Dès que la banque l'accepte et authentifie le titulaire, l'autorisation est annulée et la carte enregistrée ; rien n'est prélevé. Prévenez le client avant la saisie avec verificationNotice. Suivez l'issue avec GET /v1/card-payments/{reference} (approved puis reversed, ou failed) puis GET /v1/saved-cards. La période d'observation démarre à la vérification.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Opération financière : envoyez un Idempotency-Key unique par opération (rejoué 24 h).
Paramètres Nom Où Type Obligatoire Description Idempotency-Keyen-tête string oui Identifiant unique de l'opération (par exemple un UUID), conservé 24 h. Une même clé avec le même corps rejoue la réponse d'origine. Avec un autre corps : 422 idempotency_key_reused. Pendant le traitement : 409 idempotency_in_progress.
X-Linc-Attestationen-tête string non Assertion de l'installation attestée, pour une opération sensible. Hachage de la requête : base64url(SHA-256(METHOD "\n" PATH "\n" Idempotency-Key "\n" hex(SHA-256(corps)))). Android : jeton Play Integrity (requête standard) avec ce requestHash. iOS : assertion App Attest (CBOR en base64) sur le SHA-256 de ce hachage. Absente ou invalide quand la politique l'exige : 403 attestation_required.
Corps de la requête Nom Type Obligatoire Description twoFactorobject non Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring non totp · sms · backup_code
twoFactor.codestring non twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/saved-cards" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/saved-cards');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import uuid
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/saved-cards",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"twoFactor": {
"method": "totp",
"code": "••••••"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/saved-cards", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json" },
body: JSON.stringify({
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"reference": "LP-7K2Q4F",
"status": "pending",
"url": "https://example.com",
"expiresAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 201Page carte à ouvrir (lien à usage unique).
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
PATCH /v1/saved-cards/{id}
Nommer une carte enregistrée ou la choisir par défaut
nickname : nom donné par le client (40 caractères au plus, vide pour l'effacer) ; default : true en fait la carte proposée en premier au prochain paiement (une seule par client). Un champ absent est laissé tel quel.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui Identifiant de la carte enregistrée.
Corps de la requête Nom Type Obligatoire Description nicknamestring non Nom donné à la carte ; vide pour l'effacer.
defaultboolean non
Exemple de requête {
"nickname": "texte",
"default": true
}
Exemple de code cURL PHP Python JavaScript
curl -X PATCH "https://sandbox.api.linc.cd/v1/saved-cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"nickname": "texte",
"default": true
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/saved-cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"nickname": "texte",
"default": true
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.patch(
"https://sandbox.api.linc.cd/v1/saved-cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"nickname": "texte",
"default": True
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/saved-cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f", {
method: "PATCH",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"nickname": "texte",
"default": true
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"label": "texte",
"network": "visa",
"last4": "texte",
"expiry": "texte",
"issuerCountry": "KE",
"createdAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 200Carte mise à jour.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
DELETE /v1/saved-cards/{id}
Supprimer une carte bancaire enregistrée
Le jeton est aussi supprimé chez l'acquéreur.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui Identifiant de la carte enregistrée.
Exemple de code cURL PHP Python JavaScript
curl -X DELETE "https://sandbox.api.linc.cd/v1/saved-cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/saved-cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.delete(
"https://sandbox.api.linc.cd/v1/saved-cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/saved-cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 204
Carte supprimée.
Réponses et erreurs Statut Signification 204Carte supprimée.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/saved-wallets
Lister mes porte-monnaie mobiles enregistrés
Les numéros mobile money enregistrés par le client, le porte-monnaie par défaut en premier. Le numéro n'est jamais renvoyé : opérateur et 4 derniers chiffres seulement. Un porte-monnaie pending n'a pas encore été vérifié : il ne peut pas financer un envoi.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/saved-wallets" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/saved-wallets');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/saved-wallets",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/saved-wallets", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"wallets": [
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"label": "texte",
"provider": "airtel",
"providerLabel": "texte",
"last4": "texte",
"maskedNumber": "texte",
"status": "pending",
"verified": true,
"default": true,
"createdAt": "2026-10-01T09:30:00Z"
}
],
"max": 0
}
Réponses et erreurs Statut Signification 200Porte-monnaie enregistrés et nombre maximal.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/saved-wallets
Enregistrer un porte-monnaie mobile
Enregistre un numéro mobile money à votre nom . L'opérateur est lu depuis le numéro si provider est absent (saved_wallet_operator_unknown sinon). Le porte-monnaie est pending et un code de 6 chiffres est envoyé par SMS à ce numéro (5 minutes, 5 essais) : renvoyez-le à POST /v1/saved-wallets/{id}/verify avec le challengeId. Le numéro du compte, déjà vérifié, est enregistré verified d'emblée (challengeId nul). Erreurs : saved_wallet_limit (limite atteinte), saved_wallet_exists (déjà enregistré). Le même numéro enregistré par plusieurs clients ouvre une alerte de fraude.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description X-Linc-Attestationen-tête string non Assertion de l'installation attestée, pour une opération sensible. Hachage de la requête : base64url(SHA-256(METHOD "\n" PATH "\n" Idempotency-Key "\n" hex(SHA-256(corps)))). Android : jeton Play Integrity (requête standard) avec ce requestHash. iOS : assertion App Attest (CBOR en base64) sur le SHA-256 de ce hachage. Absente ou invalide quand la politique l'exige : 403 attestation_required.
Corps de la requête Nom Type Obligatoire Description msisdnstring oui Numéro mobile money de la RDC, avec ou sans +243.
providerstring non Opérateur ; lu depuis le numéro si absent.
airtel · mpesa · orange · afrimoney
labelstring non Nom du porte-monnaie ; l'opérateur par défaut.
Exemple de requête {
"msisdn": "+243810000000"
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/saved-wallets" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"msisdn": "+243810000000"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/saved-wallets');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"msisdn": "+243810000000"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/saved-wallets",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"msisdn": "+243810000000"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/saved-wallets", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"msisdn": "+243810000000"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"wallet": {
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"label": "texte",
"provider": "airtel",
"providerLabel": "texte",
"last4": "texte",
"maskedNumber": "texte",
"status": "pending",
"verified": true,
"default": true,
"createdAt": "2026-10-01T09:30:00Z"
},
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f"
}
Réponses et erreurs Statut Signification 201Porte-monnaie enregistré.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
PATCH /v1/saved-wallets/{id}
Renommer un porte-monnaie ou le choisir par défaut
label : nom (1 à 40 caractères) ; default : true en fait le porte-monnaie proposé en premier (il doit être vérifié). Un champ absent est laissé tel quel.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui
Corps de la requête Nom Type Obligatoire Description labelstring non defaultboolean non
Exemple de requête {
"label": "texte",
"default": true
}
Exemple de code cURL PHP Python JavaScript
curl -X PATCH "https://sandbox.api.linc.cd/v1/saved-wallets/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"label": "texte",
"default": true
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/saved-wallets/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"label": "texte",
"default": true
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.patch(
"https://sandbox.api.linc.cd/v1/saved-wallets/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"label": "texte",
"default": True
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/saved-wallets/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f", {
method: "PATCH",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"label": "texte",
"default": true
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"label": "texte",
"provider": "airtel",
"providerLabel": "texte",
"last4": "texte",
"maskedNumber": "texte",
"status": "pending",
"verified": true,
"default": true,
"createdAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 200Porte-monnaie mis à jour.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
DELETE /v1/saved-wallets/{id}
Supprimer un porte-monnaie enregistré
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui
Exemple de code cURL PHP Python JavaScript
curl -X DELETE "https://sandbox.api.linc.cd/v1/saved-wallets/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/saved-wallets/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.delete(
"https://sandbox.api.linc.cd/v1/saved-wallets/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/saved-wallets/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 204
Porte-monnaie supprimé.
Réponses et erreurs Statut Signification 204Porte-monnaie supprimé.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/saved-wallets/{id}/code
Renvoyer le code de vérification d'un porte-monnaie
Nouveau code par SMS au numéro du porte-monnaie (limité comme les autres codes ; le précédent est invalidé). saved_wallet_verified si le porte-monnaie est déjà vérifié.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/saved-wallets/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/code" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/saved-wallets/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/code');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/saved-wallets/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/code",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/saved-wallets/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/code", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f"
}
Réponses et erreurs Statut Signification 200Code envoyé.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/saved-wallets/{id}/verify
Vérifier un porte-monnaie avec le code reçu par SMS
Preuve que le client détient le numéro. Après un code juste, le porte-monnaie est verified et peut financer un envoi (source.savedWalletId). Un code faux, expiré ou épuisé renvoie l'erreur OTP habituelle.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description X-Linc-Attestationen-tête string non Assertion de l'installation attestée, pour une opération sensible. Hachage de la requête : base64url(SHA-256(METHOD "\n" PATH "\n" Idempotency-Key "\n" hex(SHA-256(corps)))). Android : jeton Play Integrity (requête standard) avec ce requestHash. iOS : assertion App Attest (CBOR en base64) sur le SHA-256 de ce hachage. Absente ou invalide quand la politique l'exige : 403 attestation_required.
idchemin string oui
Corps de la requête Nom Type Obligatoire Description challengeIdstring (uuid) oui codestring oui Code à 6 chiffres reçu par SMS au numéro du porte-monnaie.
Exemple de requête {
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"code": "••••••"
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/saved-wallets/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/verify" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"code": "••••••"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/saved-wallets/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/verify');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"code": "••••••"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/saved-wallets/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/verify",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"code": "••••••"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/saved-wallets/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/verify", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"code": "••••••"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"label": "texte",
"provider": "airtel",
"providerLabel": "texte",
"last4": "texte",
"maskedNumber": "texte",
"status": "pending",
"verified": true,
"default": true,
"createdAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 200Porte-monnaie vérifié.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/transfers/{reference}/saved-wallet
Enregistrer le numéro d'un envoi qui a abouti
Proposé à la fin d'un envoi par mobile money dont la collecte a abouti (GET /v1/transfers/{reference} : source mobile_money, numéro pas encore enregistré, limite non atteinte). Enregistre le numéro de l'envoi comme porte-monnaie pending et envoie le code de vérification à ce numéro (consentement journalisé : after_payment). saved_wallet_not_found si l'envoi ne s'y prête pas.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/saved-wallet" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/saved-wallet');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/saved-wallet",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/transfers/LP-7K2Q4F/saved-wallet", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"wallet": {
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"label": "texte",
"provider": "airtel",
"providerLabel": "texte",
"last4": "texte",
"maskedNumber": "texte",
"status": "pending",
"verified": true,
"default": true,
"createdAt": "2026-10-01T09:30:00Z"
},
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f"
}
Réponses et erreurs Statut Signification 201Porte-monnaie enregistré, code envoyé.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/me/dashboard
Afficher le tableau de bord
Soldes, actions rapides, envois en cours, favoris, taux, carte, plafond, sécurité, statistiques et dernières opérations.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description X-App-Iden-tête string non Application mobile appelante.
X-App-Platformen-tête string non Plateforme de l'application mobile.
X-App-Versionen-tête string non Version de l'application (par exemple 1.4.2). Sous la version minimale, réponse 426 app_update_required.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/me/dashboard" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/dashboard');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/me/dashboard",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/dashboard", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"mode": "wallet",
"kycLevel": 1,
"balances": [
{
"amount": 10000,
"currency": "USD",
"display": "texte"
}
],
"reserved": [
{
"amount": 10000,
"currency": "USD",
"display": "texte"
}
],
"actions": {
"send": true,
"pay": true,
"topup": true,
"withdraw": true,
"card": true
},
"transfersInProgress": [
{
"reference": "LP-7K2Q4F",
"status": "in_progress",
"steps": [
{
"label": "texte",
"done": true
}
],
"beneficiary": "texte",
"destination": "texte",
"country": "KE",
"source": "texte",
"sourceType": "mobile_money",
"send": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"fee": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"vat": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"levy": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"total": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"receive": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"rate": "texte",
"createdAt": "2026-10-01T09:30:00Z",
"deliveredAt": "2026-10-01T09:30:00Z",
"refundedAt": "2026-10-01T09:30:00Z"
}
],
"favourites": [
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"fullName": "texte",
"country": "KE",
"payoutMethod": "mobile_money",
"destination": "texte"
}
],
"rates": [
{
"country": "KE",
"name": "texte",
"payoutMethod": "mobile_money",
"send": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"fee": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"receive": {
"amount": 10000,
"currency": "USD",
"display": "texte"
}
}
],
"card": {
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"network": "visa",
"last4": "texte",
"status": "active",
"balance": {
"amount": 10000,
"currency": "USD",
"display": "texte"
}
},
"monthlyLimit": {
"used": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"cap": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"percent": 0,
"level": 1
},
"security": {
"twoFactor": true,
"totp": true,
"sms": true,
"trustedDevices": 0,
"lastLogin": "2026-10-01T09:30:00Z"
},
"statistics": {
"months": [
{
"label": "texte",
"sent": 0,
"received": 0,
"paid": 0
}
],
"max": 0,
"destinations": [
{
"name": "texte",
"count": 0,
"percent": 0
}
]
},
"recent": [
{
"type": "send",
"label": "texte",
"date": "2026-10-01T09:30:00Z",
"statusLabel": "texte",
"amount": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"reference": "LP-7K2Q4F",
"receipt": true
}
]
}
Réponses et erreurs Statut Signification 200Tableau de bord du client.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/me/history
Afficher l'historique
Historique paginé, filtré par type et par texte (libellé ou référence).
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description pagerequête integer non perPagerequête integer non typerequête string non Filtre. Valeur vide ou inconnue = tout.
qrequête string non Texte recherché dans le libellé ou la référence.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/me/history" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/me/history');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/me/history",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/me/history", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"items": [
{
"type": "send",
"label": "texte",
"date": "2026-10-01T09:30:00Z",
"statusLabel": "texte",
"amount": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"reference": "LP-7K2Q4F",
"receipt": true
}
],
"page": 0,
"perPage": 0,
"total": 0,
"hasMore": true,
"filters": [
"texte"
]
}
Réponses et erreurs Statut Signification 200Page d'historique.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/receipts/{reference}
Télécharger un reçu
Reçu PDF d'un envoi (LP-), d'un paiement marchand (TX-), d'un rechargement (TU-) ou d'une opération crypto (CX-).
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/receipts/LP-7K2Q4F" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/receipts/LP-7K2Q4F');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/receipts/LP-7K2Q4F",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/receipts/LP-7K2Q4F", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
Fichier (PDF ou image)
Réponses et erreurs Statut Signification 200Reçu PDF (pièce jointe recu-linc-{reference}.pdf).
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/notifications
Lister mes notifications
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/notifications" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/notifications');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/notifications",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/notifications", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"notifications": [
{
"key": "texte",
"title": "texte",
"text": "texte",
"date": "2026-10-01T09:30:00Z",
"reference": "LP-7K2Q4F",
"read": true
}
],
"unread": 0
}
Réponses et erreurs Statut Signification 200Notifications et nombre de non lues.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/notifications/{key}/read
Marquer une notification comme lue
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description keychemin string oui Clé de la notification, par exemple transfer:LP-7K2Q9M:delivered.
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/notifications/texte/read" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/notifications/texte/read');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/notifications/texte/read",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/notifications/texte/read", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 204
Notification lue.
Réponses et erreurs Statut Signification 204Notification lue.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/notifications/read-all
Tout marquer comme lu
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/notifications/read-all" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/notifications/read-all');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/notifications/read-all",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/notifications/read-all", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"marked": 0
}
Réponses et erreurs Statut Signification 200Nombre de notifications marquées.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/wallet/top-ups
Lister mes rechargements
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/wallet/top-ups" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/wallet/top-ups');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/wallet/top-ups",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/wallet/top-ups", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"topUps": [
{
"reference": "LP-7K2Q4F",
"status": "pending",
"provider": "airtel",
"amount": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"failureReason": "texte",
"createdAt": "2026-10-01T09:30:00Z",
"completedAt": "2026-10-01T09:30:00Z"
}
]
}
Réponses et erreurs Statut Signification 200Rechargements du client.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/wallet/top-ups
Recharger le solde
Collecte USSD / STK push sur le mobile money. Le résultat est asynchrone (suivez le statut).
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Opération financière : envoyez un Idempotency-Key unique par opération (rejoué 24 h).
Paramètres Nom Où Type Obligatoire Description Idempotency-Keyen-tête string oui Identifiant unique de l'opération (par exemple un UUID), conservé 24 h. Une même clé avec le même corps rejoue la réponse d'origine. Avec un autre corps : 422 idempotency_key_reused. Pendant le traitement : 409 idempotency_in_progress.
Corps de la requête Nom Type Obligatoire Description providerstring non airtel · mpesa · orange · afrimoney
msisdnstring non Numéro à débiter. Vide = numéro du compte.
amountstring oui currencystring non
Exemple de requête {
"amount": "texte"
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/wallet/top-ups" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"amount": "texte"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/wallet/top-ups');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"amount": "texte"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import uuid
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/wallet/top-ups",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"amount": "texte"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/wallet/top-ups", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json" },
body: JSON.stringify({
"amount": "texte"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 202
{
"reference": "LP-7K2Q4F",
"status": "pending",
"provider": "airtel",
"amount": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"failureReason": "texte",
"createdAt": "2026-10-01T09:30:00Z",
"completedAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 202Rechargement lancé.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/wallet/top-ups/{reference}
Suivre un rechargement
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/wallet/top-ups/LP-7K2Q4F" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/wallet/top-ups/LP-7K2Q4F');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/wallet/top-ups/LP-7K2Q4F",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/wallet/top-ups/LP-7K2Q4F", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"reference": "LP-7K2Q4F",
"status": "pending",
"provider": "airtel",
"amount": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"failureReason": "texte",
"createdAt": "2026-10-01T09:30:00Z",
"completedAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 200Rechargement.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/merchant-payments/resolve
Lire un QR marchand ou un lien de paiement
Ce que demande un QR scanné (EMVCo) ou un lien INV-… ouvert, avant de payer.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Corps de la requête Nom Type Obligatoire Description payloadstring oui Contenu du QR EMVCo, lien https://app.linc.cd/pay/INV-… ou référence INV-….
Exemple de requête {
"payload": "texte"
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/merchant-payments/resolve" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"payload": "texte"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/merchant-payments/resolve');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"payload": "texte"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/merchant-payments/resolve",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"payload": "texte"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/merchant-payments/resolve", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"payload": "texte"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"type": "link",
"reference": "LP-7K2Q4F",
"merchant": {
"code": "••••••",
"name": "texte",
"country": "KE"
},
"label": "texte",
"amount": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"status": "open",
"payable": true,
"expiresAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 200Marchand, montant et état du paiement demandé.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/merchant-payments
Lister mes paiements marchands
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/merchant-payments" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/merchant-payments');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/merchant-payments",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/merchant-payments", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"payments": [
{
"reference": "LP-7K2Q4F",
"status": "pending",
"statusLabel": "texte",
"merchant": {
"code": "••••••",
"name": "texte",
"country": "KE"
},
"label": "texte",
"channel": "link",
"source": "mobile_money",
"amount": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"createdAt": "2026-10-01T09:30:00Z",
"paidAt": "2026-10-01T09:30:00Z",
"refundedAt": "2026-10-01T09:30:00Z"
}
]
}
Réponses et erreurs Statut Signification 200Paiements du client.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/merchant-payments
Payer un marchand
Paie un lien (INV-…) ou un QR de caisse (QR-…, montant obligatoire). Second facteur requis, sauf par carte bancaire : la réponse donne alors la page carte (cardCheckout) où la carte est saisie et confirmée par sa banque (3-D Secure). La collecte est asynchrone. Opération sensible : assertion X-Linc-Attestation exigée des applications attestées.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Opération financière : envoyez un Idempotency-Key unique par opération (rejoué 24 h).
Paramètres Nom Où Type Obligatoire Description Idempotency-Keyen-tête string oui Identifiant unique de l'opération (par exemple un UUID), conservé 24 h. Une même clé avec le même corps rejoue la réponse d'origine. Avec un autre corps : 422 idempotency_key_reused. Pendant le traitement : 409 idempotency_in_progress.
X-Linc-Attestationen-tête string non Assertion de l'installation attestée, pour une opération sensible. Hachage de la requête : base64url(SHA-256(METHOD "\n" PATH "\n" Idempotency-Key "\n" hex(SHA-256(corps)))). Android : jeton Play Integrity (requête standard) avec ce requestHash. iOS : assertion App Attest (CBOR en base64) sur le SHA-256 de ce hachage. Absente ou invalide quand la politique l'exige : 403 attestation_required.
Corps de la requête Nom Type Obligatoire Description referencestring oui amountstring non Obligatoire pour un QR de caisse (USD).
sourceobject non source.typestring non mobile_money · wallet · card
source.providerstring non airtel · mpesa · orange · afrimoney
source.msisdnstring non twoFactorobject non Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring non totp · sms · backup_code
twoFactor.codestring non twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"reference": "INV-7K2Q4F",
"source": {
"type": "mobile_money",
"provider": "airtel",
"msisdn": "+243970000000"
},
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/merchant-payments" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"reference": "INV-7K2Q4F",
"source": {
"type": "mobile_money",
"provider": "airtel",
"msisdn": "+243970000000"
},
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/merchant-payments');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"reference": "INV-7K2Q4F",
"source": {
"type": "mobile_money",
"provider": "airtel",
"msisdn": "+243970000000"
},
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import uuid
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/merchant-payments",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"reference": "INV-7K2Q4F",
"source": {
"type": "mobile_money",
"provider": "airtel",
"msisdn": "+243970000000"
},
"twoFactor": {
"method": "totp",
"code": "••••••"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/merchant-payments", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json" },
body: JSON.stringify({
"reference": "INV-7K2Q4F",
"source": {
"type": "mobile_money",
"provider": "airtel",
"msisdn": "+243970000000"
},
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 202
{
"reference": "LP-7K2Q4F",
"status": "pending",
"statusLabel": "texte",
"merchant": {
"code": "••••••",
"name": "texte",
"country": "KE"
},
"label": "texte",
"channel": "link",
"source": "mobile_money",
"amount": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"createdAt": "2026-10-01T09:30:00Z",
"paidAt": "2026-10-01T09:30:00Z",
"refundedAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 202Paiement accepté, en cours.
422Refus métier (Problem.code), dont journey_limit_exceeded : le montant dépasse un plafond du parcours de paiement (par envoi, par jour ou par mois, en USD quelle que soit la devise envoyée, docs/adr/0083). detail donne le plafond atteint (« 30.00 USD »). Un parcours fermé répond operation_unavailable (403), sans motif.
Erreur au format application/problem+json : voir « Erreurs ».
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/merchant-payments/{reference}
Afficher un paiement marchand
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui Référence du paiement marchand.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/merchant-payments/LP-7K2Q4F" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/merchant-payments/LP-7K2Q4F');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/merchant-payments/LP-7K2Q4F",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/merchant-payments/LP-7K2Q4F", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"reference": "LP-7K2Q4F",
"status": "pending",
"statusLabel": "texte",
"merchant": {
"code": "••••••",
"name": "texte",
"country": "KE"
},
"label": "texte",
"channel": "link",
"source": "mobile_money",
"amount": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"createdAt": "2026-10-01T09:30:00Z",
"paidAt": "2026-10-01T09:30:00Z",
"refundedAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 200Paiement marchand.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/withdrawal-codes
Lister mes codes de retrait
Le code complet n'est jamais renvoyé (code = null).
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/withdrawal-codes" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/withdrawal-codes');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/withdrawal-codes",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/withdrawal-codes", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"codes": [
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"status": "active",
"statusLabel": "texte",
"code": "••••••",
"last4": "texte",
"amount": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"createdAt": "2026-10-01T09:30:00Z",
"expiresAt": "2026-10-01T09:30:00Z",
"closedAt": "2026-10-01T09:30:00Z"
}
]
}
Réponses et erreurs Statut Signification 200Codes de retrait.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/withdrawal-codes
Créer un code de retrait
Code à 8 chiffres, affiché une seule fois, à donner à l'agent avec une pièce d'identité. Le montant est réservé. Second facteur requis. Opération sensible (X-Linc-Attestation).
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Opération financière : envoyez un Idempotency-Key unique par opération (rejoué 24 h).
Paramètres Nom Où Type Obligatoire Description Idempotency-Keyen-tête string oui Identifiant unique de l'opération (par exemple un UUID), conservé 24 h. Une même clé avec le même corps rejoue la réponse d'origine. Avec un autre corps : 422 idempotency_key_reused. Pendant le traitement : 409 idempotency_in_progress.
X-Linc-Attestationen-tête string non Assertion de l'installation attestée, pour une opération sensible. Hachage de la requête : base64url(SHA-256(METHOD "\n" PATH "\n" Idempotency-Key "\n" hex(SHA-256(corps)))). Android : jeton Play Integrity (requête standard) avec ce requestHash. iOS : assertion App Attest (CBOR en base64) sur le SHA-256 de ce hachage. Absente ou invalide quand la politique l'exige : 403 attestation_required.
Corps de la requête Nom Type Obligatoire Description amountstring oui currencystring non twoFactorobject oui Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring oui totp · sms · backup_code
twoFactor.codestring oui twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"amount": "texte",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/withdrawal-codes" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"amount": "texte",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/withdrawal-codes');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"amount": "texte",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import uuid
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/withdrawal-codes",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"amount": "texte",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/withdrawal-codes", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json" },
body: JSON.stringify({
"amount": "texte",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"status": "active",
"statusLabel": "texte",
"code": "••••••",
"last4": "texte",
"amount": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"createdAt": "2026-10-01T09:30:00Z",
"expiresAt": "2026-10-01T09:30:00Z",
"closedAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 201Code créé (champ code présent une seule fois).
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/withdrawal-codes/{id}/cancel
Annuler un code de retrait
Libère le montant réservé.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/withdrawal-codes/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/cancel" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/withdrawal-codes/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/cancel');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/withdrawal-codes/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/cancel",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/withdrawal-codes/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/cancel", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 204
Code annulé.
Réponses et erreurs Statut Signification 204Code annulé.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/cards
Lister mes cartes virtuelles
Cartes du client et programmes ouverts à la création.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/cards" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/cards');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/cards",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/cards", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"cards": [
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"last4": "texte",
"network": "visa",
"currency": "USD",
"embossedName": "texte",
"status": "active",
"frozenByCompliance": true,
"model": "companion",
"balance": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"limits": {
"perTransaction": 0,
"daily": 0,
"monthly": 0,
"ecommerce": true
},
"closeReason": "texte",
"replacedBy": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"createdAt": "2026-10-01T09:30:00Z"
}
],
"programmes": [
{
"network": "visa",
"currency": "USD"
}
]
}
Réponses et erreurs Statut Signification 200Cartes et programmes ouverts.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/cards
Créer une carte virtuelle
Mode wallet et KYC niveau 2 requis. Second facteur requis.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Opération financière : envoyez un Idempotency-Key unique par opération (rejoué 24 h).
Paramètres Nom Où Type Obligatoire Description Idempotency-Keyen-tête string oui Identifiant unique de l'opération (par exemple un UUID), conservé 24 h. Une même clé avec le même corps rejoue la réponse d'origine. Avec un autre corps : 422 idempotency_key_reused. Pendant le traitement : 409 idempotency_in_progress.
X-Linc-Attestationen-tête string non Assertion de l'installation attestée, pour une opération sensible. Hachage de la requête : base64url(SHA-256(METHOD "\n" PATH "\n" Idempotency-Key "\n" hex(SHA-256(corps)))). Android : jeton Play Integrity (requête standard) avec ce requestHash. iOS : assertion App Attest (CBOR en base64) sur le SHA-256 de ce hachage. Absente ou invalide quand la politique l'exige : 403 attestation_required.
Corps de la requête Nom Type Obligatoire Description networkstring non visa · mastercard
embossedNamestring non twoFactorobject oui Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring oui totp · sms · backup_code
twoFactor.codestring oui twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"network": "visa",
"embossedName": "AMANI K",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/cards" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"network": "visa",
"embossedName": "AMANI K",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/cards');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"network": "visa",
"embossedName": "AMANI K",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import uuid
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/cards",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"network": "visa",
"embossedName": "AMANI K",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/cards", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json" },
body: JSON.stringify({
"network": "visa",
"embossedName": "AMANI K",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"id": "0192a7c4-7a13-7d0b-b8c4-1e5f6a2b3c44",
"last4": "4821",
"network": "visa",
"currency": "USD",
"embossedName": "AMANI K",
"status": "active",
"frozenByCompliance": false,
"model": "companion",
"balance": {
"amount": 0,
"currency": "USD",
"display": "0,00 $"
},
"limits": {
"perTransaction": 100000,
"daily": 200000,
"monthly": 500000,
"ecommerce": true
},
"closeReason": null,
"replacedBy": null,
"createdAt": "2026-09-29T14:02:00+00:00"
}
Réponses et erreurs Statut Signification 201Carte créée.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/cards/{id}
Afficher une carte
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui Identifiant de la carte.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"last4": "texte",
"network": "visa",
"currency": "USD",
"embossedName": "texte",
"status": "active",
"frozenByCompliance": true,
"model": "companion",
"balance": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"limits": {
"perTransaction": 0,
"daily": 0,
"monthly": 0,
"ecommerce": true
},
"closeReason": "texte",
"replacedBy": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"createdAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 200Carte.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/cards/{id}/transactions
Lister les opérations d'une carte
Paiements, refus et chargements, du plus récent au plus ancien (100 au plus).
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui Identifiant de la carte.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/transactions" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/transactions');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/transactions",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/transactions", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"transactions": [
{
"kind": "payment",
"label": "texte",
"date": "2026-10-01T09:30:00Z",
"status": "texte",
"detail": "texte",
"amount": {
"amount": 10000,
"currency": "USD",
"display": "texte"
}
}
]
}
Réponses et erreurs Statut Signification 200Opérations de la carte.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/cards/{id}/freeze
Geler une carte
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui Identifiant de la carte.
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/freeze" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/freeze');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/freeze",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/freeze", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"last4": "texte",
"network": "visa",
"currency": "USD",
"embossedName": "texte",
"status": "active",
"frozenByCompliance": true,
"model": "companion",
"balance": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"limits": {
"perTransaction": 0,
"daily": 0,
"monthly": 0,
"ecommerce": true
},
"closeReason": "texte",
"replacedBy": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"createdAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 200Carte.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/cards/{id}/unfreeze
Dégeler une carte
Impossible si la conformité a gelé la carte.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui Identifiant de la carte.
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/unfreeze" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/unfreeze');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/unfreeze",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/unfreeze", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"last4": "texte",
"network": "visa",
"currency": "USD",
"embossedName": "texte",
"status": "active",
"frozenByCompliance": true,
"model": "companion",
"balance": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"limits": {
"perTransaction": 0,
"daily": 0,
"monthly": 0,
"ecommerce": true
},
"closeReason": "texte",
"replacedBy": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"createdAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 200Carte.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/cards/{id}/reveal
Afficher les détails de la carte
Retourne une session d'affichage (60 s) pour le SDK de l'émetteur, après un second facteur. Aucune donnée de carte ne transite par Linc.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui Identifiant de la carte.
X-Linc-Attestationen-tête string non Assertion de l'installation attestée, pour une opération sensible. Hachage de la requête : base64url(SHA-256(METHOD "\n" PATH "\n" Idempotency-Key "\n" hex(SHA-256(corps)))). Android : jeton Play Integrity (requête standard) avec ce requestHash. iOS : assertion App Attest (CBOR en base64) sur le SHA-256 de ce hachage. Absente ou invalide quand la politique l'exige : 403 attestation_required.
Corps de la requête Nom Type Obligatoire Description twoFactorobject non Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring non totp · sms · backup_code
twoFactor.codestring non twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/reveal" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/reveal');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/reveal",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"twoFactor": {
"method": "totp",
"code": "••••••"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/reveal", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"issuer": "texte",
"cardReference": "LP-7K2Q4F",
"last4": "texte",
"sdkUrl": "https://example.com",
"expiresAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 200Session d'affichage.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/cards/{id}/replace
Remplacer une carte
Ferme la carte (perdue ou compromise) et en crée une nouvelle. Second facteur requis.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Opération financière : envoyez un Idempotency-Key unique par opération (rejoué 24 h).
Paramètres Nom Où Type Obligatoire Description idchemin string oui Identifiant de la carte.
Idempotency-Keyen-tête string oui Identifiant unique de l'opération (par exemple un UUID), conservé 24 h. Une même clé avec le même corps rejoue la réponse d'origine. Avec un autre corps : 422 idempotency_key_reused. Pendant le traitement : 409 idempotency_in_progress.
X-Linc-Attestationen-tête string non Assertion de l'installation attestée, pour une opération sensible. Hachage de la requête : base64url(SHA-256(METHOD "\n" PATH "\n" Idempotency-Key "\n" hex(SHA-256(corps)))). Android : jeton Play Integrity (requête standard) avec ce requestHash. iOS : assertion App Attest (CBOR en base64) sur le SHA-256 de ce hachage. Absente ou invalide quand la politique l'exige : 403 attestation_required.
Corps de la requête Nom Type Obligatoire Description reasonstring non lost · compromised
twoFactorobject oui Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring oui totp · sms · backup_code
twoFactor.codestring oui twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/replace" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/replace');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import uuid
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/replace",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"twoFactor": {
"method": "totp",
"code": "••••••"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/replace", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json" },
body: JSON.stringify({
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"last4": "texte",
"network": "visa",
"currency": "USD",
"embossedName": "texte",
"status": "active",
"frozenByCompliance": true,
"model": "companion",
"balance": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"limits": {
"perTransaction": 0,
"daily": 0,
"monthly": 0,
"ecommerce": true
},
"closeReason": "texte",
"replacedBy": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"createdAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 201Nouvelle carte.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/cards/{id}/terminate
Fermer une carte
Fermeture définitive. Second facteur requis.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Opération financière : envoyez un Idempotency-Key unique par opération (rejoué 24 h).
Paramètres Nom Où Type Obligatoire Description idchemin string oui Identifiant de la carte.
Idempotency-Keyen-tête string oui Identifiant unique de l'opération (par exemple un UUID), conservé 24 h. Une même clé avec le même corps rejoue la réponse d'origine. Avec un autre corps : 422 idempotency_key_reused. Pendant le traitement : 409 idempotency_in_progress.
X-Linc-Attestationen-tête string non Assertion de l'installation attestée, pour une opération sensible. Hachage de la requête : base64url(SHA-256(METHOD "\n" PATH "\n" Idempotency-Key "\n" hex(SHA-256(corps)))). Android : jeton Play Integrity (requête standard) avec ce requestHash. iOS : assertion App Attest (CBOR en base64) sur le SHA-256 de ce hachage. Absente ou invalide quand la politique l'exige : 403 attestation_required.
Corps de la requête Nom Type Obligatoire Description twoFactorobject non Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring non totp · sms · backup_code
twoFactor.codestring non twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/terminate" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/terminate');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import uuid
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/terminate",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"twoFactor": {
"method": "totp",
"code": "••••••"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/terminate", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json" },
body: JSON.stringify({
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"last4": "texte",
"network": "visa",
"currency": "USD",
"embossedName": "texte",
"status": "active",
"frozenByCompliance": true,
"model": "companion",
"balance": {
"amount": 10000,
"currency": "USD",
"display": "texte"
},
"limits": {
"perTransaction": 0,
"daily": 0,
"monthly": 0,
"ecommerce": true
},
"closeReason": "texte",
"replacedBy": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"createdAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 200Carte fermée.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/cards/{id}/credential-show-session
Ouvrir une session d'affichage de la carte (SDK mobile)
Même contrôle que reveal (second facteur, audit) pour le SDK Credential Show de l'émetteur sur Android et iOS. L'application passe cardReference au SDK, qui affiche les détails lui-même. Opération sensible (X-Linc-Attestation).
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description idchemin string oui Identifiant de la carte.
X-App-Platformen-tête string non Plateforme de l'application mobile.
X-Linc-Attestationen-tête string non Assertion de l'installation attestée, pour une opération sensible. Hachage de la requête : base64url(SHA-256(METHOD "\n" PATH "\n" Idempotency-Key "\n" hex(SHA-256(corps)))). Android : jeton Play Integrity (requête standard) avec ce requestHash. iOS : assertion App Attest (CBOR en base64) sur le SHA-256 de ce hachage. Absente ou invalide quand la politique l'exige : 403 attestation_required.
Corps de la requête Nom Type Obligatoire Description twoFactorobject non Preuve de second facteur. Pour sms, joignez le challengeId du code reçu. Certaines opérations demandent un code saisi à l'instant, jamais un code de secours : le code de l'application d'authentification quand elle est activée depuis un certain temps, sinon un code SMS envoyé au téléphone vérifié (à demander avec POST /v1/me/security/otp, même si la double authentification par SMS n'est pas activée). Un autre moyen répond two_factor_method_unavailable (422), avec le moyen attendu dans le message. Quand aucun moyen ne convient, l'opération répond operation_unavailable (403) ou est mise en attente.
twoFactor.methodstring non totp · sms · backup_code
twoFactor.codestring non twoFactor.challengeIdstring (uuid) non
Exemple de requête {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/credential-show-session" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/credential-show-session');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/credential-show-session",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"twoFactor": {
"method": "totp",
"code": "••••••"
}
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/cards/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/credential-show-session", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"issuer": "texte",
"cardReference": "LP-7K2Q4F",
"last4": "texte",
"platform": "android",
"expiresAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 201Session pour le SDK Credential Show de l'émetteur.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/payment-links
Créer un lien de paiement
Crée une facture INV-XXXXXX payable sur https://app.linc.cd/pay/{id} (aussi par carte bancaire, sans compte Linc, si le marchand accepte les cartes). Le paiement est notifié par le webhook signé payment.succeeded ; un litige carte par payment.disputed.
Authentification : Clé secrète marchand : Authorization: Bearer sk_test_… (serveur uniquement)
Opération financière : envoyez un Idempotency-Key unique par opération (rejoué 24 h).
Paramètres Nom Où Type Obligatoire Description Idempotency-Keyen-tête string oui Identifiant unique de l'opération (par exemple un UUID), conservé 24 h. Une même clé avec le même corps rejoue la réponse d'origine. Avec un autre corps : 422 idempotency_key_reused. Pendant le traitement : 409 idempotency_in_progress.
Corps de la requête Nom Type Obligatoire Description amountstring oui Montant en décimal (texte), par exemple 42.50.
currencystring non descriptionstring oui Libellé de la facture.
expires_instring non 24h · 7d · 30d
Exemple de requête {
"amount": "25.00",
"currency": "USD",
"description": "Commande n° 10452",
"expires_in": "24h"
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/payment-links" \
-H "Authorization: Bearer $LINC_SECRET_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"amount": "25.00",
"currency": "USD",
"description": "Commande n° 10452",
"expires_in": "24h"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/payment-links');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_SECRET_KEY'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"amount": "25.00",
"currency": "USD",
"description": "Commande n° 10452",
"expires_in": "24h"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import uuid
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/payment-links",
headers={"Authorization": f"Bearer {os.environ['LINC_SECRET_KEY']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"amount": "25.00",
"currency": "USD",
"description": "Commande n° 10452",
"expires_in": "24h"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/payment-links", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_SECRET_KEY}`, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json" },
body: JSON.stringify({
"amount": "25.00",
"currency": "USD",
"description": "Commande n° 10452",
"expires_in": "24h"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"id": "INV-7K2Q4F",
"object": "payment_link",
"status": "open",
"livemode": false,
"description": "Commande n° 10452",
"amount": {
"amount": 2500,
"currency": "USD",
"display": "25,00 $"
},
"url": "https://app.linc.cd/pay/INV-7K2Q4F",
"qr": "000201010212…6304ABCD",
"expires_at": "2026-09-30T14:00:00+00:00",
"paid_at": null,
"created_at": "2026-09-29T14:00:00+00:00"
}
Réponses et erreurs Statut Signification 201Lien créé.
403ip_not_allowed : l'appel avec une clé secrète vient d'une adresse IP absente des adresses autorisées du marchand. sk_live_ est toujours contrôlée (liste vide = tout refusé) ; sk_test_ seulement si une liste sandbox est renseignée. Ajoutez l'adresse de votre serveur dans « API & webhooks › Adresses IP autorisées ».
Erreur au format application/problem+json : voir « Erreurs ».
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/payment-links/{id}
Afficher un lien de paiement
Authentification : Clé secrète marchand : Authorization: Bearer sk_test_… (serveur uniquement)
Paramètres Nom Où Type Obligatoire Description idchemin string oui Référence de la facture.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/payment-links/INV-7K2Q4F" \
-H "Authorization: Bearer $LINC_SECRET_KEY"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/payment-links/INV-7K2Q4F');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_SECRET_KEY')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/payment-links/INV-7K2Q4F",
headers={"Authorization": f"Bearer {os.environ['LINC_SECRET_KEY']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/payment-links/INV-7K2Q4F", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_SECRET_KEY}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"id": "INV-7K2Q4F",
"object": "payment_link",
"status": "open",
"livemode": false,
"description": "Commande n° 10452",
"amount": {
"amount": 2500,
"currency": "USD",
"display": "25,00 $"
},
"url": "https://app.linc.cd/pay/INV-7K2Q4F",
"qr": "000201010212…6304ABCD",
"expires_at": "2026-09-30T14:00:00+00:00",
"paid_at": null,
"created_at": "2026-09-29T14:00:00+00:00"
}
Réponses et erreurs Statut Signification 200Lien de paiement.
403ip_not_allowed : l'appel avec une clé secrète vient d'une adresse IP absente des adresses autorisées du marchand. sk_live_ est toujours contrôlée (liste vide = tout refusé) ; sk_test_ seulement si une liste sandbox est renseignée. Ajoutez l'adresse de votre serveur dans « API & webhooks › Adresses IP autorisées ».
Erreur au format application/problem+json : voir « Erreurs ».
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/tickets/options
Lister les types et catégories de demande
Types (réclamation, demande d'information), catégories et contraintes des pièces jointes.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/tickets/options" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/tickets/options');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/tickets/options",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/tickets/options", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"types": [
{
"code": "complaint",
"label": "texte"
}
],
"categories": [
{
"code": "transfer",
"label": "texte"
}
],
"attachments": {
"types": [
"texte"
],
"maxBytes": 0
}
}
Réponses et erreurs Statut Signification 200Options du formulaire de demande.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/tickets
Lister mes demandes
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/tickets" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/tickets');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/tickets",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/tickets", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"items": [
{
"reference": "LP-7K2Q4F",
"type": "complaint",
"category": "transfer",
"categoryLabel": "texte",
"subject": "texte",
"linkedReference": "LP-7K2Q4F",
"status": "received",
"statusLabel": "texte",
"createdAt": "2026-10-01T09:30:00Z",
"updatedAt": "2026-10-01T09:30:00Z"
}
]
}
Réponses et erreurs Statut Signification 200Demandes du client, de la plus récente à la plus ancienne.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/tickets
Ouvrir une demande
Ouvre une réclamation ou une demande d'information (référence TK-XXXXXX). Erreur 422 validation_failed ou ticket_invalid si le formulaire est incomplet.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Opération financière : envoyez un Idempotency-Key unique par opération (rejoué 24 h).
Paramètres Nom Où Type Obligatoire Description Idempotency-Keyen-tête string oui Identifiant unique de l'opération (par exemple un UUID), conservé 24 h. Une même clé avec le même corps rejoue la réponse d'origine. Avec un autre corps : 422 idempotency_key_reused. Pendant le traitement : 409 idempotency_in_progress.
Corps de la requête Nom Type Obligatoire Description typestring oui complaint : réclamation ; information : demande d'information.
complaint · information
categorystring oui transfer · merchant_payment · top_up · withdrawal_agent · card · kyc · account_security · fraud · technical · other
subjectstring oui descriptionstring oui linkedReferencestring non LP-…, INV-…, TX-…, TU-…, AG-…, QR-…, CL-…, RG-… ou CARD-1234 (4 derniers chiffres).
Exemple de requête {
"type": "complaint",
"category": "transfer",
"subject": "texte",
"description": "texte"
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/tickets" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"type": "complaint",
"category": "transfer",
"subject": "texte",
"description": "texte"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/tickets');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"type": "complaint",
"category": "transfer",
"subject": "texte",
"description": "texte"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import uuid
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/tickets",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"type": "complaint",
"category": "transfer",
"subject": "texte",
"description": "texte"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/tickets", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json" },
body: JSON.stringify({
"type": "complaint",
"category": "transfer",
"subject": "texte",
"description": "texte"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"reference": "LP-7K2Q4F",
"type": "complaint",
"category": "transfer",
"categoryLabel": "texte",
"subject": "texte",
"linkedReference": "LP-7K2Q4F",
"status": "received",
"statusLabel": "texte",
"createdAt": "2026-10-01T09:30:00Z",
"updatedAt": "2026-10-01T09:30:00Z",
"messages": [
{
"author": "texte",
"mine": true,
"body": "texte",
"createdAt": "2026-10-01T09:30:00Z"
}
],
"attachments": [
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"filename": "texte",
"mimeType": "application/pdf",
"size": 0,
"mine": true,
"scan": "pending",
"createdAt": "2026-10-01T09:30:00Z"
}
],
"canReply": true,
"canReopen": true,
"reopenUntil": "2026-10-01T09:30:00Z",
"canRate": true,
"satisfaction": 0,
"suggestedActions": [
"freeze_card"
]
}
Réponses et erreurs Statut Signification 201Demande ouverte.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/tickets/{reference}
Afficher une demande
Fil des échanges, pièces jointes et actions possibles. Erreur 404 ticket_not_found.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui Référence publique de la demande.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"reference": "LP-7K2Q4F",
"type": "complaint",
"category": "transfer",
"categoryLabel": "texte",
"subject": "texte",
"linkedReference": "LP-7K2Q4F",
"status": "received",
"statusLabel": "texte",
"createdAt": "2026-10-01T09:30:00Z",
"updatedAt": "2026-10-01T09:30:00Z",
"messages": [
{
"author": "texte",
"mine": true,
"body": "texte",
"createdAt": "2026-10-01T09:30:00Z"
}
],
"attachments": [
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"filename": "texte",
"mimeType": "application/pdf",
"size": 0,
"mine": true,
"scan": "pending",
"createdAt": "2026-10-01T09:30:00Z"
}
],
"canReply": true,
"canReopen": true,
"reopenUntil": "2026-10-01T09:30:00Z",
"canRate": true,
"satisfaction": 0,
"suggestedActions": [
"freeze_card"
]
}
Réponses et erreurs Statut Signification 200Demande.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/tickets/{reference}/messages
Répondre à une demande
Ajoute un message au fil. Erreur 404 ticket_not_found, 409 ticket_closed si la demande est clôturée.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Opération financière : envoyez un Idempotency-Key unique par opération (rejoué 24 h).
Paramètres Nom Où Type Obligatoire Description referencechemin string oui Référence publique de la demande.
Idempotency-Keyen-tête string oui Identifiant unique de l'opération (par exemple un UUID), conservé 24 h. Une même clé avec le même corps rejoue la réponse d'origine. Avec un autre corps : 422 idempotency_key_reused. Pendant le traitement : 409 idempotency_in_progress.
Corps de la requête Nom Type Obligatoire Description bodystring oui
Exemple de requête {
"body": "texte"
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/messages" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"body": "texte"
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/messages');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16)), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"body": "texte"
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import uuid
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/messages",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"body": "texte"
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/messages", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Idempotency-Key": crypto.randomUUID(), "Content-Type": "application/json" },
body: JSON.stringify({
"body": "texte"
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"reference": "LP-7K2Q4F",
"type": "complaint",
"category": "transfer",
"categoryLabel": "texte",
"subject": "texte",
"linkedReference": "LP-7K2Q4F",
"status": "received",
"statusLabel": "texte",
"createdAt": "2026-10-01T09:30:00Z",
"updatedAt": "2026-10-01T09:30:00Z",
"messages": [
{
"author": "texte",
"mine": true,
"body": "texte",
"createdAt": "2026-10-01T09:30:00Z"
}
],
"attachments": [
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"filename": "texte",
"mimeType": "application/pdf",
"size": 0,
"mine": true,
"scan": "pending",
"createdAt": "2026-10-01T09:30:00Z"
}
],
"canReply": true,
"canReopen": true,
"reopenUntil": "2026-10-01T09:30:00Z",
"canRate": true,
"satisfaction": 0,
"suggestedActions": [
"freeze_card"
]
}
Réponses et erreurs Statut Signification 201Demande mise à jour.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/tickets/{reference}/attachments
Joindre un fichier à une demande
Envoie un fichier dans le champ multipart file (PDF, JPEG ou PNG, 10 Mo maximum), analysé par l'antivirus avant de pouvoir être lu. Erreurs 422 attachment_type_refused ou attachment_too_large, 409 attachment_limit_reached.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui Référence publique de la demande.
Corps de la requête Fichier envoyé en multipart/form-data.
Nom Type Obligatoire Description filestring oui Fichier (PDF, JPEG ou PNG, 10 Mo maximum).
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/attachments" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-F "file=@document.jpg"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/attachments');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_POSTFIELDS => ['file' => new CURLFile('document.jpg')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/attachments",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
files={"file": open("document.jpg", "rb")},
timeout=30,
)
print(answer.status_code, answer.text)import { openAsBlob } from "node:fs";
const form = new FormData();
form.append("file", await openAsBlob("document.jpg"), "document.jpg");
const answer = await fetch("https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/attachments", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
body: form,
});
console.log(answer.status, await answer.text());
Exemple de réponse 201
{
"reference": "LP-7K2Q4F",
"type": "complaint",
"category": "transfer",
"categoryLabel": "texte",
"subject": "texte",
"linkedReference": "LP-7K2Q4F",
"status": "received",
"statusLabel": "texte",
"createdAt": "2026-10-01T09:30:00Z",
"updatedAt": "2026-10-01T09:30:00Z",
"messages": [
{
"author": "texte",
"mine": true,
"body": "texte",
"createdAt": "2026-10-01T09:30:00Z"
}
],
"attachments": [
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"filename": "texte",
"mimeType": "application/pdf",
"size": 0,
"mine": true,
"scan": "pending",
"createdAt": "2026-10-01T09:30:00Z"
}
],
"canReply": true,
"canReopen": true,
"reopenUntil": "2026-10-01T09:30:00Z",
"canRate": true,
"satisfaction": 0,
"suggestedActions": [
"freeze_card"
]
}
Réponses et erreurs Statut Signification 201Demande mise à jour.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/tickets/{reference}/attachments/{id}/link
Obtenir le lien de téléchargement d'une pièce jointe
Lien signé valable 5 minutes, réservé à l'utilisateur connecté. Erreur 404 si la pièce est inconnue, 409 attachment_unavailable tant que l'analyse antivirus n'est pas terminée ou si le fichier est infecté.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui Référence publique de la demande.
idchemin string oui Identifiant de la pièce jointe.
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/attachments/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/link" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/attachments/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/link');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/attachments/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/link",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/attachments/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f/link", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"url": "https://example.com",
"expiresAt": "2026-10-01T09:30:00Z"
}
Réponses et erreurs Statut Signification 200Lien de téléchargement signé.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
GET /v1/tickets/{reference}/attachments/{id}
Télécharger une pièce jointe
Adresse renvoyée par …/attachments/{id}/link, valable 5 minutes et liée à l'utilisateur qui l'a demandée ; le jeton d'accès reste exigé. Erreurs 403 attachment_link_invalid (lien expiré, altéré ou d'un autre utilisateur), 409 attachment_unavailable.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui Référence publique de la demande.
idchemin string oui Identifiant de la pièce jointe.
viewerrequête string oui Utilisateur auquel le lien est lié (fourni par le lien signé).
_expiresrequête string oui Expiration du lien (fournie par le lien signé).
_signaturerequête string oui Signature du lien.
Exemple de code cURL PHP Python JavaScript
curl "https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/attachments/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f?viewer=texte&_expires=texte&_signature=texte" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/attachments/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f?viewer=texte&_expires=texte&_signature=texte');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN')],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.get(
"https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/attachments/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f?viewer=texte&_expires=texte&_signature=texte",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/attachments/0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f?viewer=texte&_expires=texte&_signature=texte", {
method: "GET",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}` },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
Fichier (PDF ou image)
Réponses et erreurs Statut Signification 200Contenu de la pièce jointe (téléchargement, jamais mis en cache).
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/tickets/{reference}/reopen
Rouvrir une demande
Possible pendant un délai après la résolution (reopenUntil). Erreur 409 ticket_not_reopenable.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Opération financière : envoyez un Idempotency-Key unique par opération (rejoué 24 h).
Paramètres Nom Où Type Obligatoire Description referencechemin string oui Référence publique de la demande.
Idempotency-Keyen-tête string oui Identifiant unique de l'opération (par exemple un UUID), conservé 24 h. Une même clé avec le même corps rejoue la réponse d'origine. Avec un autre corps : 422 idempotency_key_reused. Pendant le traitement : 409 idempotency_in_progress.
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/reopen" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)"<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/reopen');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Idempotency-Key: ' . bin2hex(random_bytes(16))],
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import uuid
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/reopen",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/reopen", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Idempotency-Key": crypto.randomUUID() },
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"reference": "LP-7K2Q4F",
"type": "complaint",
"category": "transfer",
"categoryLabel": "texte",
"subject": "texte",
"linkedReference": "LP-7K2Q4F",
"status": "received",
"statusLabel": "texte",
"createdAt": "2026-10-01T09:30:00Z",
"updatedAt": "2026-10-01T09:30:00Z",
"messages": [
{
"author": "texte",
"mine": true,
"body": "texte",
"createdAt": "2026-10-01T09:30:00Z"
}
],
"attachments": [
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"filename": "texte",
"mimeType": "application/pdf",
"size": 0,
"mine": true,
"scan": "pending",
"createdAt": "2026-10-01T09:30:00Z"
}
],
"canReply": true,
"canReopen": true,
"reopenUntil": "2026-10-01T09:30:00Z",
"canRate": true,
"satisfaction": 0,
"suggestedActions": [
"freeze_card"
]
}
Réponses et erreurs Statut Signification 200Demande.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».
POST /v1/tickets/{reference}/satisfaction
Noter le traitement d'une demande
Une seule note par demande résolue ou clôturée. Erreurs 409 ticket_already_rated, 422 validation_failed.
Authentification : Jeton client : Authorization: Bearer <jeton d'accès>
Paramètres Nom Où Type Obligatoire Description referencechemin string oui Référence publique de la demande.
Corps de la requête Nom Type Obligatoire Description scoreinteger oui commentstring non
Exemple de requête {
"score": 0
}
Exemple de code cURL PHP Python JavaScript
curl -X POST "https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/satisfaction" \
-H "Authorization: Bearer $LINC_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"score": 0
}'<?php
$ch = curl_init('https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/satisfaction');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('LINC_ACCESS_TOKEN'), 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => <<<'JSON'
{
"score": 0
}
JSON,
CURLOPT_RETURNTRANSFER => true,
]);
$answer = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_RESPONSE_CODE), PHP_EOL;
print_r($answer);import os
import requests
answer = requests.post(
"https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/satisfaction",
headers={"Authorization": f"Bearer {os.environ['LINC_ACCESS_TOKEN']}"},
json={
"score": 0
},
timeout=30,
)
print(answer.status_code, answer.text)const answer = await fetch("https://sandbox.api.linc.cd/v1/tickets/LP-7K2Q4F/satisfaction", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.LINC_ACCESS_TOKEN}`, "Content-Type": "application/json" },
body: JSON.stringify({
"score": 0
}),
});
console.log(answer.status, await answer.text());
Exemple de réponse 200
{
"reference": "LP-7K2Q4F",
"type": "complaint",
"category": "transfer",
"categoryLabel": "texte",
"subject": "texte",
"linkedReference": "LP-7K2Q4F",
"status": "received",
"statusLabel": "texte",
"createdAt": "2026-10-01T09:30:00Z",
"updatedAt": "2026-10-01T09:30:00Z",
"messages": [
{
"author": "texte",
"mine": true,
"body": "texte",
"createdAt": "2026-10-01T09:30:00Z"
}
],
"attachments": [
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"filename": "texte",
"mimeType": "application/pdf",
"size": 0,
"mine": true,
"scan": "pending",
"createdAt": "2026-10-01T09:30:00Z"
}
],
"canReply": true,
"canReopen": true,
"reopenUntil": "2026-10-01T09:30:00Z",
"canRate": true,
"satisfaction": 0,
"suggestedActions": [
"freeze_card"
]
}
Réponses et erreurs Statut Signification 200Demande.
Toute autre erreur Erreur (RFC 9457).
Erreur au format application/problem+json : voir « Erreurs ».