Swapnoir
FR

API publique · v1 · Gratuite

API Swapnoir

Taux de change en direct, devises prises en charge et suivi des commandes pour votre portefeuille, votre bot ou votre site web. Lecture seule, sans clé API, sans compte.

URL de base
https://swapnoir.com/api/v1
Authentification
Aucune
Format
JSON, UTF-8
Erreurs
RFC 9457

Vue d’ensemble

L’API Swapnoir fournit à votre application les mêmes données en direct que celles utilisées par la plateforme d’échange swapnoir.com. C’est une petite API REST en HTTPS avec trois endpoints ; elle renvoie du JSON et est décrite dans un fichier OpenAPI 3.1 que vous pouvez charger dans Postman, Insomnia, Scalar ou un générateur de code.

Affichez les taux en direct

Widgets de prix, calculateurs et bots. Les estimations incluent déjà tous les frais du versement.

Envoyez vos utilisateurs vers un échange

Ouvrez un échange prérempli sur swapnoir.com depuis votre application, avec un simple lien.

Suivez les commandes

Suivez un échange grâce à son numéro de commande et prévenez vos utilisateurs lorsqu’il est terminé.

Démarrage rapide

Aucune inscription requise. Exécutez ces commandes dans un terminal ; chacune fonctionne de façon indépendante.

  1. Listez ce que vous pouvez échanger. Utilisez l’id de chaque devise dans les autres appels.
    curl "https://swapnoir.com/api/v1/currencies"
  2. Obtenez une estimation en direct. Combien de XMR obtient-on pour 0.01 BTC, frais déduits ?
    curl "https://swapnoir.com/api/v1/estimate?from=BTC&to=XMR&amount=0.01"
  3. Envoyez votre utilisateur vers l’échange et suivez-le. L’utilisateur termine sur swapnoir.com et obtient une page de commande. Le numéro de cette commande vous permet de la suivre.
    curl "https://swapnoir.com/api/v1/orders/K7M2QX9PRT4B"

Essayer en direct

GET /api/v1/estimate?from=BTC&to=XMR&amount=0.01&rate=float

Requêtes et données

URL de basehttps://swapnoir.com/api/v1. HTTPS uniquement.
MéthodesTous les endpoints sont en GET. Les paramètres se placent dans la chaîne de requête ou dans le chemin.
Réponsesapplication/json, UTF-8. Les erreurs utilisent application/problem+json.
MontantsDes chaînes décimales telles que "0.01", pour ne perdre aucune précision. Envoyez les montants avec un point et au plus le nombre de décimales decimals de la devise.
ID des devisesDevise et réseau, par exemple BTC, USDT-TRC20. Insensible à la casse dans les requêtes ; toujours en majuscules dans les réponses.
Dates et heuresISO 8601 en UTC, par exemple 2026-10-05T12:00:00.000Z.
NavigateursCORS est ouvert (Access-Control-Allow-Origin: *) : vous pouvez donc appeler l’API depuis une page web. Aucun cookie n’est utilisé.
TorÉgalement disponible via Tor à l’adresse http://swapnoqyyp3mfh3hoypzmvpnau7gymt7c32tybx2qew3s7sw7bzz7aqd.onion/api/v1, avec les mêmes endpoints et les mêmes limites.
Gestion des versionsLa version figure dans le chemin. Au sein de la v1, nous ne faisons qu’ajouter des éléments : nouveaux endpoints, nouveaux paramètres facultatifs, nouveaux champs de réponse et nouvelles devises ; ignorez donc les champs que vous ne connaissez pas. Tout changement susceptible de casser une intégration est publié dans une nouvelle version, et la v1 continue de fonctionner en parallèle.

Authentification

Aucune. Il n’y a ni clé API, ni compte, ni jeton, et les requêtes ne sont associées à personne. N’envoyez jamais d’identifiants, de phrases de récupération ou de clés privées à l’API ; elle ne vous les demandera jamais.

Limites de requêtes

Les limites sont calculées par connexion sur une minute glissante.

EndpointRequêtes par minute
GET /currencies60
GET /estimate90
GET /orders/{id}30

