Fiatside

Developpeurs

Coter une operation

La cotation est le seul endpoint ouvert aujourd’hui, et le plus important : c’est lui qui rend la decomposition ligne a ligne que le site affiche. Il ne demande aucune cle.

POST/api/quoteOuvert

Coter une operation

Rend la decomposition complete d’une vente : le taux mid-market utilise, chaque prelevement sur sa ligne, le net et le taux effectif reellement obtenu. La somme des lignes egale exactement l’ecart entre le brut et le net — l’invariant est verifie avant que la reponse parte, et une reponse desequilibree n’est jamais rendue.

Authentification : aucune aujourd’hui. L’endpoint de cotation est ouvert : une cotation ne revele aucune donnee personnelle.

Parametres

Parametres
ChampTypeDescription
assetIdrequisstringIdentifiant de l’actif depose, par exemple « btc », « usdt », « sol ».
railIdrequisstringIdentifiant du moyen de paiement de reception, par exemple « sepa_instant », « br_pix », « ke_mpesa ».
networkIdstringReseau de depot. Facultatif : le premier reseau de l’actif est pris par defaut. Le cout reseau varie fortement d’un reseau a l’autre, ce champ change donc le montant net.
directionrequis"sell" | "receive"Sens de la saisie. « sell » : le montant est ce que vous deposez. « receive » : le montant est ce que vous voulez recevoir, et le depot requis est resolu par recherche binaire.
amountrequisstringMontant en unite majeure, transmis en CHAINE. Un nombre flottant JSON perdrait des unites mineures sur les grands montants : la chaine est le seul format sur lequel client et serveur sont d’accord au centime pres.
Requetebash
curl -sS -X POST https://fiatside.com/api/quote \
  -H 'Content-Type: application/json' \
  -d '{
    "assetId": "usdt",
    "railId": "sepa_instant",
    "networkId": "tron",
    "direction": "sell",
    "amount": "1000"
  }'
Reponse — exemple reeljson
{
  "deposit": { "amount": "1000.000000", "ticker": "USDT", "decimals": 6 },
  "gross": "921.68",
  "net": "912.28",
  "currency": "EUR",
  "currencyDecimals": 2,
  "midRate": "0.92168430",
  "effectiveRate": "0.91228000",
  "totalCostBps": 102,
  "lines": [
    { "code": "network", "amount": "1.11", "basis": "Cout reseau tron, preleve en USDT" },
    { "code": "spread",  "amount": "8.29", "basis": "0.90 % du montant converti" }
  ],
  "settlement": { "p50Minutes": 1, "p95Minutes": 12 },
  "lockSeconds": 1800,
  "rateAsOf": 1788356981608,
  "rateSource": "mock",
  "limitError": null
}
  • La reponse porte l’en-tete Cache-Control: no-store. Une cotation mise en cache est un prix perime servi comme un prix ferme.
  • Un depassement de limite du rail n’est pas une erreur HTTP : la cotation est rendue avec un objet limitError qui contient le code below_min ou above_max et la limite exacte, pour que votre interface puisse afficher le bon message sans second appel.
  • rateSource indique la source du prix. La valeur « mock » designe la source deterministe de developpement : elle ne peut pas demarrer en production, ou le processus refuse de se lancer plutot que de coter des prix figes.

Erreurs possibles : invalid_request, unknown_asset_or_rail, rail_not_open, asset_not_offered, invalid_amount, rate_stale, rate_unavailable, quote_failed. Catalogue complet

01

Lire la decomposition

Le tableau lines contient une entree par prelevement reel. Une ligne a zero n’est pas rendue : afficher « frais de rail : 0,00 » n’apporte rien et alourdit l’interface.

