Documentation

Construisez avecCryptocardium.

Émettez des cartes, alimentez des comptes, déclenchez des transactions et suivez leur cycle de vie — depuis cURL, depuis n'importe quel SDK, depuis votre agent IA. L'ensemble de la plateforme repose sur une API REST stable et un serveur MCP natif.

Bienvenue

Cryptocardium est un programme de cartes sans KYC financé en cryptomonnaies. Chaque action réalisable dans le panneau — ouverture de compte, recharge, émission de carte, chargement, dépense, suivi des transactions — est accessible via la même API REST et le même serveur MCP.

Cette documentation couvre tout : les conventions (comment l'API communique), les ressources (ce que vous pouvez demander), les événements (comment rester synchronisé) et les intégrations (Claude, ChatGPT, Cursor, tout agent).

Les clés API sont générées dans le panneau.

Inscrivez-vous sur /account, ouvrez API Settings, cliquez sur "New key". Le texte en clair complet s'affiche une seule fois — copiez-le dans un gestionnaire de secrets.

Démarrage rapide

De zéro à une carte virtuelle active en trois appels. Le shell ci-dessous utilise cURL ; remplacez-le par n'importe quel client HTTP.

1. Authentification

Placez votre clé API dans l'en-tête Authorization. Chaque endpoint l'exige.

export CCM_KEY="ccm_live_a1b2c3d4..."

2. Alimenter le trésor

Créez une adresse de dépôt USDT. Envoyez les fonds ; nous créditons à la confirmation.

curl https://api.cryptocardium.com/v1/topups \
  -H "Authorization: Bearer $CCM_KEY" \
  -H "Idempotency-Key: top_$(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "amount_usd": 500, "asset": "USDT", "chain": "tron" }'

3. Émettre une carte & dépenser

Choisissez un BIN (Visa Platinum pour les portefeuilles, Visa Business pour les publicités), chargez-le et vous êtes opérationnel.

curl https://api.cryptocardium.com/v1/cards \
  -H "Authorization: Bearer $CCM_KEY" \
  -d '{
    "type": "virtual",
    "bin": "489517",
    "load_usd": 300,
    "wallet_provision": ["apple_pay", "google_pay"]
  }'

# → 201 Created · card is live, balance loaded, wallet-ready
C'est tout.

Quarante-sept secondes en médiane, de l'inscription à la première authentification. Les sections suivantes couvrent tout le reste — gestion des erreurs, idempotence, webhooks, configuration des agents — dont vous aurez besoin en production.

Authentification

Trois types d'identifiants, selon la nature de l'intégration :

TypeFormatUtilisation
Bearer de sessionsess_…Scripts interactifs, tests, le panneau lui-même.
Clé APIccm_live_…Serveurs de production, CI, tâches planifiées, durée illimitée.
OAuth 2.1 + DCReyJh… (JWT)Agents s'enregistrant eux-mêmes à l'exécution, grants à portée limitée.

En-tête Bearer

Les trois passent par le même en-tête :

Authorization: Bearer ccm_live_a1b2c3d4...

Générer une clé API

Les clés sont générées uniquement dans le panneau. Nous n'acceptons jamais une demande de création de clé via l'API sans session authentifiée rattachée à la session du panneau elle-même.

  1. Connectez-vous à votre compte.
  2. Ouvrez API Settings.
  3. Cliquez sur New key, donnez-lui un nom reconnaissable, enregistrez le texte en clair (affiché une seule fois).
  4. Stockez-le dans un gestionnaire de secrets. Ajoutez-le à votre environnement sous CCM_KEY.
Traitez les clés comme des mots de passe.

Une clé ccm_live_ compromise confère des permissions au niveau du compte. Effectuez une rotation via /api-settings en cas de suspicion d'exposition — la révocation est instantanée.

Tests & sandbox

Actuellement, les recharges inférieures à 200 $ sont acceptées comme réelles mais routées vers un processeur de carte sandbox, vous permettant d'intégrer sans engager de vrai règlement. Les comptes de production disposent de bascules sandbox par clé.

  • Recharge 200 $+ → rails de production, règlement réel.
  • Recharge <200 $ → rails sandbox, autorisations simulées.
  • Les cartes émises depuis des recharges sandbox portent "mode": "sandbox".

URL de base & versionnage

URL de base en production :

https://api.cryptocardium.com/v1