Chaque réponse inclut les en-têtes standard RateLimit-Policy (par exemple 90;w=60) et RateLimit (par exemple limit=90, remaining=89, reset=60). Au-delà de la limite, vous recevez une réponse 429 avec un en-tête Retry-After exprimé en secondes.

  • Mettez /currencies en cache pendant au moins 5 minutes ; la liste change rarement.
  • Pendant qu’un utilisateur saisit un montant, attendez environ une demi-seconde après la dernière frappe avant de demander une estimation.
  • Interrogez une commande au plus toutes les 10 secondes, et arrêtez lorsque final vaut true.

Erreurs

Les erreurs suivent le format standard RFC 9457 « problem details ». Vérifiez le statut HTTP, puis basez votre logique sur code, qui ne change jamais. detail est un message en anglais simple que vous pouvez afficher à votre utilisateur, et type renvoie vers la ligne correspondante ci-dessous.

422 Exemple
{
  "type": "https://swapnoir.com/api#error-amount_too_small",
  "title": "Amount below minimum",
  "status": 422,
  "detail": "The minimum for this pair is 0.00005799 BTC.",
  "code": "amount_too_small",
  "min_amount": "0.00005799"
}
CodeHTTPSignification
invalid_parameter400Un paramètre de requête est manquant ou mal formé. param indique lequel.
same_currency400from et to correspondent à la même devise.
receive_not_supported400La devise to est disponible uniquement à l’envoi (Lightning).
amount_too_small422Le montant est inférieur au minimum pour cette paire. min_amount contient le minimum.
pair_not_supported422Cette paire de devises et de réseaux n’est pas proposée.
pair_unavailable503Aucun taux n’est disponible pour cette paire pour le moment. Réessayez plus tard ou essayez un autre montant.
not_found404Aucune commande ne correspond à ce numéro, ou la commande a été supprimée.
rate_limited429Vous avez atteint la limite de requêtes. Attendez le nombre de secondes indiqué dans Retry-After.
internal_error500Un problème est survenu de notre côté. Réessayez plus tard.

Référence

Lister les devises

GET/api/v1/currencies

Toutes les devises et tous les réseaux pris en charge par Swapnoir. Un jeton sur un autre réseau est une devise distincte, par exemple USDT-TRC20 et USDT-ERC20. La liste change rarement ; mettez-la en cache quelques minutes.

L’exemple montre trois des devises. Les champs de réponse ci-dessous s’appliquent à chaque devise.

Requête

curl "https://swapnoir.com/api/v1/currencies"
const res = await fetch("https://swapnoir.com/api/v1/currencies");
const { currencies } = await res.json();

// Currencies a user can receive
const receivable = currencies.filter((c) => c.receive);
import requests

r = requests.get("https://swapnoir.com/api/v1/currencies", timeout=10)
r.raise_for_status()
currencies = r.json()["currencies"]

Réponse

200 OK
{
  "currencies": [
    {
      "id": "BTC",
      "ticker": "BTC",
      "name": "Bitcoin",
      "network": "Bitcoin",
      "decimals": 8,
      "send": true,
      "receive": true,
      "memo": null,
      "icon_url": "https://swapnoir.com/assets/coins/btc.svg"
    },
    {
      "id": "BTC-LN",
      "ticker": "BTC",
      "name": "Bitcoin",
      "network": "Lightning",
      "decimals": 8,
      "send": true,
      "receive": false,
      "memo": null,
      "icon_url": "https://swapnoir.com/assets/coins/btc.svg"
    },
    {
      "id": "XRP",
      "ticker": "XRP",
      "name": "XRP",
      "network": "XRP Ledger",
      "decimals": 6,
      "send": true,
      "receive": true,
      "memo": "Destination tag",
      "icon_url": "https://swapnoir.com/assets/coins/xrp.svg"
    }
  ]
}
Champs de la réponse
ChampTypeDescription
idstringDevise et réseau.
tickerstring
namestring
networkstring
decimalsintegerNombre maximal de décimales accepté dans les montants.
sendbooleanUtilisable comme from.
receivebooleanUtilisable comme to.
memostring or nullNom du champ supplémentaire que certains réseaux exigent avec l’adresse, comme Destination tag ; null s’il n’est pas utilisé.
icon_urlstring

Obtenir une estimation

