MolnPayDocs
API reference

Meta

GET/v1/ping
AuthorizationBearer <token>

Authorization: Bearer mp<64 hex> for live, mptest<64 hex> for test.

The token is the prefix plus 64 lowercase hex characters (32 CSPRNG bytes) and nothing else — no separators, no embedded fields — so nothing in it needs quoting, escaping or encoding. Send it in the Authorization header and nowhere else. Never put it in a query string: URLs reach access logs, proxy logs, browser history and Referer headers, and a key that lands in any of those is a leaked key. A key's KIND (checkout, payout or wallet) is a property of the key, not of the string: it is chosen at creation, returned by GET /v1/ping, and decides which routes the key may reach.

The full key is shown exactly once, at creation. No endpoint can return it afterwards. Moving funds additionally requires signing to be enabled globally, for your project, and for that key — so a read-only key is a supported configuration.

In: header

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/v1/ping"
{  "object": "ping",  "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",  "tenant_slug": "string",  "key_id": "string",  "env": "live",  "kind": "checkout",  "scopes": [    "string"  ],  "signing_enabled": true,  "signing_blocked_by": [    "service"  ],  "network": "mainnet",  "enabled_chains": [    "ethereum"  ]}
GET/v1/chains

Read decimals from here rather than hardcoding. decimals_differ_from_default flags the assets whose scale deviates (USDT/USDC on BSC are 18, not 6).

AuthorizationBearer <token>

Authorization: Bearer mp<64 hex> for live, mptest<64 hex> for test.

The token is the prefix plus 64 lowercase hex characters (32 CSPRNG bytes) and nothing else — no separators, no embedded fields — so nothing in it needs quoting, escaping or encoding. Send it in the Authorization header and nowhere else. Never put it in a query string: URLs reach access logs, proxy logs, browser history and Referer headers, and a key that lands in any of those is a leaked key. A key's KIND (checkout, payout or wallet) is a property of the key, not of the string: it is chosen at creation, returned by GET /v1/ping, and decides which routes the key may reach.

The full key is shown exactly once, at creation. No endpoint can return it afterwards. Moving funds additionally requires signing to be enabled globally, for your project, and for that key — so a read-only key is a supported configuration.

In: header

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/v1/chains"
{  "object": "list",  "has_more": true,  "next_cursor": "string",  "data": [    {      "chain": "ethereum",      "name": "string",      "network_type": "TRC20",      "chain_id": 0,      "native_currency": {        "name": "string",        "symbol": "string",        "decimals": 0      },      "required_confirmations": 0,      "explorer_url": "string",      "enabled_for_tenant": true,      "account_kind": "contract",      "status": "live",      "status_note": "string",      "deposits_enabled": true,      "payouts_enabled": true,      "supports_memo": true,      "assets": [        {          "symbol": "string",          "decimals": 0,          "contract": "string",          "is_native": true,          "deposits_enabled": true,          "payouts_enabled": true,          "decimals_differ_from_default": true        }      ]    }  ]}
GET/v1/coins

The platform's BREADTH, for a page that wants to show it. Unlike GET /v1/chains, which lists only what you may act on now, this includes coins that are switched off — each one carries live: false. Do not build a payment picker on this endpoint; use GET /v1/chains for that, or you will offer a coin the next call refuses. The catalogue is read at MAINNET whichever mode your key is in, because "what do you carry" has one answer — a test key sees the whole list here and GET /v1/chains tells it what it can actually transact with. Ordered live first, then by market rank with natives ahead of tokens — so the first rows are coins you can use today AND the ones people recognise. totals is computed over the WHOLE catalogue, before chain and before limit.

AuthorizationBearer <token>

Authorization: Bearer mp<64 hex> for live, mptest<64 hex> for test.

The token is the prefix plus 64 lowercase hex characters (32 CSPRNG bytes) and nothing else — no separators, no embedded fields — so nothing in it needs quoting, escaping or encoding. Send it in the Authorization header and nowhere else. Never put it in a query string: URLs reach access logs, proxy logs, browser history and Referer headers, and a key that lands in any of those is a leaked key. A key's KIND (checkout, payout or wallet) is a property of the key, not of the string: it is chosen at creation, returned by GET /v1/ping, and decides which routes the key may reach.

The full key is shown exactly once, at creation. No endpoint can return it afterwards. Moving funds additionally requires signing to be enabled globally, for your project, and for that key — so a read-only key is a supported configuration.

In: header

Query Parameters

limit?integer

How many coins to return. The totals are unaffected.

Range1 <= value <= 1000
Default120
filter?string

live returns only the coins the platform services today.

Default"all"

Value in

  • "all"
  • "live"
chain?string

One network's coins. totals still covers every network.

Value in

  • "ethereum"
  • "bsc"
  • "polygon"
  • "arbitrum"
  • "base"
  • "avalanche"
  • "tron"
  • "solana"
  • "ton"
  • "bitcoin"
  • "dogecoin"
  • "optimism"
  • "linea"
  • "zksync"
  • "scroll"
group?string

symbol collapses a coin carried on several networks into one row with a chains count — right for a wall of logos. contract returns every deployment, which is what a per-network table wants.

Default"symbol"

Value in

  • "symbol"
  • "contract"

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X GET "https://example.com/v1/coins"
{  "object": "coin_list",  "totals": {    "coins": 0,    "live": 0,    "symbols": 0,    "chains": 0,    "chains_live": 0,    "by_chain": {      "property1": {        "coins": 0,        "live": 0      },      "property2": {        "coins": 0,        "live": 0      }    }  },  "returned": 0,  "data": [    {      "chain": "ethereum",      "chain_name": "BNB Chain",      "chains": 0,      "symbol": "PYUSD",      "name": "string",      "contract": "string",      "decimals": 0,      "is_native": true,      "logo_url": "string",      "deposits_enabled": true,      "payouts_enabled": true,      "decimals_differ_from_default": true,      "live": true    }  ]}
GET/v1/market/prices

Public and unauthenticated — exchange rates are not tenant data, and the hosted checkout needs them before any session exists. Prices are cached for ttl_seconds; respect it rather than polling. usd is a STRING, like every other amount in this API. age_seconds says how old the quote is: past ttl_seconds we serve the cached price immediately and refresh behind the response, so a value older than the TTL is expected and is not an error. When the upstream market source is not configured the response is a 503 with configured: false and an empty list — callers should render whatever they last had rather than treat it as an error.

Query Parameters

symbols?string

Comma-separated symbols, e.g. USDT,ETH. Omit for all priced assets.

Response Body

application/json

application/json

curl -X GET "https://example.com/v1/market/prices"
{  "object": "price_list",  "configured": true,  "ttl_seconds": 0,  "data": [    {      "symbol": "string",      "usd": "string",      "age_seconds": 0    }  ]}
GET/v1/market/status

Public. Lets a caller hide price-dependent UI rather than render an empty figure.

Response Body

application/json

curl -X GET "https://example.com/v1/market/status"
{  "object": "market_status",  "configured": true,  "base_url": "string"}