Le préfixe v1 fait partie du chemin. v1 est LTS-forever — aucune modification incompatible ne sera jamais publiée sous ce préfixe. Les changements additifs (nouveaux champs optionnels, nouveaux endpoints) sont déployés de façon transparente.

Les modifications incompatibles passeront sous un nouveau préfixe (v2) avec au moins six mois de chevauchement. Les dépréciations sont annoncées via webhook (system.deprecation) et le journal des modifications.

Requêtes

Toutes les requêtes sont en HTTPS uniquement (TLS 1.3). Les corps de requête sont en JSON ; les objets imbriqués sont pris en charge nativement. Les corps encodés en formulaire ne sont pas pris en charge.

  • Content-Type : application/json pour les endpoints d'écriture.
  • <strong>Charset</strong> : UTF-8 systématiquement.
  • Méthodes HTTP : GET (lecture), POST (création / action), PATCH (mise à jour partielle), DELETE (suppression).
  • Limites des en-têtes : 8 Ko au total, 4 Ko par valeur.
  • Limite du corps : 25 Mo (100 Mo pour les pièces justificatives de litige).
  • Délais d'expiration : 30 s connexion, 60 s lecture. Les opérations longues sont asynchrones.

Réponses

Chaque réponse est en JSON. Les réponses de succès retournent 200/201/204 avec le corps de la ressource. Les erreurs retournent un objet d'erreur structuré — voir Erreurs.

Enveloppe standard

{
  "id": "card_8f3a91b7c4d2",
  "object": "card",
  "created_at": "2026-05-19T07:30:00Z",
  "updated_at": "2026-05-19T07:30:00Z",
  ...
}

Horodatages

Tous les horodatages sont en ISO 8601 UTC, formatés en YYYY-MM-DDTHH:MM:SSZ. L'API ne connaît pas d'autres fuseaux horaires.

Valeurs monétaires

Tous les montants sont des décimaux équivalents USD dans les champs amount_usd. Précision à deux décimales. Adossés à USDT en interne.

Pagination

Les endpoints de liste (/topups, /cards, /transactions, …) utilisent une pagination par curseur. Pas d'offset, pas de LIMIT SQL.

GET /v1/transactions?limit=50&cursor=tx_8f3a91b7c4d2
  • limit — taille de page, défaut 25, max 100.
  • cursor — transmettez le next_cursor de la réponse précédente.
  • La pagination suit le tri naturel de chaque ressource (généralement <code>created_at</code> décroissant).
{
  "object": "list",
  "data": [ /* 50 items */ ],
  "has_more": true,
  "next_cursor": "tx_2bea88..."
}

Filtrage & tri

Chaque endpoint de liste prend en charge le filtrage sur ses champs principaux via des paramètres de requête :

GET /v1/transactions
  ?card_id=card_8f3a91b7c4d2
  &status=captured
  &created_after=2026-05-01T00:00:00Z
  &sort=-amount_usd

Le paramètre sort accepte un seul champ ; préfixez avec - pour un ordre décroissant. Consultez la référence des endpoints de chaque ressource pour les clés de filtre prises en charge.

Idempotence

Chaque requête d'écriture (POST, PATCH, DELETE) accepte un en-tête Idempotency-Key. Passez une valeur unique par opération logique. Les nouvelles tentatives avec la même clé retournent la réponse originale.

POST /v1/cards
Idempotency-Key: card_create_b9f1a4...
Authorization: Bearer ccm_live_...
  • Les clés sont stockées pendant 24 heures. Après ce délai, la même clé peut être réutilisée pour une nouvelle opération.
  • Format recommandé : <operation>_<uuid-v4>.
  • Même clé + corps différent → 409 Conflict avec conflict_idempotency_key.
  • Les requêtes GET sont toujours idempotentes et n'ont pas besoin (ni n'acceptent) de cet en-tête.

Limites de débit

Par clé API :

FenêtreLimiteRemarques
Burst 1 s60 reqPics courts tolérés.
1 min1 000 reqPlafond soutenu.
1 jour50 000 reqAgrégat par clé.

Chaque réponse comporte :

X-RateLimit-Limit:     1000
X-RateLimit-Remaining: 943
X-RateLimit-Reset:     1718999999

Lorsque vous dépassez la limite, vous recevrez un 429 Too Many Requests avec un en-tête Retry-After en secondes. Respectez-le ; nous appliquons un backoff exponentiel aux contrevenants.

Erreurs

Chaque réponse d'erreur utilise la même structure :