GET/api/v1/estimate

Montant de to que l’utilisateur reçoit pour amount de from, tous frais d’échange et de réseau du versement déjà inclus. Les estimations sont en direct et ne sont pas réservées : le montant final est fixé à la création de l’échange (taux fixe) ou à la confirmation du dépôt (taux variable).

Paramètres

NomEmplacementDescription
fromobligatoirequeryDevise envoyée par l’utilisateur. Exemple : BTC.
toobligatoirequeryDevise reçue par l’utilisateur. BTC-LN est disponible uniquement à l’envoi. Exemple : XMR.
amountobligatoirequeryMontant de from, en nombre décimal avec un point et au plus le nombre de décimales decimals de la devise. Exemple : 0.01.
ratequeryfloat (par défaut) suit le marché jusqu’à la confirmation du dépôt. fixed bloque le montant à la création de l’échange. Valeurs possibles : float, fixed. Exemple : float.

Requête

curl "https://swapnoir.com/api/v1/estimate?from=BTC&to=XMR&amount=0.01&rate=float"
const params = new URLSearchParams({ from: "BTC", to: "XMR", amount: "0.01" });
const res = await fetch(`https://swapnoir.com/api/v1/estimate?${params}`);
const data = await res.json();

if (!res.ok) {
  // RFC 9457 problem, e.g. data.code === "amount_too_small"
  throw new Error(data.detail);
}
console.log(data.amount_to, data.to);
import requests

r = requests.get(
    "https://swapnoir.com/api/v1/estimate",
    params={"from": "BTC", "to": "XMR", "amount": "0.01"},
    timeout=10,
)
data = r.json()
if not r.ok:
    raise RuntimeError(data["code"] + ": " + data["detail"])
print(data["amount_to"], data["to"])

Réponse

200 OK
{
  "from": "BTC",
  "to": "XMR",
  "rate_type": "float",
  "amount_from": "0.01",
  "amount_to": "1.57166029",
  "rate": "157.166029",
  "usd_value": "866.32",
  "quoted_at": "2026-10-05T12:00:00.000Z"
}
422 Sous le minimum
{
  "type": "https://swapnoir.com/api#error-amount_too_small",
  "title": "Amount below minimum",
  "status": 422,
  "detail": "The minimum for this pair is 0.00005799 BTC.",
  "code": "amount_too_small",
  "min_amount": "0.00005799"
}
400 Paramètre invalide
{
  "type": "https://swapnoir.com/api#error-invalid_parameter",
  "title": "Invalid parameter",
  "status": 400,
  "detail": "Unknown currency `DOG`. See /api/v1/currencies.",
  "code": "invalid_parameter",
  "param": "from"
}
Champs de la réponse
ChampTypeDescription
fromstringDevise et réseau.
tostringToute devise, sauf celles disponibles uniquement à l’envoi.
rate_typestringType de taux
amount_fromstringLe montant sur lequel porte la requête.
amount_tostringCe que reçoit l’utilisateur, après déduction de tous les frais.
ratestringMontant de to pour 1 from, frais déduits.
usd_valuestring or nullValeur approximative de amount_from en dollars américains, si elle est connue.
quoted_atstring

Obtenir une commande

GET/api/v1/orders/{id}

Statut en direct et détails d’un échange. Le numéro de commande est la dernière partie de l’URL de la page de commande. Toute personne disposant de ce numéro peut voir la commande : traitez-le comme un mot de passe. Interrogez l’API au plus toutes les 10 secondes et arrêtez dès que final vaut true. Les commandes sont supprimées 7 jours après leur clôture.

Paramètres

NomEmplacementDescription
idobligatoirepathNuméro de commande, par exemple K7M2QX9PRT4B.

Requête

curl "https://swapnoir.com/api/v1/orders/K7M2QX9PRT4B"
const res = await fetch(`https://swapnoir.com/api/v1/orders/${orderId}`);
if (res.status === 404) {
  // wrong ID, or the order was deleted
}
const order = await res.json();
console.log(order.status, order.final);
import time
import requests

while True:
    r = requests.get(f"https://swapnoir.com/api/v1/orders/{order_id}", timeout=10)
    if r.status_code == 404:
        break  # wrong ID, or the order was deleted
    order = r.json()
    print(order["status"])
    if order["final"]:
        break
    time.sleep(15)

