Get started
Environment Base URL Use
Sandbox https://sandbox.api.linc.cdDevelopment and testing. sk_test_… keys, no real money, simulated partners.
Production https://api.linc.cdReal operations. sk_live_… keys, available once your application is approved.
Every route starts with /v1. Request and response bodies are JSON (UTF-8). You can call the API from any language that can make an HTTPS request: the examples below use cURL , PHP , Python and JavaScript (Node.js 18+) .
Open a merchant account at merchant.linc.cd . Your test keys are available right away.
Get your keys in Merchant portal › API & webhooks . The secret key is shown only once: keep it in a vault or an environment variable.
Register your webhook URL in the same place, then test on the sandbox.
Go live once your business verification (KYB) is approved: switch the base URL and the key.
Which integration?
You want to… Authentication Main routes
Collect payments from your customers (website, app, invoice) Merchant secret key sk_ /v1/payment-links
Act on behalf of a Linc customer: transfers, payments, virtual card, top-up Customer token (15-min JWT + refresh token) /v1/auth, /v1/quotes, /v1/transfers, /v1/cards
Build an app for a Linc merchant or agent Pro token (password + TOTP) /v1/pro/auth
Connect an agent network's platform, server to server Coming soon: scoped keys, signed requests and allowed IP addresses. Write to sales@linc.cd .
The customer API always acts for an identified customer, who confirms every sensitive operation with their own second factor. Linc never issues a customer token to a third party without the customer's consent.
Authentication
Merchant secret key
Send the key in the Authorization header. A missing or invalid key returns 401 api_key_invalid. Never use the secret key in a browser or a mobile app: it stays on your server.
curl https://sandbox.api.linc.cd/v1/payment-links/INV-7K2Q4F \
-H "Authorization: Bearer $LINC_SECRET_KEY"
Allowed IP addresses
Secret keys only work from the IP addresses of your servers. Declare them in the “Technical integration” step of your file, then manage them in your merchant space, “API & webhooks › Allowed IP addresses”. Each change is confirmed with your authenticator app.
Production (sk_live_): the list is required to generate the keys. A call from any other address returns 403 ip_not_allowed.
Sandbox (sk_test_): the list is optional. Empty, any address is accepted, including the test area of this page.
Up to 10 IPv4 (203.0.113.10) or IPv6 (2001:db8::10) addresses, or CIDR ranges (198.51.100.0/28; /8 to /32 in IPv4, /32 to /128 in IPv6).
The address checked is the one that connects to Linc: the outbound address of your server, or of your NAT gateway or outbound proxy. An X-Forwarded-For header sent by your code is ignored.
Moving to another host? Add the new address before the switch, then remove the old one.
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": "IP address not allowed for this key. Add your server's address in “API & webhooks › Allowed IP addresses”."}
Customer token: two-step sign-in
POST /v1/auth/login with the identifier (phone or e-mail) and password, and the X-Device-Id header (a stable installation identifier).
Known device: 200 response with the tokens. New device: 202 two_factor_required response with a pendingLoginId and the available methods (totp, sms, backup_code).
For SMS, request the code first: POST /v1/auth/login/{pendingLoginId}/sms. Then send the code: POST /v1/auth/login/{pendingLoginId}/verify.
Use accessToken (valid 15 minutes) in Authorization: Bearer …. Before it expires, call POST /v1/auth/refresh: the refresh token rotates , so keep the new one and discard the old one.
cURL PHP Python JavaScript
# 1. Password
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 factor
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. Refresh
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
Idempotency Every financial POST requires the Idempotency-Key header (8 to 255 characters, one UUID per operation). The key is kept for 24 hours: sending the same request with the same key never creates a duplicate. The same key with a different body returns idempotency_key_reused.
Amounts As input, a decimal string: "150.00". As output, an object {"amount": 15000, "currency": "USD", "display": "150,00 $"} where amount is an integer in minor units. Never use floating-point numbers for money.
Currencies and countries ISO 4217 codes (USD, CDF) and ISO 3166 alpha-2 codes (CI, SN…). Open countries and payout methods are listed by GET /v1/corridors (public).
Second factor Sensitive operations (transfer, payment, card, beneficiary) take a "twoFactor": {"method": "totp", "code": "••••••"} object. Without it, the response is two_factor_required: ask the customer for the code, then resend the request with the same Idempotency-Key.
Mobile apps Send X-Device-Id, X-App-Id, X-App-Platform and X-App-Version. When the policy requires it, sensitive operations also need X-Linc-Attestation (attested device).
Asynchronous A transfer or payment is accepted (202) and then processed: track its status by webhook or GET, never assume it succeeded.
Send a transfer
Example: 150 USD from Airtel Money (DRC) to an Orange Money wallet in Côte d'Ivoire.
1 Amount and country The customer picks the country and payout method.
2 Quote Fees, rate, total debited, amount received. Valid 60 s.
3 Beneficiary Mobile money number, bank account or card.
4 Confirmation Source of funds and 6-digit code (2FA).
5 Tracking Collection, payout, delivery, in real time.
POST /v1/quotes: amount, currency, country and payout method. Response: id, send, fee, vat, levy, total, receive, rate, expiresAt. Show them to the customer as returned.
POST /v1/beneficiaries (once per beneficiary): name, country, method and details in details.
POST /v1/transfers before the quote expires: quoteId, beneficiaryId, source, purpose and twoFactor. 202 response with the LP-XXXXXX reference.
GET /v1/transfers/{reference}: status is in_progress, delivered, failed, refunded or on_hold, with the steps.
cURL PHP Python JavaScript
# 1. Quote
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. Beneficiary
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. Transfer, confirmed with the second factor
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. Tracking
curl https://sandbox.api.linc.cd/v1/transfers/LP-8QK2ZD -H "Authorization: Bearer $ACCESS_TOKEN"
<?php
// linc(): see the authentication example
$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()]);
// Show $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
Possible sources: mobile_money (Airtel Money, M-Pesa, Orange Money, Afrimoney), wallet (Linc balance, wallet-mode account) and card when that flow is open. Destinations: mobile_money, bank_account or card. Available countries and methods depend on the open corridors: read them from GET /v1/corridors instead of hard-coding them.
Collect a payment (merchant)
1 Your site Your server creates the payment link.
2 Linc page The customer opens app.linc.cd/pay/INV-… or scans the QR.
3 Payment Balance, mobile money or card, confirmed by the customer.
4 Receipt You receive payment.succeeded.
POST /v1/payment-links with your secret key: amount, description, expires_in (24h, 7d or 30d). The response contains id (INV-XXXXXX), url and qr.
Redirect the customer to url, show the QR or send the link by SMS.
Fulfil the order when you receive the payment.succeeded webhook (not when the customer returns to your site). As a fallback, read the status with GET /v1/payment-links/{id}: open, paid, expired or 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": "Order no. 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' => 'Order no. 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": "Order no. 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: "Order no. 10452", expires_in: "24h" }),
});
const link = await res.json();
response.redirect(303, link.url);
A link created with a test key (livemode: false) can never be paid for real. In the customer app, paying a link or a QR uses POST /v1/merchant-payments/resolve (read the QR or link), then POST /v1/merchant-payments (pay, with the second factor). Card payments go through a hosted card page with 3-D Secure: you never handle the card number.
Create a virtual card
Available to a customer in wallet mode with KYC level 2 . The card is funded from the Linc balance.
1 Network Visa or Mastercard, name on the card.
2 Confirmation 6-digit code (2FA).
3 Card Last 4 digits, status, limits.
4 Details Shown by the issuer's secure widget.
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": {…}, …}
# Freeze, unfreeze
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 never returns the full card number, the CVV or the expiry date. To show them, POST /v1/cards/{id}/reveal (with the second factor) opens a 60-second session for the issuer's widget or SDK, which displays the details directly to the customer. Other routes: GET /v1/cards, GET /v1/cards/{id}/transactions, /replace, /terminate.
Receive webhooks
Linc sends a JSON POST to the URL registered in Merchant portal › API & webhooks (HTTPS required) for every event:
Event When
payment.succeededA payment is confirmed by the partner. Fulfil the order.
payment.refundedA payment is refunded, fully or partially.
payment.disputedA card payment is disputed.
settlement.paidThe daily settlement is paid to your bank account, net of commission.
Headers sent: X-Linc-Event (type), X-Linc-Delivery (unique event identifier) and X-Linc-Signature:
X-Linc-Signature: t=1790712000,v1=5f1c…e9a2
# v1 = hex HMAC-SHA256, key = webhook secret (whsec_…), message = "{t}.{raw body}"
{
"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", …
}
}
Always verify the signature on the raw body, before decoding it, and reject a timestamp older than 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);
// Skip an event already processed ($event['id']), then process it in a queue
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() # raw body
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()
# Skip an event already processed (event["id"]), then process it in a queue
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);
// Skip an event already processed (event.id), then process it in a queue
res.sendStatus(200);
});
Reply 2xx within 10 seconds, then process in the background.
Without a 2xx reply, Linc resends the event after 1 min, 5 min, 30 min, 2 h and 6 h.
The same event may arrive twice: deduplicate on id (or X-Linc-Delivery).
Delivery order is not guaranteed: rely on the status inside data.
The webhook secret can be renewed in the merchant portal; so can the API keys (rotation).
Test space
Check your key and see the real API answers without writing code. Calls go from your browser to the sandbox https://sandbox.api.linc.cd, which accepts test keys only: no real money, no payable link.
Type only an sk_test_… key. An sk_live_… key is refused before anything is sent. The key stays in this page: it is never stored, logged or put in the address. Close the tab to erase it.
Result
Type your test key, then click “Check the key”.
Equivalent request
Sign and verify a webhook
Test your verification code: paste the raw body received and the X-Linc-Signature header, or generate a header for a test body. The computation runs in your browser : nothing is sent. Preferably use the secret of your test webhook.
JSON files
Request and response examples that follow the API contract. Download them for your tests, screen mock-ups or simulators (file names are in French).
Sandbox Postman collection
Import the collection into Postman, then fill in secretKey (test key) or the credentials of a test account, and deviceId. Tokens, quotes, beneficiaries and references are saved automatically from one request to the next.
Errors
Errors use the application/problem+json format (RFC 9457), with a stable code to test in your code and a readable title:
HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json
{"type": "https://docs.linc.cd/erreurs/validation_failed", "title": "Some fields are invalid. Correct them, then try again.",
"status": 422, "code": "validation_failed",
"violations": [{"field": "amount", "message": "…"}]}
Code What to do
validation_failedFix the fields listed in violations.
api_key_invalidCheck the key and the environment (sk_test_ on the sandbox, sk_live_ in production).
ip_not_allowedThe call comes from an IP address that is not among your allowed addresses : add your server's address in “API & webhooks”.
two_factor_requiredAsk the customer for the code and resend the request with twoFactor.
quote_expiredThe quote is older than 60 seconds: request a new one and show it to the customer.
quote_already_usedThis quote was already used: track the existing transfer.
idempotency_key_requiredAdd the Idempotency-Key header.
idempotency_key_reusedSame key, different body: generate a new key for a new operation.
idempotency_in_progressThe first request is still running: retry in a few seconds.
attestation_requiredSend the device's X-Linc-Attestation assertion.
app_update_requiredUpdate the app (minimumVersion).
rate_limitedToo many requests: wait, then retry with an increasing delay.
Help and security
Never put a secret key, webhook secret or token in source code, a mobile app or a browser.
Log the code and the reference (LP-…, INV-…), never personal data.
Full documentation generated from the OpenAPI contract, and the developer space, are coming soon.
Technical questions: support@linc.cd . Partnerships and production access: sales@linc.cd .
POST /v1/auth/register
Create a customer account
The detailed descriptions of this sheet are written in French.
Crée le compte et envoie un code SMS de vérification du téléphone.
Authentication: None (public route)
Parameters Name In Type Required Description X-Device-Idheader string no Identifiant d'installation de l'application. Un appareil inconnu déclenche la double authentification.
Request body Name Type Required Description fullNamestring yes phonestring yes Numéro de téléphone, par exemple +243812345678.
emailstring (email) yes passwordstring yes 8 caractères au moins avec un chiffre. Refusé s'il figure dans une fuite connue.
acceptTermsboolean yes Case « J'ai lu et j'accepte les Conditions générales d'utilisation » (versions : GET /v1/legal).
acceptPrivacyboolean yes Case « J'ai lu la Politique de confidentialité et j'accepte le traitement de mes données décrit ».
acceptAmlboolean yes 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 no 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).
Request example {
"fullName": "texte",
"phone": "+243810000000",
"email": "client@example.com",
"password": "••••••••",
"acceptTerms": true,
"acceptPrivacy": true,
"acceptAml": true
}
Code example 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());
Answer example 201
{
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"purpose": "phone_verification",
"sentTo": "texte",
"expiresAt": "2026-10-01T09:30:00Z",
"remainingAttempts": 0
}
Answers and errors Status Meaning 201Compte créé. Code SMS envoyé.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/origin-countries
List the countries of residence accepted at sign-up
The detailed descriptions of this sheet are written in French.
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.
Authentication: None (public route)
Code example 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());
Answer example 200
{
"countries": [
{
"country": "CD",
"name": "Congo-Kinshasa",
"callingCode": "+243",
"default": true
}
]
}
Answers and errors Status Meaning 200Pays de résidence acceptés.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/auth/register/resend
Resend the verification code
The detailed descriptions of this sheet are written in French.
Envoie un nouveau code SMS pour la vérification du téléphone.
Authentication: None (public route)
Request body Name Type Required Description challengeIdstring (uuid) yes
Request example {
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f"
}
Code example 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());
Answer example 201
{
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"purpose": "phone_verification",
"sentTo": "texte",
"expiresAt": "2026-10-01T09:30:00Z",
"remainingAttempts": 0
}
Answers and errors Status Meaning 201Nouveau code envoyé.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/auth/verify-phone
Verify the phone number
The detailed descriptions of this sheet are written in French.
Valide le code SMS, active le compte et ouvre une session mobile.
Authentication: None (public route)
Parameters Name In Type Required Description X-Device-Idheader string no Identifiant d'installation de l'application. Un appareil inconnu déclenche la double authentification.
Request body Name Type Required Description challengeIdstring (uuid) yes codestring yes Code à 6 chiffres reçu par SMS.
Request example {
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"code": "••••••"
}
Code example 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());
Answer example 200
{
"tokenType": "Bearer",
"accessToken": "…",
"expiresIn": 0,
"refreshToken": "…",
"refreshExpiresIn": 0
}
Answers and errors Status Meaning 200Téléphone vérifié. Jetons de session.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/auth/login
Sign in
The detailed descriptions of this sheet are written in French.
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.
Authentication: None (public route)
Parameters Name In Type Required Description X-Device-Idheader string no Identifiant d'installation de l'application. Un appareil inconnu déclenche la double authentification.
Request body Name Type Required Description identifierstring yes Téléphone ou e-mail.
passwordstring yes
Request example {
"identifier": "+243810000000",
"password": "••••••••"
}
Code example 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());
Answer example 200
{
"status": "two_factor_required",
"pendingLoginId": "0192a7c4-2c9d-7e41-a3b5-6f7e8d9c0b12",
"methods": [
"totp",
"sms",
"backup_code"
],
"expiresAt": "2026-09-29T14:05:00+00:00"
}
Answers and errors Status Meaning 200Connexion réussie.
202Double authentification requise.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/auth/login/{pendingLoginId}/sms
Receive the sign-in code by SMS
The detailed descriptions of this sheet are written in French.
Envoie un code SMS pour terminer une connexion en attente.
Authentication: None (public route)
Parameters Name In Type Required Description pendingLoginIdpath string yes Identifiant de la connexion en attente.
Code example 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());
Answer example 201
{
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"purpose": "phone_verification",
"sentTo": "texte",
"expiresAt": "2026-10-01T09:30:00Z",
"remainingAttempts": 0
}
Answers and errors Status Meaning 201Code envoyé.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/auth/login/{pendingLoginId}/verify
Finish signing in with the second factor
The detailed descriptions of this sheet are written in French.
Vérifie le code TOTP, SMS ou de secours et ouvre la session sur ce nouvel appareil.
Authentication: None (public route)
Parameters Name In Type Required Description pendingLoginIdpath string yes Identifiant de la connexion en attente.
X-Device-Idheader string no Identifiant d'installation de l'application. Un appareil inconnu déclenche la double authentification.
Request body Name Type Required Description methodstring yes totp · sms · backup_code
codestring yes challengeIdstring (uuid) no
Request example {
"method": "totp",
"code": "••••••"
}
Code example 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());
Answer example 200
{
"tokenType": "Bearer",
"accessToken": "eyJ…",
"expiresIn": 900,
"refreshToken": "…",
"refreshExpiresIn": 2592000
}
Answers and errors Status Meaning 200Connexion réussie.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/auth/refresh
Renew the tokens
The detailed descriptions of this sheet are written in French.
Échange le jeton de rafraîchissement contre une nouvelle paire (rotation). Un jeton réutilisé révoque la session.
Authentication: None (public route)
Request body Name Type Required Description refreshTokenstring yes
Request example {
"refreshToken": "…"
}
Code example 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());
Answer example 200
{
"tokenType": "Bearer",
"accessToken": "eyJ…",
"expiresIn": 900,
"refreshToken": "…",
"refreshExpiresIn": 2592000
}
Answers and errors Status Meaning 200Nouvelle paire de jetons.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/auth/logout
Sign out
The detailed descriptions of this sheet are written in French.
Révoque le jeton de rafraîchissement.
Authentication: None (public route)
Request body Name Type Required Description refreshTokenstring yes
Request example {
"refreshToken": "…"
}
Code example 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());
Answer example 204
Session fermée.
Answers and errors Status Meaning 204Session fermée.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/me
Show my profile
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 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
}
}
Answers and errors Status Meaning 200Profil du client connecté.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
PUT /v1/me/locale
Choose the account language
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Request body Name Type Required Description localestring yes fr · en
Request example {
"locale": "fr"
}
Code example 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());
Answer example 200
{
"locale": "fr"
}
Answers and errors Status Meaning 200Langue enregistrée.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/me/consents/contract
Accept the new version of the contract documents
The detailed descriptions of this sheet are written in French.
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).
Authentication: Customer token: Authorization: Bearer <access token>
Request body Name Type Required Description acceptTermsboolean no Case des Conditions générales, obligatoire si elles sont en attente.
acceptPrivacyboolean no Case de la Politique de confidentialité, obligatoire si elle est en attente.
acceptAmlboolean no Case de la Politique LBC/FT, obligatoire si elle est en attente.
acceptContractboolean no Case du contrat d'utilisation, obligatoire seulement s'il est seul en attente.
Request example {
"acceptTerms": false,
"acceptPrivacy": false,
"acceptAml": false,
"acceptContract": false
}
Code example 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());
Answer example 200
{
"termsAcceptanceRequired": true,
"pending": [
{
"document": "terms",
"version": "texte"
}
],
"biometric": true
}
Answers and errors Status Meaning 200Consentements à jour.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/me/consents/terms
Accepter les documents du contrat (ancien nom)
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Request body Name Type Required Description acceptTermsboolean no Case des Conditions générales, obligatoire si elles sont en attente.
acceptPrivacyboolean no Case de la Politique de confidentialité, obligatoire si elle est en attente.
acceptAmlboolean no Case de la Politique LBC/FT, obligatoire si elle est en attente.
acceptContractboolean no Case du contrat d'utilisation, obligatoire seulement s'il est seul en attente.
Request example {
"acceptTerms": false,
"acceptPrivacy": false,
"acceptAml": false,
"acceptContract": false
}
Code example 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());
Answer example 200
{
"termsAcceptanceRequired": true,
"pending": [
{
"document": "terms",
"version": "texte"
}
],
"biometric": true
}
Answers and errors Status Meaning 200Consentements à jour.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/me/consents/biometric
Consent to biometric processing
The detailed descriptions of this sheet are written in French.
Consentement explicite au traitement du visage, requis avant l'envoi d'un selfie ou d'images de vivacité.
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 200
{
"termsAcceptanceRequired": true,
"pending": [
{
"document": "terms",
"version": "texte"
}
],
"biometric": true
}
Answers and errors Status Meaning 200Consentements à jour.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/me/documents
Show the documents I accepted
The detailed descriptions of this sheet are written in French.
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).
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 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"
]
}
Answers and errors Status Meaning 200Documents et preuves d'acceptation.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
PUT /v1/me/account-mode
Choose the account mode
The detailed descriptions of this sheet are written in French.
wallet conserve un solde chez Linc. pass_through débite directement le mobile money.
Authentication: Customer token: Authorization: Bearer <access token>
Request body Name Type Required Description modestring yes wallet · pass_through
Request example {
"mode": "wallet"
}
Code example 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());
Answer example 200
{
"accountMode": "wallet"
}
Answers and errors Status Meaning 200Mode enregistré.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/me/communications
Afficher les choix de communication
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 200
{
"email": true,
"sms": true
}
Answers and errors Status Meaning 200Choix en cours.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
PUT /v1/me/communications
Choisir les communications
The detailed descriptions of this sheet are written in French.
Oui ou non pour chaque canal. Chaque choix est conservé comme preuve du consentement.
Authentication: Customer token: Authorization: Bearer <access token>
Request body Name Type Required Description emailboolean yes Nouveautés par e-mail (à une adresse vérifiée seulement).
smsboolean yes Nouveautés par SMS, de 8 h à 20 h (heure de Kinshasa). Répondre STOP les arrête.
Request example {
"email": true,
"sms": true
}
Code example 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());
Answer example 200
{
"email": true,
"sms": true
}
Answers and errors Status Meaning 200Choix enregistrés.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/me/security/two-factor
Show the two-factor status
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 200
{
"totp": true,
"sms": true,
"backupCodesRemaining": true,
"availableMethods": [
"totp"
]
}
Answers and errors Status Meaning 200Méthodes actives et méthodes utilisables.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/me/security/otp
Receive an SMS confirmation code
The detailed descriptions of this sheet are written in French.
Envoie un code SMS pour confirmer une opération sensible. Utilisez le challengeId retourné dans twoFactor.
Authentication: Customer token: Authorization: Bearer <access token>
Request body Name Type Required Description purposestring yes security_change · transfer · payment · withdrawal · card_reveal · card_management · card_add · beneficiary_add
Request example {
"purpose": "security_change"
}
Code example 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());
Answer example 201
{
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"purpose": "phone_verification",
"sentTo": "texte",
"expiresAt": "2026-10-01T09:30:00Z",
"remainingAttempts": 0
}
Answers and errors Status Meaning 201Code envoyé.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/me/security/password
Change the password
The detailed descriptions of this sheet are written in French.
Exige le mot de passe actuel et un second facteur. Les autres sessions sont fermées.
Authentication: Customer token: Authorization: Bearer <access token>
Request body Name Type Required Description currentPasswordstring yes newPasswordstring yes twoFactorobject yes 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 yes totp · sms · backup_code
twoFactor.codestring yes twoFactor.challengeIdstring (uuid) no
Request example {
"currentPassword": "••••••••",
"newPassword": "••••••••",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Code example 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());
Answer example 204
Mot de passe changé.
Answers and errors Status Meaning 204Mot de passe changé.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/me/security/totp/setup
Start the TOTP setup
The detailed descriptions of this sheet are written in French.
Retourne le secret et l'URI otpauth:// à afficher en QR code. Second facteur requis.
Authentication: Customer token: Authorization: Bearer <access token>
Request body Name Type Required Description twoFactorobject no 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 no totp · sms · backup_code
twoFactor.codestring no twoFactor.challengeIdstring (uuid) no
Request example {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Code example 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());
Answer example 201
{
"secret": "••••••••",
"uri": "texte"
}
Answers and errors Status Meaning 201Secret généré, en attente de confirmation.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/me/security/totp/confirm
Confirm the TOTP setup
The detailed descriptions of this sheet are written in French.
Valide un premier code de l'application. Retourne les codes de secours, affichés une seule fois.
Authentication: Customer token: Authorization: Bearer <access token>
Request body Name Type Required Description codestring yes Code à 6 chiffres de l'application d'authentification.
Request example {
"code": "••••••"
}
Code example 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());
Answer example 200
{
"backupCodes": [
"123456"
]
}
Answers and errors Status Meaning 200TOTP activé.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/me/security/totp/disable
Turn TOTP off
The detailed descriptions of this sheet are written in French.
Second facteur requis.
Authentication: Customer token: Authorization: Bearer <access token>
Request body Name Type Required Description twoFactorobject no 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 no totp · sms · backup_code
twoFactor.codestring no twoFactor.challengeIdstring (uuid) no
Request example {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Code example 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());
Answer example 204
TOTP désactivé.
Answers and errors Status Meaning 204TOTP désactivé.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
PUT /v1/me/security/sms
Turn SMS two-factor on or off
Authentication: Customer token: Authorization: Bearer <access token>
Request body Name Type Required Description enabledboolean yes twoFactorobject no 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 no totp · sms · backup_code
twoFactor.codestring no twoFactor.challengeIdstring (uuid) no
Request example {
"enabled": true
}
Code example 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());
Answer example 200
{
"totp": true,
"sms": true,
"backupCodesRemaining": true
}
Answers and errors Status Meaning 200Nouvel état de la double authentification.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/me/security/backup-codes
Regenerate the backup codes
The detailed descriptions of this sheet are written in French.
Invalide les anciens codes. TOTP actif et second facteur requis.
Authentication: Customer token: Authorization: Bearer <access token>
Request body Name Type Required Description twoFactorobject no 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 no totp · sms · backup_code
twoFactor.codestring no twoFactor.challengeIdstring (uuid) no
Request example {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Code example 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());
Answer example 200
{
"backupCodes": [
"123456"
]
}
Answers and errors Status Meaning 200Nouveaux codes, affichés une seule fois.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/legal
List the legal documents in force
The detailed descriptions of this sheet are written in French.
Versions à accepter à l'inscription (public).
Authentication: None (public route)
Code example 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());
Answer example 200
{
"documents": [
{
"document": "terms",
"title": "texte",
"version": "texte",
"date": "1990-01-31",
"draft": true,
"url": "https://example.com"
}
]
}
Answers and errors Status Meaning 200Documents légaux.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/kyc/cases
Open a KYC case
The detailed descriptions of this sheet are written in French.
Ouvre un dossier pour le niveau 2 (identité vérifiée) ou 3 (vigilance renforcée).
Authentication: Customer token: Authorization: Bearer <access token>
Financial operation: send a unique Idempotency-Key per operation (replayed for 24 h).
Parameters Name In Type Required Description Idempotency-Keyheader string yes 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.
Request body Name Type Required Description targetLevelinteger yes 2 · 3
documentTypestring no voter_card · passport · driving_license · national_id
documentNumberstring no issuingCountrystring no residenceCountrystring no 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) no addressstring no occupationstring no sourceOfFundsstring no expectedMonthlyAmountstring no Montant mensuel attendu en USD (décimal en texte), par exemple 1500.00.
documentExpiresOnstring (date) no 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 no Nationalité (ISO 3166 alpha-2), niveau 2. Par défaut, le pays qui a délivré la pièce.
residencePermitNumberstring no 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) no Date d'expiration du titre de séjour ; son renouvellement suit celui de la pièce.
Request example {
"targetLevel": 2
}
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 201Dossier ouvert.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/kyc/cases/current
Show my current KYC case
The detailed descriptions of this sheet are written in French.
Niveau actuel et dernier dossier. Interrogez cette route pour suivre la décision.
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 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"
}
}
Answers and errors Status Meaning 200Niveau KYC et dossier (ou null).
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/kyc/cases/{id}/documents/{kind}
Add a document to the KYC case
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes Identifiant du dossier.
kindpath string yes Type de document.
Request body File sent as multipart/form-data.
Name Type Required Description filestring yes Photo du document (JPEG, PNG ou PDF).
captureSourcestring no Origine de l'image ; camera obligatoire pour la pièce et le visage au niveau 2.
camera · handoff · upload
challengestring no Consigne du contrôle du vivant actif.
turn_left · turn_right · blink · smile · look_up
brightnessinteger no Luminosité moyenne mesurée par l'application avant l'envoi.
sharpnessinteger no Netteté mesurée par l'application (variance du laplacien).
glareinteger no Part de pixels brûlés (reflet), en millièmes.
Code example 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());
Answer example 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"
}
}
Answers and errors Status Meaning 201Document ajouté.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/kyc/cases/{id}/submit
Submit the KYC case
The detailed descriptions of this sheet are written in French.
Lance la vérification. Le résultat arrive de façon asynchrone (SMS et GET /v1/kyc/cases/current).
Authentication: Customer token: Authorization: Bearer <access token>
Financial operation: send a unique Idempotency-Key per operation (replayed for 24 h).
Parameters Name In Type Required Description idpath string yes Identifiant du dossier.
Idempotency-Keyheader string yes 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.
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 202Dossier envoyé, vérification en cours.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/corridors
List the open corridors
The detailed descriptions of this sheet are written in French.
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.
Authentication: None (public route)
Code example 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());
Answer example 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"
]
}
]
}
Answers and errors Status Meaning 200Corridors ouverts.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/journeys
List the journeys open to the customer
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description countryquery string yes Pays de destination (le pays du marchand pour un paiement, CD pour le solde).
currencyquery string no Devise reçue ; absente, toute devise.
Code example 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());
Answer example 200
{
"country": "KE",
"currency": "USD",
"journeys": [
{
"source": "card_visa_aft",
"destination": "card_visa"
}
]
}
Answers and errors Status Meaning 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.
Error as application/problem+json: see “Errors”.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/quotes
Ask for a quote
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Financial operation: send a unique Idempotency-Key per operation (replayed for 24 h).
Parameters Name In Type Required Description Idempotency-Keyheader string yes 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.
Request body Name Type Required Description amountstring no Montant envoyé en décimal (texte), par exemple 150.00. Ancien nom de sendAmount.
sendAmountstring no Montant envoyé en décimal (texte), par exemple 150.00.
receiveAmountstring no Montant à recevoir dans la devise reçue, avec ses décimales (XOF 0, KWD 3), par exemple 50000.
totalAmountstring no Total payé par le client dans la devise envoyée, frais déduits, par exemple 100.00.
operatorstring no 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 no Facultatif (mobile_money) : numéro du bénéficiaire, l'opérateur est déduit de son préfixe quand operator est absent.
currencystring yes Code devise ISO 4217.
destinationCountrystring yes payoutMethodstring yes 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 no Une des devises du corridor. Vide = devise principale du corridor.
sourceTypestring no 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
Request example {
"amount": "150.00",
"currency": "USD",
"destinationCountry": "CI",
"payoutMethod": "mobile_money",
"sourceType": "mobile_money"
}
Code example 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());
Answer example 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
}
Answers and errors Status Meaning 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.
Error as application/problem+json: see “Errors”.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/quotes/preview
Aperçu du prix pendant la saisie
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description destinationCountryquery string yes payoutMethodquery string yes currencyquery string no Devise envoyée (USD par défaut).
sendAmountquery string no amountquery string no Ancien nom de sendAmount.
receiveAmountquery string no totalAmountquery string no Total payé par le client dans la devise envoyée
receiveCurrencyquery string no sourceTypequery string no operatorquery string no Opérateur du wallet du bénéficiaire (nom ou code), pour sa ligne de la grille du partenaire.
msisdnquery string no Numéro du bénéficiaire : opérateur déduit du préfixe sans operator.
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 200Prix indicatif.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/quotes/{id}
Show a quote
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes Identifiant du devis.
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 200Devis.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/reference/banks
Chercher une banque du pays pendant la frappe
The detailed descriptions of this sheet are written in French.
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à).
Authentication: None (public route)
Parameters Name In Type Required Description countryquery string yes Pays de la banque (ISO 3166-1 alpha-2).
qquery string no Début ou partie du nom, du sigle, du BIC ou du code de la banque ; 2 caractères au moins.
Code example 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());
Answer example 200
{
"banks": [
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"name": "texte"
}
]
}
Answers and errors Status Meaning 200Banques trouvées (vide pour un pays inconnu).
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/reference/destination-formats
Formats de destination d'un pays
The detailed descriptions of this sheet are written in French.
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à).
Authentication: None (public route)
Parameters Name In Type Required Description countryquery string yes Pays du bénéficiaire (ISO 3166-1 alpha-2).
Code example 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());
Answer example 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": []
}
]
}
]
}
Answers and errors Status Meaning 200Formats du pays (listes vides pour un pays inconnu).
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/beneficiaries
List my beneficiaries
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 200
{
"beneficiaries": [
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"fullName": "texte",
"country": "KE",
"payoutMethod": "mobile_money",
"destination": "texte"
}
]
}
Answers and errors Status Meaning 200Bénéficiaires enregistrés.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/beneficiaries
Add a beneficiary
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Request body Name Type Required Description fullNamestring yes countrystring yes payoutMethodstring yes 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 no 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 no 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 no totp · sms · backup_code
twoFactor.codestring no twoFactor.challengeIdstring (uuid) no
Request example {
"fullName": "Bastian Kelyan",
"country": "CI",
"payoutMethod": "mobile_money",
"details": {
"msisdn": "+2250700000000",
"provider": "orange",
"relationship": "family"
}
}
Code example 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());
Answer example 201
{
"id": "0192a7c4-6f02-7a55-8e21-7b4c0d9e2f33",
"fullName": "Bastian Kelyan",
"country": "CI",
"payoutMethod": "mobile_money",
"destination": "Orange Money •• 0000"
}
Answers and errors Status Meaning 201Bénéficiaire ajouté.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
PATCH /v1/beneficiaries/{id}
Complete the bank code of a beneficiary
The detailed descriptions of this sheet are written in French.
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).
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes Identifiant du bénéficiaire.
Request body Name Type Required Description bankCodestring yes Sort code (Royaume-Uni), ABA (États-Unis) ou code banque ou guichet.
twoFactorobject no 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 no totp · sms · backup_code
twoFactor.codestring no twoFactor.challengeIdstring (uuid) no
Request example {
"bankCode": "123456"
}
Code example 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());
Answer example 200
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"fullName": "texte",
"country": "KE",
"payoutMethod": "mobile_money",
"destination": "texte"
}
Answers and errors Status Meaning 200Bénéficiaire complété (coordonnées masquées).
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
DELETE /v1/beneficiaries/{id}
Delete a beneficiary
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes Identifiant du bénéficiaire.
Code example 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());
Answer example 204
Bénéficiaire supprimé.
Answers and errors Status Meaning 204Bénéficiaire supprimé.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/beneficiaries/{id}/purposes
Purposes offered for this beneficiary
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes Identifiant du bénéficiaire.
quoteIdquery string no Devis en cours (devise reçue). Par défaut, la devise principale du corridor.
Code example 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());
Answer example 200
{
"purposes": [
{
"code": "family_support",
"label": "texte"
}
]
}
Answers and errors Status Meaning 200Motifs proposés, dans l'ordre d'affichage.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/transfers
List my transfers
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 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"
}
]
}
Answers and errors Status Meaning 200Envois du client, du plus récent au plus ancien.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/transfers
Send money
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Financial operation: send a unique Idempotency-Key per operation (replayed for 24 h).
Parameters Name In Type Required Description Idempotency-Keyheader string yes 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-Attestationheader string no 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.
Request body Name Type Required Description quoteIdstring (uuid) yes beneficiaryIdstring (uuid) yes sourceobject yes source.typestring yes 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 no airtel · mpesa · orange · afrimoney
source.msisdnstring no source.savedWalletIdstring (uuid) no 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) no Source card : carte enregistrée choisie dans le devis (GET /v1/saved-cards), proposée sur la page carte sans ressaisie.
purposestring no 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 yes 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 yes totp · sms · backup_code
twoFactor.codestring yes twoFactor.challengeIdstring (uuid) no
Request example {
"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": "••••••"
}
}
Code example 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());
Answer example 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
}
Answers and errors Status Meaning 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.
Error as application/problem+json: see “Errors”.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/transfers/{reference}/repeat
Renvoyer un transfert (valeurs pré-remplies)
The detailed descriptions of this sheet are written in French.
« 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.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes
Code example 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());
Answer example 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"
}
}
Answers and errors Status Meaning 200Valeurs de l'écran d'envoi.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/transfers/{reference}
Track a transfer
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes Référence publique de l'envoi.
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 200Envoi et étapes de suivi.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/transfers/{reference}/cash-pickup/code
Afficher le code de retrait
The detailed descriptions of this sheet are written in French.
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é.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes Référence publique de l'envoi.
X-Linc-Attestationheader string no 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.
Request body Name Type Required Description twoFactorobject no 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 no totp · sms · backup_code
twoFactor.codestring no twoFactor.challengeIdstring (uuid) no
Request example {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Code example 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());
Answer example 200
{
"code": "••••••"
}
Answers and errors Status Meaning 200Code de retrait.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/transfers/{reference}/cash-pickup/sms
Renvoyer le code au bénéficiaire par SMS
The detailed descriptions of this sheet are written in French.
Au plus 3 renvois par envoi (429 cash_pickup_resend_limit au-delà) ; chaque envoi est journalisé.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes Référence publique de l'envoi.
Code example 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());
Answer example 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"
}
}
}
Answers and errors Status Meaning 200SMS parti ou non (sent) et état du retrait.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/transfers/{reference}/cash-pickup/cancel
Annuler un retrait d'espèces
The detailed descriptions of this sheet are written in French.
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é.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes Référence publique de l'envoi.
X-Linc-Attestationheader string no 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.
Request body Name Type Required Description twoFactorobject no 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 no totp · sms · backup_code
twoFactor.codestring no twoFactor.challengeIdstring (uuid) no
Request example {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Code example 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());
Answer example 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"
}
}
Answers and errors Status Meaning 200Issue de l'annulation et envoi à jour.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/transfers/{reference}/cash-pickup/name
Corriger le nom du bénéficiaire d'un retrait
The detailed descriptions of this sheet are written in French.
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).
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes Référence publique de l'envoi.
X-Linc-Attestationheader string no 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.
Request body Name Type Required Description namestring yes Nom complet du bénéficiaire, exactement comme sur sa pièce d'identité.
twoFactorobject yes 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 yes totp · sms · backup_code
twoFactor.codestring yes twoFactor.challengeIdstring (uuid) no
Request example {
"name": "texte",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Code example 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());
Answer example 200
{
"amended": true
}
Answers and errors Status Meaning 200Corrigé ou en attente de la conformité.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/transfers/{reference}/card-checkout
Open the card page of a transfer
The detailed descriptions of this sheet are written in French.
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é.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes Référence publique de l'envoi.
Code example 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());
Answer example 200
{
"reference": "LP-7K2Q4F",
"status": "pending",
"url": "https://example.com",
"expiresAt": "2026-10-01T09:30:00Z"
}
Answers and errors Status Meaning 200Page carte à ouvrir.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/transfers/{reference}/checkout
Ouvrir la page de paiement Interswitch d'un envoi
The detailed descriptions of this sheet are written in French.
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é).
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes Référence publique de l'envoi.
Code example 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());
Answer example 200
{
"url": "https://example.com",
"expiresAt": "2026-10-01T09:30:00Z"
}
Answers and errors Status Meaning 200Page de paiement à ouvrir.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/card-payments/{reference}
Track a card payment
The detailed descriptions of this sheet are written in French.
Issue du paiement par carte d'un envoi ou d'un paiement marchand du client (après la page carte).
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes Référence du paiement par carte.
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 200Paiement par carte.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/saved-cards
List my saved bank cards
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 200Cartes enregistrées (réseau, 4 derniers chiffres, expiration).
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/saved-cards
Add a bank card without paying
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Financial operation: send a unique Idempotency-Key per operation (replayed for 24 h).
Parameters Name In Type Required Description Idempotency-Keyheader string yes 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-Attestationheader string no 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.
Request body Name Type Required Description twoFactorobject no 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 no totp · sms · backup_code
twoFactor.codestring no twoFactor.challengeIdstring (uuid) no
Request example {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Code example 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());
Answer example 201
{
"reference": "LP-7K2Q4F",
"status": "pending",
"url": "https://example.com",
"expiresAt": "2026-10-01T09:30:00Z"
}
Answers and errors Status Meaning 201Page carte à ouvrir (lien à usage unique).
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
PATCH /v1/saved-cards/{id}
Name a saved card or make it the default one
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes Identifiant de la carte enregistrée.
Request body Name Type Required Description nicknamestring no Nom donné à la carte ; vide pour l'effacer.
defaultboolean no
Request example {
"nickname": "texte",
"default": true
}
Code example 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());
Answer example 200
{
"id": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"label": "texte",
"network": "visa",
"last4": "texte",
"expiry": "texte",
"issuerCountry": "KE",
"createdAt": "2026-10-01T09:30:00Z"
}
Answers and errors Status Meaning 200Carte mise à jour.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
DELETE /v1/saved-cards/{id}
Delete a saved bank card
The detailed descriptions of this sheet are written in French.
Le jeton est aussi supprimé chez l'acquéreur.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes Identifiant de la carte enregistrée.
Code example 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());
Answer example 204
Carte supprimée.
Answers and errors Status Meaning 204Carte supprimée.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/saved-wallets
List my saved mobile money wallets
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 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
}
Answers and errors Status Meaning 200Porte-monnaie enregistrés et nombre maximal.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/saved-wallets
Save a mobile money wallet
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description X-Linc-Attestationheader string no 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.
Request body Name Type Required Description msisdnstring yes Numéro mobile money de la RDC, avec ou sans +243.
providerstring no Opérateur ; lu depuis le numéro si absent.
airtel · mpesa · orange · afrimoney
labelstring no Nom du porte-monnaie ; l'opérateur par défaut.
Request example {
"msisdn": "+243810000000"
}
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 201Porte-monnaie enregistré.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
PATCH /v1/saved-wallets/{id}
Rename a wallet or make it the default one
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes
Request body Name Type Required Description labelstring no defaultboolean no
Request example {
"label": "texte",
"default": true
}
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 200Porte-monnaie mis à jour.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
DELETE /v1/saved-wallets/{id}
Delete a saved wallet
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes
Code example 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());
Answer example 204
Porte-monnaie supprimé.
Answers and errors Status Meaning 204Porte-monnaie supprimé.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/saved-wallets/{id}/code
Send the verification code of a wallet again
The detailed descriptions of this sheet are written in French.
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é.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes
Code example 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());
Answer example 200
{
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f"
}
Answers and errors Status Meaning 200Code envoyé.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/saved-wallets/{id}/verify
Verify a wallet with the code received by SMS
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description X-Linc-Attestationheader string no 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.
idpath string yes
Request body Name Type Required Description challengeIdstring (uuid) yes codestring yes Code à 6 chiffres reçu par SMS au numéro du porte-monnaie.
Request example {
"challengeId": "0190f1b4-7c3a-7d2e-9a51-3f2b8c1d4e5f",
"code": "••••••"
}
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 200Porte-monnaie vérifié.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/transfers/{reference}/saved-wallet
Save the number of a completed transfer
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 201Porte-monnaie enregistré, code envoyé.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/me/dashboard
Show the dashboard
The detailed descriptions of this sheet are written in French.
Soldes, actions rapides, envois en cours, favoris, taux, carte, plafond, sécurité, statistiques et dernières opérations.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description X-App-Idheader string no Application mobile appelante.
X-App-Platformheader string no Plateforme de l'application mobile.
X-App-Versionheader string no Version de l'application (par exemple 1.4.2). Sous la version minimale, réponse 426 app_update_required.
Code example 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());
Answer example 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
}
]
}
Answers and errors Status Meaning 200Tableau de bord du client.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/me/history
Show the history
The detailed descriptions of this sheet are written in French.
Historique paginé, filtré par type et par texte (libellé ou référence).
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description pagequery integer no perPagequery integer no typequery string no Filtre. Valeur vide ou inconnue = tout.
qquery string no Texte recherché dans le libellé ou la référence.
Code example 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());
Answer example 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"
]
}
Answers and errors Status Meaning 200Page d'historique.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/receipts/{reference}
Download a receipt
The detailed descriptions of this sheet are written in French.
Reçu PDF d'un envoi (LP-), d'un paiement marchand (TX-), d'un rechargement (TU-) ou d'une opération crypto (CX-).
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes
Code example 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());
Answer example 200
File (PDF or image)
Answers and errors Status Meaning 200Reçu PDF (pièce jointe recu-linc-{reference}.pdf).
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/notifications
List my notifications
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 200
{
"notifications": [
{
"key": "texte",
"title": "texte",
"text": "texte",
"date": "2026-10-01T09:30:00Z",
"reference": "LP-7K2Q4F",
"read": true
}
],
"unread": 0
}
Answers and errors Status Meaning 200Notifications et nombre de non lues.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/notifications/{key}/read
Mark a notification as read
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description keypath string yes Clé de la notification, par exemple transfer:LP-7K2Q9M:delivered.
Code example 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());
Answer example 204
Notification lue.
Answers and errors Status Meaning 204Notification lue.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/notifications/read-all
Mark everything as read
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 200
{
"marked": 0
}
Answers and errors Status Meaning 200Nombre de notifications marquées.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/wallet/top-ups
List my top-ups
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 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"
}
]
}
Answers and errors Status Meaning 200Rechargements du client.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/wallet/top-ups
Top up the balance
The detailed descriptions of this sheet are written in French.
Collecte USSD / STK push sur le mobile money. Le résultat est asynchrone (suivez le statut).
Authentication: Customer token: Authorization: Bearer <access token>
Financial operation: send a unique Idempotency-Key per operation (replayed for 24 h).
Parameters Name In Type Required Description Idempotency-Keyheader string yes 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.
Request body Name Type Required Description providerstring no airtel · mpesa · orange · afrimoney
msisdnstring no Numéro à débiter. Vide = numéro du compte.
amountstring yes currencystring no
Request example {
"amount": "texte"
}
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 202Rechargement lancé.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/wallet/top-ups/{reference}
Track a top-up
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 200Rechargement.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/merchant-payments/resolve
Read a merchant QR code or payment link
The detailed descriptions of this sheet are written in French.
Ce que demande un QR scanné (EMVCo) ou un lien INV-… ouvert, avant de payer.
Authentication: Customer token: Authorization: Bearer <access token>
Request body Name Type Required Description payloadstring yes Contenu du QR EMVCo, lien https://app.linc.cd/pay/INV-… ou référence INV-….
Request example {
"payload": "texte"
}
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 200Marchand, montant et état du paiement demandé.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/merchant-payments
List my merchant payments
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 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"
}
]
}
Answers and errors Status Meaning 200Paiements du client.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/merchant-payments
Pay a merchant
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Financial operation: send a unique Idempotency-Key per operation (replayed for 24 h).
Parameters Name In Type Required Description Idempotency-Keyheader string yes 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-Attestationheader string no 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.
Request body Name Type Required Description referencestring yes amountstring no Obligatoire pour un QR de caisse (USD).
sourceobject no source.typestring no mobile_money · wallet · card
source.providerstring no airtel · mpesa · orange · afrimoney
source.msisdnstring no twoFactorobject no 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 no totp · sms · backup_code
twoFactor.codestring no twoFactor.challengeIdstring (uuid) no
Request example {
"reference": "INV-7K2Q4F",
"source": {
"type": "mobile_money",
"provider": "airtel",
"msisdn": "+243970000000"
},
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 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.
Error as application/problem+json: see “Errors”.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/merchant-payments/{reference}
Show a merchant payment
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes Référence du paiement marchand.
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 200Paiement marchand.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/withdrawal-codes
List my withdrawal codes
The detailed descriptions of this sheet are written in French.
Le code complet n'est jamais renvoyé (code = null).
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 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"
}
]
}
Answers and errors Status Meaning 200Codes de retrait.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/withdrawal-codes
Create a withdrawal code
The detailed descriptions of this sheet are written in French.
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).
Authentication: Customer token: Authorization: Bearer <access token>
Financial operation: send a unique Idempotency-Key per operation (replayed for 24 h).
Parameters Name In Type Required Description Idempotency-Keyheader string yes 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-Attestationheader string no 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.
Request body Name Type Required Description amountstring yes currencystring no twoFactorobject yes 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 yes totp · sms · backup_code
twoFactor.codestring yes twoFactor.challengeIdstring (uuid) no
Request example {
"amount": "texte",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 201Code créé (champ code présent une seule fois).
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/withdrawal-codes/{id}/cancel
Cancel a withdrawal code
The detailed descriptions of this sheet are written in French.
Libère le montant réservé.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes
Code example 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());
Answer example 204
Code annulé.
Answers and errors Status Meaning 204Code annulé.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/cards
List my virtual cards
The detailed descriptions of this sheet are written in French.
Cartes du client et programmes ouverts à la création.
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 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"
}
]
}
Answers and errors Status Meaning 200Cartes et programmes ouverts.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/cards
Create a virtual card
The detailed descriptions of this sheet are written in French.
Mode wallet et KYC niveau 2 requis. Second facteur requis.
Authentication: Customer token: Authorization: Bearer <access token>
Financial operation: send a unique Idempotency-Key per operation (replayed for 24 h).
Parameters Name In Type Required Description Idempotency-Keyheader string yes 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-Attestationheader string no 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.
Request body Name Type Required Description networkstring no visa · mastercard
embossedNamestring no twoFactorobject yes 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 yes totp · sms · backup_code
twoFactor.codestring yes twoFactor.challengeIdstring (uuid) no
Request example {
"network": "visa",
"embossedName": "AMANI K",
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 201Carte créée.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/cards/{id}
Show a card
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes Identifiant de la carte.
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 200Carte.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/cards/{id}/transactions
List the operations of a card
The detailed descriptions of this sheet are written in French.
Paiements, refus et chargements, du plus récent au plus ancien (100 au plus).
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes Identifiant de la carte.
Code example 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());
Answer example 200
{
"transactions": [
{
"kind": "payment",
"label": "texte",
"date": "2026-10-01T09:30:00Z",
"status": "texte",
"detail": "texte",
"amount": {
"amount": 10000,
"currency": "USD",
"display": "texte"
}
}
]
}
Answers and errors Status Meaning 200Opérations de la carte.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/cards/{id}/freeze
Freeze a card
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes Identifiant de la carte.
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 200Carte.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/cards/{id}/unfreeze
Unfreeze a card
The detailed descriptions of this sheet are written in French.
Impossible si la conformité a gelé la carte.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes Identifiant de la carte.
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 200Carte.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/cards/{id}/reveal
Show the card details
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes Identifiant de la carte.
X-Linc-Attestationheader string no 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.
Request body Name Type Required Description twoFactorobject no 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 no totp · sms · backup_code
twoFactor.codestring no twoFactor.challengeIdstring (uuid) no
Request example {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Code example 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());
Answer example 200
{
"issuer": "texte",
"cardReference": "LP-7K2Q4F",
"last4": "texte",
"sdkUrl": "https://example.com",
"expiresAt": "2026-10-01T09:30:00Z"
}
Answers and errors Status Meaning 200Session d'affichage.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/cards/{id}/replace
Replace a card
The detailed descriptions of this sheet are written in French.
Ferme la carte (perdue ou compromise) et en crée une nouvelle. Second facteur requis.
Authentication: Customer token: Authorization: Bearer <access token>
Financial operation: send a unique Idempotency-Key per operation (replayed for 24 h).
Parameters Name In Type Required Description idpath string yes Identifiant de la carte.
Idempotency-Keyheader string yes 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-Attestationheader string no 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.
Request body Name Type Required Description reasonstring no lost · compromised
twoFactorobject yes 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 yes totp · sms · backup_code
twoFactor.codestring yes twoFactor.challengeIdstring (uuid) no
Request example {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 201Nouvelle carte.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/cards/{id}/terminate
Close a card
The detailed descriptions of this sheet are written in French.
Fermeture définitive. Second facteur requis.
Authentication: Customer token: Authorization: Bearer <access token>
Financial operation: send a unique Idempotency-Key per operation (replayed for 24 h).
Parameters Name In Type Required Description idpath string yes Identifiant de la carte.
Idempotency-Keyheader string yes 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-Attestationheader string no 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.
Request body Name Type Required Description twoFactorobject no 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 no totp · sms · backup_code
twoFactor.codestring no twoFactor.challengeIdstring (uuid) no
Request example {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 200Carte fermée.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/cards/{id}/credential-show-session
Open a card display session (mobile SDK)
The detailed descriptions of this sheet are written in French.
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).
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description idpath string yes Identifiant de la carte.
X-App-Platformheader string no Plateforme de l'application mobile.
X-Linc-Attestationheader string no 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.
Request body Name Type Required Description twoFactorobject no 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 no totp · sms · backup_code
twoFactor.codestring no twoFactor.challengeIdstring (uuid) no
Request example {
"twoFactor": {
"method": "totp",
"code": "••••••"
}
}
Code example 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());
Answer example 201
{
"issuer": "texte",
"cardReference": "LP-7K2Q4F",
"last4": "texte",
"platform": "android",
"expiresAt": "2026-10-01T09:30:00Z"
}
Answers and errors Status Meaning 201Session pour le SDK Credential Show de l'émetteur.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/payment-links
Create a payment link
The detailed descriptions of this sheet are written in French.
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.
Authentication: Merchant secret key: Authorization: Bearer sk_test_… (server side only)
Financial operation: send a unique Idempotency-Key per operation (replayed for 24 h).
Parameters Name In Type Required Description Idempotency-Keyheader string yes 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.
Request body Name Type Required Description amountstring yes Montant en décimal (texte), par exemple 42.50.
currencystring no descriptionstring yes Libellé de la facture.
expires_instring no 24h · 7d · 30d
Request example {
"amount": "25.00",
"currency": "USD",
"description": "Commande n° 10452",
"expires_in": "24h"
}
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 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 ».
Error as application/problem+json: see “Errors”.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/payment-links/{id}
Show a payment link
Authentication: Merchant secret key: Authorization: Bearer sk_test_… (server side only)
Parameters Name In Type Required Description idpath string yes Référence de la facture.
Code example 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());
Answer example 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"
}
Answers and errors Status Meaning 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 ».
Error as application/problem+json: see “Errors”.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/tickets/options
List the request types and categories
The detailed descriptions of this sheet are written in French.
Types (réclamation, demande d'information), catégories et contraintes des pièces jointes.
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 200
{
"types": [
{
"code": "complaint",
"label": "texte"
}
],
"categories": [
{
"code": "transfer",
"label": "texte"
}
],
"attachments": {
"types": [
"texte"
],
"maxBytes": 0
}
}
Answers and errors Status Meaning 200Options du formulaire de demande.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/tickets
List my requests
Authentication: Customer token: Authorization: Bearer <access token>
Code example 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());
Answer example 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"
}
]
}
Answers and errors Status Meaning 200Demandes du client, de la plus récente à la plus ancienne.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/tickets
Open a request
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Financial operation: send a unique Idempotency-Key per operation (replayed for 24 h).
Parameters Name In Type Required Description Idempotency-Keyheader string yes 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.
Request body Name Type Required Description typestring yes complaint : réclamation ; information : demande d'information.
complaint · information
categorystring yes transfer · merchant_payment · top_up · withdrawal_agent · card · kyc · account_security · fraud · technical · other
subjectstring yes descriptionstring yes linkedReferencestring no LP-…, INV-…, TX-…, TU-…, AG-…, QR-…, CL-…, RG-… ou CARD-1234 (4 derniers chiffres).
Request example {
"type": "complaint",
"category": "transfer",
"subject": "texte",
"description": "texte"
}
Code example 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());
Answer example 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"
]
}
Answers and errors Status Meaning 201Demande ouverte.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/tickets/{reference}
Show a request
The detailed descriptions of this sheet are written in French.
Fil des échanges, pièces jointes et actions possibles. Erreur 404 ticket_not_found.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes Référence publique de la demande.
Code example 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());
Answer example 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"
]
}
Answers and errors Status Meaning 200Demande.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/tickets/{reference}/messages
Reply to a request
The detailed descriptions of this sheet are written in French.
Ajoute un message au fil. Erreur 404 ticket_not_found, 409 ticket_closed si la demande est clôturée.
Authentication: Customer token: Authorization: Bearer <access token>
Financial operation: send a unique Idempotency-Key per operation (replayed for 24 h).
Parameters Name In Type Required Description referencepath string yes Référence publique de la demande.
Idempotency-Keyheader string yes 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.
Request body Name Type Required Description bodystring yes
Request example {
"body": "texte"
}
Code example 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());
Answer example 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"
]
}
Answers and errors Status Meaning 201Demande mise à jour.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/tickets/{reference}/attachments
Attach a file to a request
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes Référence publique de la demande.
Request body File sent as multipart/form-data.
Name Type Required Description filestring yes Fichier (PDF, JPEG ou PNG, 10 Mo maximum).
Code example 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());
Answer example 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"
]
}
Answers and errors Status Meaning 201Demande mise à jour.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/tickets/{reference}/attachments/{id}/link
Get the download link of an attachment
The detailed descriptions of this sheet are written in French.
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é.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes Référence publique de la demande.
idpath string yes Identifiant de la pièce jointe.
Code example 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());
Answer example 200
{
"url": "https://example.com",
"expiresAt": "2026-10-01T09:30:00Z"
}
Answers and errors Status Meaning 200Lien de téléchargement signé.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
GET /v1/tickets/{reference}/attachments/{id}
Download an attachment
The detailed descriptions of this sheet are written in French.
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.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes Référence publique de la demande.
idpath string yes Identifiant de la pièce jointe.
viewerquery string yes Utilisateur auquel le lien est lié (fourni par le lien signé).
_expiresquery string yes Expiration du lien (fournie par le lien signé).
_signaturequery string yes Signature du lien.
Code example 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());
Answer example 200
File (PDF or image)
Answers and errors Status Meaning 200Contenu de la pièce jointe (téléchargement, jamais mis en cache).
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/tickets/{reference}/reopen
Reopen a request
The detailed descriptions of this sheet are written in French.
Possible pendant un délai après la résolution (reopenUntil). Erreur 409 ticket_not_reopenable.
Authentication: Customer token: Authorization: Bearer <access token>
Financial operation: send a unique Idempotency-Key per operation (replayed for 24 h).
Parameters Name In Type Required Description referencepath string yes Référence publique de la demande.
Idempotency-Keyheader string yes 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.
Code example 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());
Answer example 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"
]
}
Answers and errors Status Meaning 200Demande.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.
POST /v1/tickets/{reference}/satisfaction
Rate the handling of a request
The detailed descriptions of this sheet are written in French.
Une seule note par demande résolue ou clôturée. Erreurs 409 ticket_already_rated, 422 validation_failed.
Authentication: Customer token: Authorization: Bearer <access token>
Parameters Name In Type Required Description referencepath string yes Référence publique de la demande.
Request body Name Type Required Description scoreinteger yes commentstring no
Request example {
"score": 0
}
Code example 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());
Answer example 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"
]
}
Answers and errors Status Meaning 200Demande.
Any other error Erreur (RFC 9457).
Error as application/problem+json: see “Errors”.