# Reference

Asset catalogue, fee schedule, live prices

7 endpoints. Generated from `docs/openapi.yaml` v1.0.0.

| Endpoint | Summary |
| --- | --- |
| [`GET /v1/assets`](#get-v1-assets) | List enabled assets |
| [`GET /v1/a/{token}`](#get-v1-a-token) | PUBLIC — a merchant's affiliate ledger |
| [`GET /v1/merchant/affiliate-ledger`](#get-v1-merchant-affiliate-ledger) | The link to your public affiliate ledger |
| [`POST /v1/merchant/affiliate-ledger/rotate`](#post-v1-merchant-affiliate-ledger-rotate) | Replace the link (dashboard owner, both codes) |
| [`GET /v1/pricing`](#get-v1-pricing) | PUBLIC — the live price sheet |
| [`GET /v1/fees`](#get-v1-fees) | Your effective fee schedule |
| [`GET /v1/prices`](#get-v1-prices) | Live market prices |

## GET /v1/assets

**List enabled assets**  ·  _Auth: bearer API key_  ·  `operationId: listAssets`

The asset catalogue with decimals, confirmation requirements, the flat withdrawal fee, and `swappable` — false when no exchange can route the asset (leave it out of a swap picker; deposits and withdrawals are unaffected).

#### Responses

| Status | Body | Meaning |
| --- | --- | --- |
| `200` | `object[]` | Enabled assets. |
| `401` | `Error` | Missing, malformed or unknown API key. |

**`200` response body**

| Field | Type | Description |
| --- | --- | --- |
| `[].id` **required** | `string` | — |
| `[].chain` **required** | `string` | The chain an address or asset is on. TRON is the only network the platform serves: `btc`, `eth`, `bsc` and `sol` were retired — historical addresses on them are never handed out again and nothing scans them. Read the value as an open string rather than a closed list, so a chain added later does not break your client. _(one of `tron`)_ |
| `[].symbol` **required** | `string` | — |
| `[].contract_address` **required** | `string | null` | null for native coins; the token contract/mint otherwise. |
| `[].decimals` **required** | `integer` | — |
| `[].confirmations_required` **required** | `integer` | — |
| `[].min_deposit` **required** | `string` | A monetary value as a decimal string. Always paired with a `*_base` field that carries the exact integer base-unit value; compute with the `_base` string. |
| `[].withdraw_fee` **required** | `string` | The STATIC fallback fee for a withdrawal of this asset — what is charged as `fee` only when no live network price can be read (`dynamic: false` on the quote). The live figure, network gas included, is on GET /v1/withdrawal-fee-quote and GET /v1/pricing. The energy a transfer consumes is rented by us, so you never hold TRX and never top up a gas balance. It does not vary with the recipient. A TRC20 transfer to an address that has never held the token costs roughly twice the energy of one to an existing holder, and that difference is absorbed here rather than passed on — you cannot see which case a customer's wallet is, so you cannot price it. Read it at runtime; it is the number that will be charged. |
| `[].min_withdrawal` **required** | `string` | A monetary value as a decimal string. Always paired with a `*_base` field that carries the exact integer base-unit value; compute with the `_base` string. |
| `[].swappable` **required** | `boolean` | False when no exchange can route this asset. Leave it out of a swap picker — POST /v1/swap/quote and POST /v1/exchange/quote refuse it with 400 invalid_pair. Deposits and withdrawals are unaffected. |

```json
[
  {
    "id": "usdt_trc20",
    "chain": "tron",
    "symbol": "string",
    "contract_address": "string",
    "decimals": 1,
    "confirmations_required": 1,
    "min_deposit": "1.5",
    "withdraw_fee": "1.5",
    "min_withdrawal": "1.5",
    "swappable": true
  }
]
```

#### Example request

```bash
curl -X GET 'https://api.cryptoinfra.build/v1/assets' \
  -H 'Authorization: Bearer ck_live_your_key'
```

## GET /v1/a/{token}

**PUBLIC — a merchant's affiliate ledger**  ·  _Auth: none — public_  ·  `operationId: getAffiliateLedger`

No authentication: the token (256 bits, minted for the merchant on `GET /v1/merchant/affiliate-ledger`) is the whole authorization, and it reads that ONE merchant's affiliate commission — their share of our fee, total per asset and one line per operation that earned some — and nothing else: no customer ids, no addresses. This is what the hosted page `/a/{token}` on the merchant origin renders. A rotated token answers `404` from that moment; responses are `no-store`.

#### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `token` | path | `string` | yes | — |
| `limit` | query | `integer` | no | — _(default `50`; min `1`; max `200`)_ |
| `offset` | query | `integer` | no | — _(default `0`; min `0`)_ |

#### Responses

| Status | Body | Meaning |
| --- | --- | --- |
| `200` | `object` | The ledger. |
| `404` | — | No merchant holds this token (or it was rotated). |

**`200` response body**

| Field | Type | Description |
| --- | --- | --- |
| `merchant` | `object` | — |
| `merchant.name` | `string` | — |
| `merchant.merchant_id` | `string | null` | — |
| `share_bps` | `integer` | — |
| `share_percent` | `number` | — |
| `totals` | `object[]` | — |
| `totals[].asset_id` | `string` | — |
| `totals[].symbol` | `string` | — |
| `totals[].amount` | `string` | A monetary value as a decimal string. Always paired with a `*_base` field that carries the exact integer base-unit value; compute with the `_base` string. |
| `totals[].amount_base` | `string` | Exact integer amount in the asset's smallest unit. _(pattern `^[0-9]+$`)_ |
| `totals[].count` | `integer` | — |
| `lines` | `object[]` | — |
| `lines[].id` | `integer` | — |
| `lines[].at` | `string<date-time>` | — |
| `lines[].operation` | `string` |  _(one of `deposit`, `withdrawal`, `swap`, `card_issue`, `card_load`)_ |
| `lines[].ref` | `object` | What earned it |
| `lines[].ref.kind` | `string` | — |
| `lines[].ref.id` | `string` | — |
| `lines[].our_fee` | `object` | Our fee the share was taken of. |
| `lines[].share_bps` | `integer` | — |
| `lines[].commission` | `object` | What the merchant received. |
| `total_lines` | `integer` | — |
| `limit` | `integer` | — |
| `offset` | `integer` | — |
| `generated_at` | `string<date-time>` | — |

```json
{
  "merchant": {
    "name": "string",
    "merchant_id": "string"
  },
  "share_bps": 1,
  "share_percent": 0,
  "totals": [
    {
      "asset_id": "string",
      "symbol": "string",
      "amount": "1.5",
      "amount_base": "1500000000",
      "count": 1
    }
  ],
  "lines": [
    {
      "id": 1,
      "at": "2026-08-31T09:15:00.000Z",
      "operation": "deposit",
      "ref": {
        "kind": "string",
        "id": "string"
      },
      "our_fee": {},
      "share_bps": 1,
      "commission": {}
    }
  ],
  "total_lines": 1,
  "limit": 1,
  "offset": 1,
  "generated_at": "2026-08-31T09:15:00.000Z"
}
```

#### Example request

```bash
curl -X GET 'https://api.cryptoinfra.build/v1/a/string'
```

## GET /v1/merchant/affiliate-ledger

**The link to your public affiliate ledger**  ·  _Auth: bearer API key_  ·  `operationId: merchantAffiliateLedgerGet`

Your shareable page — your commission, total and line by line, readable without a login by anyone holding the link. Minted on first read. Works with an API key or a dashboard login.

#### Responses

| Status | Body | Meaning |
| --- | --- | --- |
| `200` | `object` | The link. |
| `401` | `Error` | Missing, malformed or unknown API key. |

**`200` response body**

| Field | Type | Description |
| --- | --- | --- |
| `url` **required** | `string` | — |

```json
{
  "url": "https://merchant.cryptoinfra.build/a/…"
}
```

#### Example request

```bash
curl -X GET 'https://api.cryptoinfra.build/v1/merchant/affiliate-ledger' \
  -H 'Authorization: Bearer ck_live_your_key'
```

## POST /v1/merchant/affiliate-ledger/rotate

**Replace the link (dashboard owner, both codes)**  ·  _Auth: bearer API key_  ·  `operationId: merchantAffiliateLedgerRotate`

Mints a fresh token; the old link answers `404` from that moment. Dashboard only — an owner login with the authenticator and the emailed code — and `403 session_required` to an API key.

#### Responses

| Status | Body | Meaning |
| --- | --- | --- |
| `200` | `object` | The new link. |
| `403` | — | Not a dashboard owner |

**`200` response body**

| Field | Type | Description |
| --- | --- | --- |
| `url` **required** | `string` | — |

```json
{
  "url": "string"
}
```

#### Example request

```bash
curl -X POST 'https://api.cryptoinfra.build/v1/merchant/affiliate-ledger/rotate' \
  -H 'Authorization: Bearer ck_live_your_key'
```

## GET /v1/pricing

**PUBLIC — the live price sheet**  ·  _Auth: none — public_  ·  `operationId: getPricing`

No authentication. Every price the platform charges, read live: the flat platform fee and the network figures per asset for deposits (free), payouts and swaps, plus every card product's issue, load and close terms. Built once a minute and shared, so it is cheap to poll. It is what the documentation renders, so the docs can never show a number this endpoint does not. A merchant's own fees are not here — they are on `GET /v1/fees` with that merchant's key. The exact charge for one send is `GET /v1/withdrawal-fee-quote`. `as_of` is when the sheet was priced; every network figure carries `dynamic` (live now, or the `static_fallback`) so nothing here is mirrored as a fixed charge.

#### Responses

| Status | Body | Meaning |
| --- | --- | --- |
| `200` | `object` | The price sheet. |
| `503` | — | The sheet cannot be built right now. |

**`200` response body**

| Field | Type | Description |
| --- | --- | --- |
| `as_of` | `string<date-time>` | — |
| `cached_for_seconds` | `integer` | — |
| `rule` | `string` | — |
| `assets` | `object[]` | — |
| `assets[].asset_id` | `string` | — |
| `assets[].symbol` | `string` | — |
| `assets[].chain` | `string` | — |
| `assets[].min_deposit` | `string` | — |
| `assets[].min_withdrawal` | `string` | — |
| `assets[].deposit` | `object` | platform_flat |
| `assets[].withdrawal` | `object` | platform_flat, network_fee, network_fee_fresh_recipient, first_send_activation_fee, total, total_fresh_recipient, dynamic, static_fallback, priced_from, and network_fee_burning_trx / network_fee_burning_trx_fresh_recipient — what the same transfer burns in a wallet without energy, at the chain's own rates, for a "you save" comparison |
| `assets[].swap` | `object` | platform_flat |
| `cards` | `object` | gas (per load, priced live), gas_dynamic, gas_burning_trx (what that send burns in a wallet without energy), and products[] with issue_fee, min_opening_balance, load_fee_bps, load_fee_min, load_fee_flat, close_fee, issue_total_at_minimum, cardholder_fees, and limits (per_transaction, daily, monthly, atm_single, atm_per_day, atm_monthly in the card's currency; validity_years) — null on both for a BIN whose terms are not published yet. |

```json
{
  "as_of": "2026-08-31T09:15:00.000Z",
  "cached_for_seconds": 1,
  "rule": "string",
  "assets": [
    {
      "asset_id": "string",
      "symbol": "string",
      "chain": "string",
      "min_deposit": "string",
      "min_withdrawal": "string",
      "deposit": {},
      "withdrawal": {},
      "swap": {}
    }
  ],
  "cards": {}
}
```

#### Example request

```bash
curl -X GET 'https://api.cryptoinfra.build/v1/pricing'
```

## GET /v1/fees

**Your effective fee schedule**  ·  _Auth: bearer API key_  ·  `operationId: getFees`

The exact fees that will be charged, per asset, for deposits and payouts. The swap/exchange fee is not here — it is visible only on POST /v1/swap/quote and POST /v1/exchange/quote (`fee`, `fee_base`).

#### Responses

| Status | Body | Meaning |
| --- | --- | --- |
| `200` | `FeesResponse` | Effective fee schedule. |
| `401` | `Error` | Missing, malformed or unknown API key. |

**`200` response body** — `FeesResponse`

| Field | Type | Description |
| --- | --- | --- |
| `priced_at` | `string<date-time>` | When every network figure in this response was priced — computed for this response, never stored. |
| `note` **required** | `string` | — |
| `assets` **required** | `object[]` | — |
| `assets[].asset_id` **required** | `string` | — |
| `assets[].symbol` **required** | `string` | — |
| `assets[].deposit` **required** | `object` | Deposits to the addresses we issue are free: `flat`, `network_fee` and `total` read 0, and the whole amount is credited (less only your own merchant_fee, if you set one). `dynamic` says whether a non-zero network part was priced live. |
| `assets[].deposit.percent_bps` **required** | `integer` | Basis points (100 = 1%). |
| `assets[].deposit.percent` **required** | `number` | Same as percent_bps / 100. |
| `assets[].deposit.flat` **required** | `string` | A monetary value as a decimal string. Always paired with a `*_base` field that carries the exact integer base-unit value; compute with the `_base` string. |
| `assets[].deposit.flat_base` **required** | `string` | Exact integer amount in the asset's smallest unit. _(pattern `^[0-9]+$`)_ |
| `assets[].deposit.min` **required** | `string` | A monetary value as a decimal string. Always paired with a `*_base` field that carries the exact integer base-unit value; compute with the `_base` string. |
| `assets[].deposit.min_base` **required** | `string` | Exact integer amount in the asset's smallest unit. _(pattern `^[0-9]+$`)_ |
| `assets[].deposit.max` **required** | `string | null` | null when uncapped. |
| `assets[].deposit.max_base` **required** | `string | null` | — |
| `assets[].withdrawal` **required** | `object` | Our live network cost plus a flat platform fee. Your flat platform part (`flat`) plus today's live network figures: `network_fee` for a recipient that already holds the token, `network_fee_fresh_recipient` for one that does not, `first_send_activation_fee` added once on a user's first send, and `total` = flat + network_fee. `dynamic: false` means the static fallback is showing. GET /v1/withdrawal-fee-quote is the charge for a specific send. |
| `assets[].withdrawal.percent_bps` **required** | `integer` | Basis points (100 = 1%). |
| `assets[].withdrawal.percent` **required** | `number` | Same as percent_bps / 100. |
| `assets[].withdrawal.flat` **required** | `string` | A monetary value as a decimal string. Always paired with a `*_base` field that carries the exact integer base-unit value; compute with the `_base` string. |
| `assets[].withdrawal.flat_base` **required** | `string` | Exact integer amount in the asset's smallest unit. _(pattern `^[0-9]+$`)_ |
| `assets[].withdrawal.min` **required** | `string` | A monetary value as a decimal string. Always paired with a `*_base` field that carries the exact integer base-unit value; compute with the `_base` string. |
| `assets[].withdrawal.min_base` **required** | `string` | Exact integer amount in the asset's smallest unit. _(pattern `^[0-9]+$`)_ |
| `assets[].withdrawal.max` **required** | `string | null` | null when uncapped. |
| `assets[].withdrawal.max_base` **required** | `string | null` | — |

```json
{
  "priced_at": "2026-08-31T09:15:00.000Z",
  "note": "string",
  "assets": [
    {
      "asset_id": "string",
      "symbol": "string",
      "deposit": {
        "percent_bps": 1,
        "percent": 0,
        "flat": "1.5",
        "flat_base": "1500000000",
        "min": "1.5",
        "min_base": "1500000000",
        "max": "string",
        "max_base": "string"
      },
      "withdrawal": {
        "percent_bps": 1,
        "percent": 0,
        "flat": "1.5",
        "flat_base": "1500000000",
        "min": "1.5",
        "min_base": "1500000000",
        "max": "string",
        "max_base": "string"
      }
    }
  ]
}
```

#### Example request

```bash
curl -X GET 'https://api.cryptoinfra.build/v1/fees' \
  -H 'Authorization: Bearer ck_live_your_key'
```

## GET /v1/prices

**Live market prices**  ·  _Auth: bearer API key_  ·  `operationId: getPrices`

USD spot prices for the symbols in the catalogue (`GET /v1/assets`): TRX, USDT, USDC. Display/estimation only — never for settlement.

#### Responses

| Status | Body | Meaning |
| --- | --- | --- |
| `200` | `PricesResponse` | Prices (best-effort; may be empty on a feed outage). |
| `401` | `Error` | Missing, malformed or unknown API key. |

**`200` response body** — `PricesResponse`

| Field | Type | Description |
| --- | --- | --- |
| `currency` **required** | `string` |  _(one of `usd`)_ |
| `prices` **required** | `object[]` | — |
| `prices[].symbol` **required** | `string` | — |
| `prices[].price_usd` **required** | `number` | — |
| `prices[].change_24h_pct` **required** | `number` | — |
| `prices[].sparkline` **required** | `number[]` | 7-day downsampled price points for a sparkline; empty when unavailable. |

```json
{
  "currency": "usd",
  "prices": [
    {
      "symbol": "USDT",
      "price_usd": 0,
      "change_24h_pct": 0,
      "sparkline": [
        0
      ]
    }
  ]
}
```

#### Example request

```bash
curl -X GET 'https://api.cryptoinfra.build/v1/prices' \
  -H 'Authorization: Bearer ck_live_your_key'
```