Réponse

200 OK
{
  "id": "K7M2QX9PRT4B",
  "status": "confirming",
  "final": false,
  "rate_type": "float",
  "created_at": "2026-10-05T12:00:00.000Z",
  "updated_at": "2026-10-05T12:06:12.000Z",
  "from": {
    "currency": "BTC",
    "amount": "0.01"
  },
  "to": {
    "currency": "XMR",
    "amount": "1.57166029",
    "amount_is_final": false
  },
  "deposit": {
    "address": "bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq",
    "memo": null,
    "expires_at": null
  },
  "payout": {
    "address": "888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H",
    "memo": null
  },
  "refund": null,
  "transactions": {
    "deposit": {
      "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
      "url": "https://mempool.space/tx/e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    },
    "payout": null
  },
  "links": {
    "order_page": "https://swapnoir.com/order/K7M2QX9PRT4B",
    "receipt": "https://swapnoir.com/order/K7M2QX9PRT4B/receipt.txt"
  }
}
404 Introuvable
{
  "type": "https://swapnoir.com/api#error-not_found",
  "title": "Not found",
  "status": 404,
  "detail": "No order with this ID. Orders are deleted 7 days after they finish.",
  "code": "not_found"
}
Champs de la réponse
ChampTypeDescription
idstringNuméro de commande
statusstringStatut de la commande
finalbooleanVaut true pour done, expired, refunded et failed : arrêtez d’interroger l’API.
rate_typestringType de taux
created_atstring
updated_atstring
fromobject
from.currencystringDevise et réseau.
from.amountstringMontant à déposer.
toobject
to.currencystringDevise et réseau.
to.amountstring or nullVersement estimé, ou versement final dès que amount_is_final vaut true.
to.amount_is_finalboolean
depositobject
deposit.addressstring or nullAdresse à laquelle l’utilisateur envoie le dépôt ; null tant que le statut est preparing.
deposit.memostring or nullMémo ou tag de destination à inclure avec le dépôt, s’il est défini.
deposit.expires_atstring or nullEnvoyer avant cette heure, si elle est définie.
payoutobject
payout.addressstring
payout.memostring or null
refundnull or object
refund.addressstring
refund.memostring or null
transactionsobject
transactions.depositnull or object
transactions.deposit.hashstring
transactions.deposit.urlstring or nullLien vers un explorateur de blocs, s’il est connu.
transactions.payoutnull or object
transactions.payout.hashstring
transactions.payout.urlstring or nullLien vers un explorateur de blocs, s’il est connu.
linksobject
links.order_pagestring
links.receiptstring

Guides

Créer un échange

Les échanges sont créés sur swapnoir.com : votre utilisateur obtient ainsi toujours sa propre page de commande et en garde le contrôle. Votre application l’y envoie avec les cryptos et le montant déjà renseignés :

LienPage ouverte
https://swapnoir.com/exchange?from=BTC&to=XMR&amount=0.01&rate=floatL’échange à l’étape de l’adresse, avec l’estimation en direct affichée. Idéal pour les boutons « Échanger maintenant ».
https://swapnoir.com/?from=BTC&to=XMR&amount=0.01La page d’accueil avec le formulaire d’échange prérempli : l’utilisateur peut encore modifier les cryptos et le montant.

Les deux acceptent les mêmes paramètres from, to, amount et rate (facultatif) que l’endpoint Obtenir une estimation. Pour ouvrir la page dans une autre langue, placez d’abord le code de langue, par exemple /de/exchange?….

<a href="https://swapnoir.com/exchange?from=BTC&to=XMR&amount=0.01&rate=float" rel="noopener">
  Exchange BTC to XMR on Swapnoir
</a>
  1. L’utilisateur colle son adresse de réception et, s’il le souhaite, une adresse de remboursement, passe une rapide vérification de sécurité, puis appuie sur Échanger maintenant.
  2. L’utilisateur arrive sur sa page de commande, https://swapnoir.com/order/<ID>, où figurent l’adresse de dépôt et le montant.
  3. Si votre application doit suivre la commande, demandez à l’utilisateur de coller le lien ou le numéro de commande, puis interrogez régulièrement l’endpoint Obtenir une commande.

Statuts de commande

Un échange normal passe par awaiting → confirming → exchanging → sending → done. Affichez status à votre utilisateur avec vos propres mots et arrêtez d’interroger l’API dès que final vaut true.

StatutFinalSignification
preparingNonL’adresse de dépôt est en cours de préparation. Elle apparaît généralement en quelques minutes.
awaitingNonEn attente du dépôt. N’envoyez que tant que la commande a ce statut et avant deposit.expires_at.
confirmingNonLe dépôt a été détecté et attend les confirmations du réseau.
exchangingNonLe dépôt est confirmé et en cours d’échange.
sendingNonLes cryptos échangées sont en cours d’envoi vers l’adresse de réception.
processingNonEn cours. Utilisé lorsqu’aucun statut plus précis n’est connu.
doneOuiTerminé. Le versement a été envoyé ; voir transactions.payout.
expiredOuiAucun dépôt n’est arrivé à temps. Un dépôt tardif peut encore être échangé ou remboursé via le support.
holdNonMis en pause pour une vérification de routine. L’utilisateur doit contacter le support en indiquant le numéro de commande.
attentionNonUn point doit être vérifié, par exemple un dépôt d’un montant incorrect. L’utilisateur doit contacter le support.
refundingNonLe dépôt est en cours de renvoi vers l’adresse de remboursement.
refundedOuiLe dépôt a été renvoyé.
failedOuiL’échange n’a pas pu être finalisé. L’utilisateur doit contacter le support.

Devises prises en charge

La même liste que celle renvoyée par Lister les devises. De nouvelles devises sont ajoutées au fil du temps : lisez donc la liste depuis l’API au lieu de la coder en dur.

IDDeviseRéseauDécimalesRéceptionMémo
BTCBitcoinBitcoin8Oui–
XMRMoneroMonero12Oui–
ETHEthereumEthereum8Oui–
USDT-TRC20TetherTron (TRC20)6Oui–
USDT-ERC20TetherEthereum (ERC20)6Oui–
USDT-SOLTetherSolana6Oui–
USDC-ERC20USD CoinEthereum (ERC20)6Oui–
LTCLitecoinLitecoin8Oui–
SOLSolanaSolana9Oui–
BTC-LNBitcoin LightningLightning8Envoi uniquement–
TRXTronTron6Oui–
BNBBNBBNB Smart Chain (BEP20)8Oui–
DOGEDogecoinDogecoin8Oui–
ZECZcashZcash8Oui–
BCHBitcoin CashBitcoin Cash8Oui–
DASHDashDash8Oui–
XRPXRPXRP Ledger6OuiTag de destination

Liste de contrôle pour l’intégration

  1. Affichez le réseauAffichez toujours le réseau à côté de la crypto, par ex. USDT sur Tron. Un envoi sur le mauvais réseau peut entraîner la perte des fonds.
  2. Affichez le mémoLorsque deposit.memo est défini, le dépôt doit l’inclure. Affichez-le aussi clairement que l’adresse.
  3. Expliquez le taux fixeUn échange à taux fixe ne verse le montant annoncé que si l’utilisateur envoie exactement from.amount avant deposit.expires_at.
  4. Gardez les numéros de commande privésToute personne disposant d’un numéro de commande peut voir la commande correspondante. Ne mettez pas ces numéros dans vos outils de mesure d’audience, vos journaux ou des URL publiques.
  5. Gérez les erreurs par codeBasez votre logique sur code, affichez detail et respectez Retry-After.
  6. Renvoyez vers le vrai siteNe renvoyez que vers https://swapnoir.com. Ne demandez jamais aux utilisateurs leur phrase de récupération ou leurs clés privées.

Journal des modifications

  • Publication de la v1. GET /currencies, GET /estimate, GET /orders/{id}, erreurs RFC 9457, en-têtes RateLimit et description OpenAPI 3.1.

Support

Questions, idées ou besoin de limites plus élevées pour votre intégration : envoyez-nous un message ou écrivez-nous à info@swapnoir.com. L’utilisation de l’API est régie par nos pages Conditions et Confidentialité.

Dernière mise à jour : .