{
  "object": "error",
  "type": "invalid_request_error",
  "code": "missing_required_field",
  "message": "Field 'bin' is required.",
  "param": "bin",
  "request_id": "req_a9f4b1..."
}

Correspondance des statuts HTTP

StatutTypeSignification
400invalid_request_errorPayload malformé, champs manquants.
401authentication_errorBearer absent ou invalide.
403permission_errorBearer valide, action non autorisée (ex. : seuil de solde).
404not_found_errorLa ressource n'existe pas (ou ne vous appartient pas).
409conflict_errorConflit d'état (ex. : clé d'idempotence réutilisée).
419session_expiredSession du panneau expirée. Ré-authentifiez-vous.
422validation_errorJSON valide, règle métier non respectée.
429rate_limit_errorRalentissez. Retry-After en secondes.
500api_errorErreur de notre côté. Nous avons déjà été alertés.
503service_unavailableÉmetteur upstream indisponible. Nouvelle tentative automatique recommandée.

Journalisez toujours le request_id. Les tickets de support y font directement référence.

Comptes

Le compte est votre ressource racine. Tout le reste (recharges, cartes, transactions) appartient à un compte.

Créer

POST /v1/accounts
{
  "email": "[email protected]",
  "password": "long-random-string"
}

Retourne immédiatement un Bearer de session. Pas de KYC, pas de téléversement de document, pas de vérification d'adresse e-mail requis pour commencer à utiliser l'API.

Récupérer le compte actuel

GET /v1/accounts/me
{
  "id": "acc_8f3a91b7c4d2",
  "email": "[email protected]",
  "balance_usd": 487.20,
  "twofa_enabled": true,
  "created_at": "2026-05-18T20:14:00Z"
}

Solde & trésor

Le solde du compte est le pool USDT disponible à la dépense. Les recharges le créditent ; les chargements de carte et les retraits le débitent.

GET /v1/balance
{
  "object": "balance",
  "available_usd": 487.20,
  "pending_usd": 200.00,
  "updated_at": "2026-05-19T07:30:00Z"
}

pending_usd couvre les recharges en cours (non encore confirmées) et les chargements de carte en vol.

Recharges

Une recharge est l'étape asymétrique où vous engagez des cryptos on-chain et nous créditons de l'USDT après finalisation.

Créer

POST /v1/topups
{
  "amount_usd": 500,
  "asset": "USDT",
  "chain": "tron"
}

Retourne une adresse de dépôt, une URI QR et une expiration (60 min par défaut). Envoyez le montant exact à l'adresse ; nous créditons à la confirmation.

{
  "id": "top_4e21a99c7b",
  "status": "pending",
  "amount_usd": 500,
  "deposit_address": "T9zFR...kQp",
  "qr_data_uri": "data:image/png;base64,...",
  "expires_at": "2026-05-19T08:30:00Z"
}

Cycle de vie du statut

StatutSignification
pendingEn attente de dépôt on-chain.
completedFonds crédités sur le solde.
expiredFenêtre d'adresse fermée. Les dépôts tardifs sont toujours auto-crédités.
cancelledVous avez appelé POST /v1/topups/:id/cancel.
errorRèglement échoué (rare). Remboursement automatique.

Préférez le webhook topup.confirmed au polling — il se déclenche une seule fois et vous évite 30+ sondages.

Cartes

Les cartes existent en deux types — virtuelles (actives en quelques secondes) et physiques (livrées en 5–9 jours, réservées au BIN Visa Gold).

Émettre

POST /v1/cards
{
  "type": "virtual",
  "bin": "489517",
  "load_usd": 300,
  "wallet_provision": ["apple_pay", "google_pay"]
}

Catalogue BIN

BINNomIdéal pourType
416842Visa BusinessDépenses publicitaires (3-D Secure)Virtuelle
557213Mastercard WorldMulti-devises, premiumVirtuelle
489517Visa PlatinumApple & Google PayVirtuelle
472305Visa CorporateAbonnements SaaSVirtuelle
448585Visa GoldPhysique uniquement (3-D Secure)Physique

Révéler le PAN complet + CVV

Le numéro de carte complet, le CVV et la date d'expiration ne sont retournés que lors d'un appel dédié et audité :

GET /v1/cards/:id/pan
{
  "pan": "4895 1712 ●●●● 4218",
  "cvv": "347",
  "expires_at": "2029-08",
  "audit_id": "audit_8c2e3f..."
}

