Fiatside

Developers

Reference data and pagination

The rail, asset and country catalogues are the same source that feeds the site. They carry limits, delays, fees and field schemas — enough to generate your payout form instead of coding it country by country.

Refresh frequency

This data changes rarely, but it does change: a rail cap, a cut-off, a country opening. Refresh it at least daily, and do not freeze it into your code. Each entry carries a last manual verification date: past six months, treat it as due for a check.

01

Pagination

Cursor pagination, not numeric offsets. An offset skips or duplicates items as soon as the list moves between two pages; a cursor points at a stable position.

Requesthttp
GET /api/v1/rails?limit=50&cursor=cJ0xNzg4MzU2OTgx
Responsejson
{
  "data": [ /* … */ ],
  "next_cursor": "cJ0xNzg4MzU3MTEy"
}
  • limit defaults to 50, maximum 100. A larger value is clamped to the maximum rather than rejected.
  • next_cursor is null on the last page. It is the only end signal: do not infer the end from a short page.
  • A cursor is opaque with no guaranteed lifetime. Do not store it as a durable identifier, and do not build one yourself.
  • Ordering is stable within one pagination run. An item added while you are paging appears on your next full run, not in the middle of the current one.
GET/api/v1/railsPublished contract, not open

List payout methods

Payout rail catalogue with currency, countries served, p50 and p95 delays, business-day rules, cut-off, per-operation limits in minor units, fees and the beneficiary field schema. That schema is what lets you generate the payout form instead of coding it country by country.

Authentication: Authorization: Bearer … See authentication

Parameters

Parameters
FieldTypeDescription
countrystringISO 3166-1 alpha-2 filter.
currencystringISO 4217 filter.
phasestringlive, beta, planned or never.
limitintegerPage size, 1 to 100, default 50.
cursorstringOpaque cursor returned by the previous call.
Requestbash
curl -sS 'https://fiatside.com/api/v1/rails?country=BR' \
  -H 'Authorization: Bearer sk_live_...'
Response — published contractjson
{
  "data": [
    {
      "id": "br_pix",
      "slug": "pix",
      "name": "PIX",
      "kind": "instant_bank",
      "currency": "BRL",
      "countries": ["BR"],
      "phase": "live",
      "settlement": { "p50Minutes": 1, "p95Minutes": 10, "businessDaysOnly": false },
      "limits": { "minMinor": 1000, "maxMinor": 5000000, "decimals": 2 },
      "fees": { "fixedMinor": 0, "bps": 0 },
      "fields": [
        { "name": "pixKeyType", "type": "select", "required": true },
        { "name": "pixKey", "type": "text", "required": true, "maxLength": 77 },
        { "name": "taxId", "type": "text", "required": true, "pattern": "^[0-9]{11}$" }
      ],
      "verifiedAt": "2026-09-02"
    }
  ],
  "next_cursor": null
}
  • A closed rail is returned with its phase and reason, not removed from the list. An integration that cannot see why a rail vanished asks its own support.

Possible errors: unauthorized, invalid_request. Full catalogue

GET/api/v1/assetsPublished contract, not open

List accepted assets

Assets accepted for deposit, with base-unit decimals, networks, minimum deposit, rate lock duration and, where relevant, the reason an asset is not offered.

Authentication: Authorization: Bearer … See authentication

Parameters

Parameters
FieldTypeDescription
networkstringOnly returns assets available on that network.
Requestbash
curl -sS 'https://fiatside.com/api/v1/assets?network=tron' \
  -H 'Authorization: Bearer sk_live_...'
Response — published contractjson
{
  "data": [
    {
      "id": "usdt",
      "ticker": "USDT",
      "name": "Tether",
      "decimals": 6,
      "networks": ["tron", "ethereum", "bsc", "solana", "polygon", "arbitrum"],
      "stablecoin": true,
      "quoteLockSeconds": 1800,
      "minDepositBase": "20000000",
      "phase": "live"
    }
  ],
  "next_cursor": null
}
  • minDepositBase is expressed in BASE units (20000000 = 20 USDT at 6 decimals). Below that threshold the network cost eats most of the operation.

Possible errors: unauthorized. Full catalogue

GET/api/v1/countriesPublished contract, not open

List countries

Countries served, countries in preparation and refused countries. A refused country is returned with its reason: international sanctions, restrictive measures, or an unacceptable money laundering risk.

Authentication: Authorization: Bearer … See authentication

Parameters

Parameters
FieldTypeDescription
statusstringopen, coming or restricted.
Requestbash
curl -sS 'https://fiatside.com/api/v1/countries?status=open' \
  -H 'Authorization: Bearer sk_live_...'
Response — published contractjson
{
  "data": [
    { "code": "BR", "name": "Brasil", "currency": "BRL", "status": "open", "rails": ["br_pix", "paypal", "wise", "swift"] },
    { "code": "IR", "name": "Iran",   "currency": null,  "status": "restricted", "reason": "international_sanctions" }
  ],
  "next_cursor": null
}

Possible errors: unauthorized. Full catalogue

02

The beneficiary field schema

Every rail describes the fields it requires, with their validation pattern, normalisation and help text. That is what lets you generate a correct form for a country you have never integrated.

One schema fieldjson
{
  "name": "iban",
  "label": { "fr": "IBAN", "en": "IBAN" },
  "type": "iban",
  "required": true,
  "pattern": "^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$",
  "normalize": "upper",
  "help": {
    "fr": "Sans espaces. Nous verifions la cle de controle avant de valider la commande.",
    "en": "No spaces. We validate the checksum before confirming your order."
  }
}

Pattern validation happens on your side AND ours: yours saves the user a round trip, ours is authoritative. The help text is provided in both languages and deserves to be displayed: it prevents most rejected payouts, which almost always come from a mistyped format rather than an outage.