Lire la decomposition
codeA qui elle revientCe que c’est
networkAu reseau blockchainCout de mouvement de l’actif, preleve en nature sur le depot avant conversion. Il varie selon le reseau choisi, parfois d’un facteur important : c’est la raison pour laquelle networkId change le montant net.
spreadA nousNotre marge, exprimee en pourcentage du montant converti. C’est la seule ligne qui constitue notre revenu.
railA l’etablissement de paiementFrais du moyen de paiement, fixe, proportionnel ou les deux. Absent quand le rail ne facture rien, ce qui est le cas de la majorite des rails ouverts.
fxAu changeLigne reservee a un ecart de change explicite lorsqu’une conversion supplementaire intervient. Elle n’apparait pas sur les corridors ou la devise du rail est celle de la cotation.

L’invariant qui rend le tableau verifiable

brut moins la somme des lignes egale exactement le net, a l’unite mineure pres. Cette egalite est verifiee a chaque cotation avant que la reponse parte ; si elle ne tombe pas juste, il existe une marge non declaree quelque part, et le moteur leve une erreur plutot que de la rendre. Vous pouvez refaire l’addition : c’est le but.

02

Un exemple avec frais de rail

Le meme montant vers un rail qui facture ses envois fait apparaitre la troisieme ligne. Reponse reelle, obtenue sur la source de developpement deterministe.

Requetebash
curl -sS -X POST https://fiatside.com/api/quote \
  -H 'Content-Type: application/json' \
  -d '{
    "assetId": "usdt",
    "railId": "ke_mpesa",
    "networkId": "tron",
    "direction": "sell",
    "amount": "1000"
  }'
Reponse — exemple reeljson
{
  "gross": "129525.90",
  "net": "128141.44",
  "currency": "KES",
  "totalCostBps": 107,
  "lines": [
    { "code": "network", "amount": "155.44", "basis": "Cout reseau tron, preleve en USDT" },
    { "code": "spread",  "amount": "582.17", "basis": "0.45 % du montant converti" },
    { "code": "rail",    "amount": "646.85", "basis": "0.50 % du montant converti" }
  ],
  "settlement": { "p50Minutes": 2, "p95Minutes": 45 },
  "limitError": null
}

Trois lignes, trois destinataires differents : le reseau, nous, l’etablissement de paiement. Le champ totalCostBps donne l’ecart total au taux mid-market en points de base — c’est le seul chiffre a comparer d’un service a l’autre, parce qu’il englobe tout, y compris ce qui serait cache dans un taux.

03

Limites du rail

Un montant hors des bornes du rail ne produit pas une erreur HTTP : la cotation est rendue, avec un objet limitError. Votre interface peut donc afficher le montant ET la raison exacte, sans second appel.

Extrait de reponse — exemple reeljson
{
  "net": "3.47",
  "currency": "EUR",
  "limitError": { "code": "below_min", "limit": "20.00" }
}

Les valeurs possibles sont below_min et above_max, et limit contient la borne en unite majeure de la devise du rail. Attention : la borne s’applique au montant NET, pas au montant depose — c’est ce que recoit le beneficiaire qui doit tenir dans les limites du rail.

04

Duree de validite

Le champ lockSeconds indique combien de temps le taux sera fige a la creation de la commande. Il depend de l’actif : plus long sur un stablecoin, plus court sur un actif volatil.

  • La cotation elle-meme n’est pas ferme : elle est indicative tant qu’aucune commande n’est creee. Le taux se verrouille a la creation de la commande, pas a l’appel de cotation.
  • La fenetre couvre votre decision, pas le temps de confirmation du reseau. Un depot bitcoin peut demander une heure de confirmations : le verrouillage protege du mouvement de marche pendant que vous decidez et deposez.
  • Si le depot arrive apres expiration, la commande est recotee et le nouveau montant doit etre accepte. Aucun reprix silencieux en defaveur du client n’est possible par construction.
  • Ne mettez pas en cache une cotation pour combler une erreur de taux perime. Une cotation en cache est un prix perime presente comme ferme, ce qui est exactement le probleme que le code de refus evite.