Chaque révélation est consignée dans la piste d'audit. Les agents doivent révéler une seule fois par achat, ne jamais stocker et effacer de la mémoire après usage.

Opérations

  • POST /v1/cards/:id/freeze — bloquer les autorisations.
  • POST /v1/cards/:id/unfreeze — reprendre.
  • POST /v1/cards/:id/load — ajouter de l'USDT à la carte.
  • POST /v1/cards/:id/unload — rapatrier le solde non dépensé vers le trésor.
  • POST /v1/cards/:id/cancel — résiliation définitive.
  • PATCH /v1/cards/:id/limits — plafonds de transaction / mensuels par carte.
  • PATCH /v1/cards/:id/mcc — listes d'autorisation/refus MCC.
  • PATCH /v1/cards/:id/geo — listes d'autorisation par pays.

Chargements & soldes de carte

Le solde de la carte est libellé en USDT équivalent USD. Un chargement débite le trésor, applique les 2 % de frais de rail et crédite la carte.

POST /v1/cards/:id/load
{ "amount_usd": 200 }
{
  "card_id": "card_8f3a91b7c4d2",
  "loaded_usd": 200.00,
  "rail_fee_usd": 4.00,
  "new_card_balance_usd": 200.00,
  "new_treasury_balance_usd": 283.20
}

Les chargements sont atomiques — l'appel ne retourne qu'une fois les fonds transférés.

Transactions

Chaque autorisation, capture, remboursement et refus est un objet transaction. Ils sont en ajout seul et immuables.

GET /v1/cards/:id/transactions?status=captured&limit=50
{
  "object": "list",
  "data": [
    {
      "id": "tx_b1c2d3",
      "object": "transaction",
      "card_id": "card_8f3a91b7c4d2",
      "status": "captured",
      "amount_usd": 42.95,
      "merchant": { "name": "OpenAI", "mcc": "7372" },
      "auth_response_code": "00",
      "created_at": "2026-05-19T03:14:00Z"
    }
  ],
  "has_more": false
}

Filtrez sur status, card_id, mcc, merchant_name, created_after, created_before, amount_min, amount_max.

Retraits

Renvoyez l'USDT du trésor vers n'importe quel portefeuille externe que vous contrôlez.

POST /v1/withdrawals
{
  "amount_usd": 100,
  "chain": "tron",
  "address": "T9zFR...kQp"
}

Min 10 $, max votre solde total. Chaînes prises en charge : tron (la moins chère), ethereum, bsc. Les envois inter-réseaux sont irrécupérables — vérifiez toujours l'adresse.

Litiges

Déposez un chargeback sur n'importe quelle transaction :

POST /v1/disputes
{
  "transaction_id": "tx_b1c2d3",
  "reason": "duplicate",
  "description": "Merchant charged twice on 2026-05-19, same order #4921."
}

Codes de motif : duplicate, not_received, fraud, not_as_described, cancelled_subscription, other.

