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.
- Listez ce que vous pouvez échanger. Utilisez l’
idde chaque devise dans les autres appels.curl "https://swapnoir.com/api/v1/currencies" - 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" - 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"
Requêtes et données
| URL de base | https://swapnoir.com/api/v1. HTTPS uniquement. |
|---|---|
| Méthodes | Tous les endpoints sont en GET. Les paramètres se placent dans la chaîne de requête ou dans le chemin. |
| Réponses | application/json, UTF-8. Les erreurs utilisent application/problem+json. |
| Montants | Des 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 devises | Devise et réseau, par exemple BTC, USDT-TRC20. Insensible à la casse dans les requêtes ; toujours en majuscules dans les réponses. |
| Dates et heures | ISO 8601 en UTC, par exemple 2026-10-05T12:00:00.000Z. |
| Navigateurs | CORS 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 versions | La 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.
| Endpoint | Requêtes par minute |
|---|---|
GET /currencies | 60 |
GET /estimate | 90 |
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
/currenciesen 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
finalvauttrue.
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.
{
"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"
}| Code | HTTP | Signification |
|---|---|---|
invalid_parameter | 400 | Un paramètre de requête est manquant ou mal formé. param indique lequel. |
same_currency | 400 | from et to correspondent à la même devise. |
receive_not_supported | 400 | La devise to est disponible uniquement à l’envoi (Lightning). |
amount_too_small | 422 | Le montant est inférieur au minimum pour cette paire. min_amount contient le minimum. |
pair_not_supported | 422 | Cette paire de devises et de réseaux n’est pas proposée. |
pair_unavailable | 503 | Aucun taux n’est disponible pour cette paire pour le moment. Réessayez plus tard ou essayez un autre montant. |
not_found | 404 | Aucune commande ne correspond à ce numéro, ou la commande a été supprimée. |
rate_limited | 429 | Vous avez atteint la limite de requêtes. Attendez le nombre de secondes indiqué dans Retry-After. |
internal_error | 500 | Un 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
{
"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
| Champ | Type | Description |
|---|---|---|
id | string | Devise et réseau. |
ticker | string | |
name | string | |
network | string | |
decimals | integer | Nombre maximal de décimales accepté dans les montants. |
send | boolean | Utilisable comme from. |
receive | boolean | Utilisable comme to. |
memo | string or null | Nom du champ supplémentaire que certains réseaux exigent avec l’adresse, comme Destination tag ; null s’il n’est pas utilisé. |
icon_url | string |
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
| Nom | Emplacement | Description |
|---|---|---|
fromobligatoire | query | Devise envoyée par l’utilisateur. Exemple : BTC. |
toobligatoire | query | Devise reçue par l’utilisateur. BTC-LN est disponible uniquement à l’envoi. Exemple : XMR. |
amountobligatoire | query | Montant de from, en nombre décimal avec un point et au plus le nombre de décimales decimals de la devise. Exemple : 0.01. |
rate | query | float (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
{
"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"
}{
"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"
}{
"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
| Champ | Type | Description |
|---|---|---|
from | string | Devise et réseau. |
to | string | Toute devise, sauf celles disponibles uniquement à l’envoi. |
rate_type | string | Type de taux |
amount_from | string | Le montant sur lequel porte la requête. |
amount_to | string | Ce que reçoit l’utilisateur, après déduction de tous les frais. |
rate | string | Montant de to pour 1 from, frais déduits. |
usd_value | string or null | Valeur approximative de amount_from en dollars américains, si elle est connue. |
quoted_at | string |
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
| Nom | Emplacement | Description |
|---|---|---|
idobligatoire | path | Numé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
{
"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"
}
}{
"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
| Champ | Type | Description |
|---|---|---|
id | string | Numéro de commande |
status | string | Statut de la commande |
final | boolean | Vaut true pour done, expired, refunded et failed : arrêtez d’interroger l’API. |
rate_type | string | Type de taux |
created_at | string | |
updated_at | string | |
from | object | |
from.currency | string | Devise et réseau. |
from.amount | string | Montant à déposer. |
to | object | |
to.currency | string | Devise et réseau. |
to.amount | string or null | Versement estimé, ou versement final dès que amount_is_final vaut true. |
to.amount_is_final | boolean | |
deposit | object | |
deposit.address | string or null | Adresse à laquelle l’utilisateur envoie le dépôt ; null tant que le statut est preparing. |
deposit.memo | string or null | Mémo ou tag de destination à inclure avec le dépôt, s’il est défini. |
deposit.expires_at | string or null | Envoyer avant cette heure, si elle est définie. |
payout | object | |
payout.address | string | |
payout.memo | string or null | |
refund | null or object | |
refund.address | string | |
refund.memo | string or null | |
transactions | object | |
transactions.deposit | null or object | |
transactions.deposit.hash | string | |
transactions.deposit.url | string or null | Lien vers un explorateur de blocs, s’il est connu. |
transactions.payout | null or object | |
transactions.payout.hash | string | |
transactions.payout.url | string or null | Lien vers un explorateur de blocs, s’il est connu. |
links | object | |
links.order_page | string | |
links.receipt | string |
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 :
| Lien | Page ouverte |
|---|---|
https://swapnoir.com/exchange?from=BTC&to=XMR&amount=0.01&rate=float | L’é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.01 | La 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>- 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.
- L’utilisateur arrive sur sa page de commande,
https://swapnoir.com/order/<ID>, où figurent l’adresse de dépôt et le montant. - 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.
| Statut | Final | Signification |
|---|---|---|
preparing | Non | L’adresse de dépôt est en cours de préparation. Elle apparaît généralement en quelques minutes. |
awaiting | Non | En attente du dépôt. N’envoyez que tant que la commande a ce statut et avant deposit.expires_at. |
confirming | Non | Le dépôt a été détecté et attend les confirmations du réseau. |
exchanging | Non | Le dépôt est confirmé et en cours d’échange. |
sending | Non | Les cryptos échangées sont en cours d’envoi vers l’adresse de réception. |
processing | Non | En cours. Utilisé lorsqu’aucun statut plus précis n’est connu. |
done | Oui | Terminé. Le versement a été envoyé ; voir transactions.payout. |
expired | Oui | Aucun dépôt n’est arrivé à temps. Un dépôt tardif peut encore être échangé ou remboursé via le support. |
hold | Non | Mis en pause pour une vérification de routine. L’utilisateur doit contacter le support en indiquant le numéro de commande. |
attention | Non | Un point doit être vérifié, par exemple un dépôt d’un montant incorrect. L’utilisateur doit contacter le support. |
refunding | Non | Le dépôt est en cours de renvoi vers l’adresse de remboursement. |
refunded | Oui | Le dépôt a été renvoyé. |
failed | Oui | L’é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.
| ID | Devise | Réseau | Décimales | Réception | Mémo |
|---|---|---|---|---|---|
BTC | Bitcoin | 8 | Oui | – | |
XMR | Monero | 12 | Oui | – | |
ETH | Ethereum | 8 | Oui | – | |
USDT-TRC20 | Tron (TRC20) | 6 | Oui | – | |
USDT-ERC20 | Ethereum (ERC20) | 6 | Oui | – | |
USDT-SOL | Solana | 6 | Oui | – | |
USDC-ERC20 | Ethereum (ERC20) | 6 | Oui | – | |
LTC | Litecoin | 8 | Oui | – | |
SOL | Solana | 9 | Oui | – | |
BTC-LN | Lightning | 8 | Envoi uniquement | – | |
TRX | Tron | 6 | Oui | – | |
BNB | BNB Smart Chain (BEP20) | 8 | Oui | – | |
DOGE | Dogecoin | 8 | Oui | – | |
ZEC | Zcash | 8 | Oui | – | |
BCH | Bitcoin Cash | 8 | Oui | – | |
DASH | Dash | 8 | Oui | – | |
XRP | XRP Ledger | 6 | Oui | Tag de destination |
Liste de contrôle pour l’intégration
- 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.
- Affichez le mémoLorsque
deposit.memoest défini, le dépôt doit l’inclure. Affichez-le aussi clairement que l’adresse. - Expliquez le taux fixeUn échange à taux fixe ne verse le montant annoncé que si l’utilisateur envoie exactement
from.amountavantdeposit.expires_at. - 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.
- Gérez les erreurs par codeBasez votre logique sur
code, affichezdetailet respectezRetry-After. - 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êtesRateLimitet 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 : .