Fiatside

Developers

API documentation

An API that returns the same fee breakdown as the site, line by line, with no hidden margin. This page describes the conventions shared by every endpoint, and states precisely what is open today.

What is open today

1 endpoint is actually exposed and callable: quoting. The other 5 are published as a contract, so you can build before they open, and each carries an explicit badge.

We document ahead because it helps an integration. Letting you believe it is wired would not: every endpoint states its status, and sample responses for open endpoints are responses actually obtained, not mock-ups.

01

Base URL and versioning

Two bases coexist: the one answering today, and the versioned API that will come with issued keys.

Today
/api Live
Versioned API
/api/v1 Published contract, not open

The version lives in the path, not in a header: a URL has to survive being pasted into a ticket. A breaking change — a removed field, a changed type, different semantics — opens a new version; the previous one stays served for at least six months, with its end date announced in the changelog. Adding a field is not breaking: your client must ignore fields it does not know.

02

Conventions

They hold on every endpoint, open or upcoming. Most of them exist for one reason: never lose a cent in transit.

Amounts are strings, or integers of minor units

Never a float. In JSON, 0.1 + 0.2 is not 0.3, and a large amount loses minor units on serialisation. Major-unit amounts are therefore sent as strings, and internal amounts as integers of minor units with their decimal count.

{
  "net": "912.28",
  "currency": "EUR",
  "currencyDecimals": 2
}

Decimals depend on the currency

The euro has two decimals, the CFA franc and the Vietnamese dong have none. Do not hardcode “× 100”: read currencyDecimals, or the decimals field from the reference data.

{ "amount": "125000", "currency": "XOF", "currencyDecimals": 0 }

Crypto amounts are in base units

The deposit is returned with its decimal count: 8 for bitcoin, 6 for USDT, 18 for ether. The same ticker can exist with different decimals depending on the network: trust the field, not your memory.

{ "deposit": { "amount": "1000.000000", "ticker": "USDT", "decimals": 6 } }

Timestamps

Dates are ISO 8601 UTC. One deliberate exception: rateAsOf is a Unix timestamp in milliseconds, because it feeds an age computation, not a display. It carries the date of the market DATA, not of your request: that distinction is what makes a stale price detectable.

{ "rateAsOf": 1788356981608, "rateSource": "coingecko" }

Identifiers are stable

An asset, rail or country identifier never changes and is never reassigned. A closed rail keeps its own, with its phase and reason: your integration can see why it left your options, instead of finding a hole.

Human-facing messages are bilingual

A refusal reason is returned in French and English in the same object. You show the one matching your user, with no translation table to maintain on your side.

{ "reason": { "fr": "…", "en": "…" } }
03

First call

No key is needed to quote. This call works as-is.

Requestbash
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"
  }'
Response — real examplejson
{
  "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
}

The rateSource field states where the price came from. The value “mock” is the deterministic development source, which cannot boot in production: the process refuses to start rather than quote frozen prices.

04

Sections

05

What the API will not do

The limits of an API are as useful to know as its capabilities.

  • No third-party payouts. The beneficiary name must match the verified identity of the order holder, and payment rails now check name against account.
  • No account creation or identity verification through the API. Those steps happen in a flow where the user sees what they accept.
  • No key in a URL parameter. URLs end up in logs, referrer headers and histories: a key passed that way is a key to revoke.
  • No caching of a quote on our side. The response carries Cache-Control: no-store, and your integration should not work around it: a cached quote is a stale price presented as firm.
  • No crypto purchase endpoint. The service runs one way, digital asset to legal tender.