Joignez des preuves (reçus, captures d'écran, correspondances) via POST /v1/disputes/:id/evidence. Nous déposons auprès de l'émetteur en votre nom — sans frais supplémentaires.

Webhooks · abonnement

Les webhooks transmettent les événements à votre endpoint HTTPS au fil de leur survenue. Évitez le polling ; utilisez les webhooks.

POST /v1/webhooks
{
  "url": "https://yourapp.example.com/webhooks/cryptocardium",
  "events": [
    "topup.confirmed",
    "card.issued",
    "transaction.captured",
    "transaction.declined"
  ],
  "description": "Production sync"
}

La réponse contient un signing_secret — conservez-le ; vous en aurez besoin pour vérifier les payloads. Abonnez-vous à "*" pour recevoir tous les événements.

Webhooks · vérification de signature

Chaque webhook porte une signature HMAC-SHA256 dans l'en-tête Cryptocardium-Signature :

Cryptocardium-Signature: t=1718999999,v1=4a8b2f0e6c9d...
Cryptocardium-Event-Id:  evt_a1b2c3d4
Cryptocardium-Delivery:  dlv_8f3a91...

Calculez la signature attendue sur "{t}.{rawBody}" avec votre signing_secret. Comparez à l'aide d'une fonction à temps constant.

Node.js

import crypto from 'crypto';

export function verify(rawBody, sigHeader, secret) {
  const [t, v1] = sigHeader.split(',')
    .map(s => s.split('=')[1]);
  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${t}.${rawBody}`)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(v1), Buffer.from(expected)
  );
}

Python

import hmac, hashlib

def verify(raw_body: bytes, sig_header: str, secret: str) -> bool:
    parts = dict(p.split('=') for p in sig_header.split(','))
    t, v1 = parts['t'], parts['v1']
    expected = hmac.new(
        secret.encode(),
        f"{t}.{raw_body.decode()}".encode(),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(v1, expected)

PHP

function verify($rawBody, $sigHeader, $secret): bool {
    $parts = [];
    foreach (explode(',', $sigHeader) as $p) {
        [$k, $v] = explode('=', $p, 2);
        $parts[$k] = $v;
    }
    $expected = hash_hmac('sha256',
        "{$parts['t']}.{$rawBody}", $secret);
    return hash_equals($expected, $parts['v1']);
}

Webhooks · relances & relectures

Livraison au moins une fois. Nous effectuons des relances sur toute réponse non-2xx ou timeout (10 s).

TentativeDélai
1immédiat
230 s
35 min
430 min
52 h
612 h
724 h (finale)

Relisez n'importe quel événement depuis le tableau de bord ou via POST /v1/webhooks/:id/replay/:event_id. Utilisez l'en-tête Cryptocardium-Event-Id pour la déduplication de votre côté.

Catalogue d'événements

Account account.created account.signed_in account.signed_out account.password_changed account.totp_enabled account.totp_disabled
Top-ups topup.created topup.confirmed topup.expired topup.cancelled topup.error
Cards card.issued card.loaded card.unloaded card.frozen card.unfrozen card.cancelled card.replaced
Tx transaction.authorized transaction.captured transaction.refunded transaction.declined transaction.reversed
Dispute dispute.opened dispute.responded dispute.won dispute.lost
Withdraw withdrawal.created withdrawal.broadcasted withdrawal.confirmed withdrawal.failed
System system.maintenance system.deprecation

Serveur MCP

Nous hébergeons un serveur Model Context Protocol sur https://mcp.cryptocardium.com/v1. Il expose 40+ outils mappant 1:1 les endpoints REST, avec des noms adaptés aux agents (create_topup, issue_card, reveal_pan, etc.).

Transport : HTTP streamable. Auth : OAuth 2.1 avec Dynamic Client Registration — les agents s'enregistrent eux-mêmes à la première connexion, sans qu'aucune clé API ne soit à coller dans leur configuration.

MCP · configuration client

Claude Desktop / Claude Code

// ~/.config/claude/claude_desktop_config.json
{
  "mcpServers": {
    "cryptocardium": {
      "url": "https://mcp.cryptocardium.com/v1",
      "transport": "http"
    }
  }
}

Cursor / Continue / mcp-cli

# Adds the server, kicks off OAuth DCR on first connect
mcp-cli add cryptocardium \
  --url https://mcp.cryptocardium.com/v1 \
  --auth oauth

Après autorisation dans votre navigateur, l'agent a accès à chaque outil du catalogue (ou uniquement ceux que vous avez accordés, si vous avez restreint la portée).

MCP · catalogue d'outils

Les outils reflètent les endpoints REST. Un petit échantillon (la liste complète est sur /api) :

Compte create_account sign_in get_account enable_2fa
Trésor get_balance create_topup withdraw
Cartes issue_card load_card reveal_pan freeze_card set_card_limits
Tx & journaux list_transactions get_activity file_dispute

MCP · OAuth 2.1 + DCR

Les agents s'enregistrent dynamiquement via RFC 7591. Flux :

  1. L'agent effectue un POST /oauth/register — reçoit client_id & client_secret.
  2. L'utilisateur est invité à autoriser dans le navigateur (une seule fois).
  3. L'agent reçoit un access_token (à portée limitée, à durée limitée).
  4. Les requêtes suivantes portent le bearer JWT.

Périmètres par outil

Limitez un agent à la lecture seule, à une carte spécifique ou à un sous-ensemble d'outils en passant scope= lors de l'enregistrement. Exemples :

scope=read           # list & get only, no writes
scope=cards:write    # manage cards but not withdraw
scope=card:card_8f3a91b7c4d2  # single card

SDK & exemples

Les SDK officiels arrivent prochainement. En attendant, l'API présente une surface REST plate — tout client HTTP moderne le prend en charge.

Node.js (fetch)

const res = await fetch('https://api.cryptocardium.com/v1/cards', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.CCM_KEY}`,
    'Idempotency-Key': `card_${crypto.randomUUID()}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    type: 'virtual', bin: '489517', load_usd: 300
  })
});
const card = await res.json();

Python (requests)

import requests, os, uuid

r = requests.post(
    'https://api.cryptocardium.com/v1/cards',
    headers={
        'Authorization': f"Bearer {os.environ['CCM_KEY']}",
        'Idempotency-Key': f"card_{uuid.uuid4()}",
    },
    json={'type': 'virtual', 'bin': '489517', 'load_usd': 300}
)
card = r.json()

PHP (curl)

$ch = curl_init('https://api.cryptocardium.com/v1/cards');
curl_setopt_array($ch, [
    CURLOPT_POST => 1,
    CURLOPT_RETURNTRANSFER => 1,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $_ENV['CCM_KEY'],
        'Idempotency-Key: card_' . bin2hex(random_bytes(16)),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'type' => 'virtual',
        'bin' => '489517',
        'load_usd' => 300,
    ]),
]);
$card = json_decode(curl_exec($ch), true);

Journal des modifications

Les modifications additives sont déployées de façon transparente. Les changements non rétrocompatibles sont placés sous un nouveau préfixe de version.

  • 2026-05-19 · v1.4 Ajout

    POST /v1/cards/:id/load & /unload sont désormais atomiques. Événement webhook card.loaded ajouté.

  • 2026-05-18 · v1.3 Ajout

    Serveur MCP disponible sur mcp.cryptocardium.com. OAuth 2.1 DCR. Plus de 40 outils mappés depuis REST.

  • 2026-05-17 · v1.2 Ajout

    Programme de carte Gold physique (BIN 448585), 3-D Secure sur Visa Business et Visa Gold.

  • 2026-05-15 · v1.1 Modification

    Rechargement minimum abaissé à 20 $ pour le routage sandbox, 200 $ pour les rails de production.

  • 2026-05-12 · v1.0 Publication

    v1 LTS. Plus de 50 endpoints. Authentification Bearer + clés d'idempotence + webhooks HMAC.

Support

Bloqué ? Deux options :

  • Consultez le centre d'aide FAQ — plus de 30 questions-réponses, avec recherche.
  • Ouvrez un ticket de support — réservé aux titulaires de carte actifs, réponse sous 24 h.

Incluez le request_id de la réponse en échec — cela accélère la résolution par un facteur 10.

FAQ

Questions développeurs.

Everything people actually ask. Last updated .

Où se trouve la spécification OpenAPI ?

OpenAPI 3.1 est disponible à https://cryptocardium.com/openapi.json (JSON) et /openapi.yaml. Lien depuis la page d'accueil via rel="service-desc".

Comment les requêtes sont-elles authentifiées ?

Trois options : (1) Bearer de session après connexion, (2) clé API Bearer créée sur /api-settings, (3) token d'accès OAuth 2.1 (recommandé pour les agents IA, prend en charge le Dynamic Client Registration). Les trois sont envoyés dans l'en-tête Authorization.

Quelle est la limite de débit ?

600 requêtes par minute par clé API, avec un burst de 100 requêtes. Les en-têtes X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset sont retournés sur chaque réponse. Plafonds supérieurs disponibles sur demande via /contact.

Comment fonctionne l'idempotence ?

Passez un en-tête Idempotency-Key (tout UUID ou chaîne aléatoire de 32 octets) sur les requêtes POST et PATCH. Les nouvelles tentatives identiques dans les 24 heures retournent la réponse mise en cache. Des payloads différents avec la même clé retournent une erreur 409 Conflict.

Comment les erreurs sont-elles retournées ?

Chaque réponse non-2xx est { "error": "machine_readable_code", "message": "Lisible par l'humain", "request_id": "req_..." }. Le code d'erreur est l'identifiant canonique lisible par machine ; adaptez votre logique cliente à celui-ci, pas au message.

Existe-t-il des SDK clients ?

Des exemples de code en cURL, JavaScript (Node + Fetch) et Python sont intégrés dans la documentation. Les SDK officiels sont publiés via l'organisation GitHub ; les SDK communautaires sont référencés depuis /api.

Existe-t-il un environnement sandbox ?

Oui. Utilisez une clé API de test depuis /api-settings (préfixée sk_test_). Tous les endpoints sont répliqués ; les cartes émises en sandbox ne passent pas sur les rails réels.