> ## Documentation Index
> Fetch the complete documentation index at: https://docs.services.payward.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Asset data best practices

> Keep an asset catalog, availability, and price charts current with as few calls as possible, handle missing data and errors, and migrate from the legacy Embed API.

The [Assets API](/tabs/developer-documentation/market-data/assets.md) returns catalog data, availability, and market data in one response. Those fields change at very different speeds: an asset's logo rarely changes, [deposits](/tabs/developer-documentation/payments/deposits-and-withdrawals.md) for an asset can be turned off without notice, and an asset's price changes every second. This guide shows how to keep each kind of data current without calling the API more than you need to.

> [!TIP]
>
> **Recommended approach:** keep an asset catalog on your backend, refresh it on a schedule, and serve every screen from
> it. Call the API at the moment of use only for data that must be current, such as whether deposits are enabled right
> before a deposit.

This guide is structured in three parts:

1. [Mapping features to data and endpoints](#mapping-features-to-data-and-endpoints)
2. [Implementing asset features reliably](#implementing-asset-features-reliably)
3. [Migrating from the legacy Embed API to the Assets API](#migrating-from-the-legacy-embed-api-to-the-assets-api)

The public asset endpoints don't need authentication. Every call needs `country`: an ISO 3166-1 alpha-2 code that applies that country's geo restrictions.

## Illustrative asset detail UI

The Assets endpoints allow you to build rich asset detail pages. One asset response carries the name, logo, and description, the price with its 24-hour range and recent changes, market cap and rank, and whether deposits, withdrawals, and swaps are enabled. Add candles from [**List asset rates**](/api-reference/assets/list-asset-rates.md) (`GET /v1/assets/{asset_type}/{asset_symbol}/rates`), and you have a price chart.

![An asset list with search and filters next to Bitcoin's details and a 14-day chart of 1-hour candles](https://mintcdn.com/mintlify-0e856cf0/r6Udhd3hk-l-xep5/images/market-data/asset-discovery-app.png?fit=max\&auto=format\&n=r6Udhd3hk-l-xep5\&q=85\&s=6d0163da8f04d6395ddb20ea4c09d2d4)

The example app shown above uses only the three public endpoints. It lists all assets with one paginated pass, re-fetches the selected asset, and draws two weeks of hourly candles that refresh with one request.

## Mapping features to data and endpoints

Build your features around your cached asset catalog. Each one shows a different slice of the asset data, and each slice changes at its own pace:

| Feature | Data it shows | Refresh |
| - | - | - |
| Asset picker or catalog list | [`name`](/api-reference/assets/list-assets#response-data-items-name), [`symbol`](/api-reference/assets/list-assets#response-data-items-symbol), [`type`](/api-reference/assets/list-assets#response-data-items-type), [`logo`](/api-reference/assets/list-assets#response-data-items-logo) | Once a day is sufficient. |
| Price ticker or watchlist | [`price`](/api-reference/assets/list-assets#response-data-items-price), [`price_change_percent`](/api-reference/assets/list-assets#response-data-items-price-change-percent), [`volume`](/api-reference/assets/list-assets#response-data-items-volume) | At most once a minute. |
| Asset detail page | [`description`](/api-reference/assets/list-assets#response-data-items-description), [`website`](/api-reference/assets/list-assets#response-data-items-website), [`docs`](/api-reference/assets/list-assets#response-data-items-docs), [`market_cap`](/api-reference/assets/list-assets#response-data-items-market-cap), [`supply`](/api-reference/assets/list-assets#response-data-items-supply), [`ath`](/api-reference/assets/list-assets#response-data-items-ath), [`price_range`](/api-reference/assets/list-assets#response-data-items-price-range), and a chart | Text daily, market fields as for a ticker. For the [chart](#refresh-only-the-newest-candle), never refetch completed candles. Fetch from your newest stored candle onward. |
| Deposit, withdrawal, or swap flow | [`status`](/api-reference/assets/list-assets#response-data-items-status), [`decimals`](/api-reference/assets/list-assets#response-data-items-decimals) | Re-check with [**Get asset**](/api-reference/assets/get-asset.md) when the user picks the asset, and validate amounts against the latest `decimals`. |

### Choose the right endpoint

| You want to | Call | Notes |
| - | - | - |
| Build or refresh your asset catalog | [**List assets**](/api-reference/assets/list-assets.md) (`GET /v1/assets`) | One paginated pass returns every asset, with [`page_size=100`](/api-reference/assets/list-assets#parameter-page-size). |
| Show current prices for many assets | [**List assets**](/api-reference/assets/list-assets.md) (`GET /v1/assets`) | Each asset includes [`price`](/api-reference/assets/list-assets#response-data-items-price), the last traded price, and [`price_change_percent`](/api-reference/assets/list-assets#response-data-items-price-change-percent) in your quote currency. |
| Show a price chart | [**List asset rates**](/api-reference/assets/list-asset-rates.md) (`GET /v1/assets/{asset_type}/{asset_symbol}/rates`) | OHLCV candles: open, high, low, and close prices plus volume, per interval. |
| Show the current price of one asset | [**Get asset**](/api-reference/assets/get-asset.md) (`GET /v1/assets/{asset_type}/{asset_symbol}`) | [`price`](/api-reference/assets/list-assets#response-data-items-price) is the last traded price on Kraken's order book. It's fetched at a slightly different time than the candles, so it won't always match a candle's close. |
| Confirm availability before a deposit, withdrawal, or swap | [**Get asset**](/api-reference/assets/get-asset.md) (`GET /v1/assets/{asset_type}/{asset_symbol}`) | Check [`status`](/api-reference/assets/list-assets#response-data-items-status) when the user selects the asset, not from a cached copy. |

> [!NOTE]
>
> Asset prices and rates are for display. Use the [Swap API](/tabs/developer-documentation/trade/swap.md) for an executable
> price.

## Implementing asset features reliably

### Identify assets by type and symbol

Every asset-specific endpoint takes both [`asset_type`](/api-reference/assets/get-asset#parameter-asset-type) and [`asset_symbol`](/api-reference/assets/get-asset#parameter-asset-symbol) in the path. Store and compare assets as that pair, for example `crypto/BTC`, not as a bare symbol.

* Keep [`type`](/api-reference/assets/list-assets#response-data-items-type) next to [`symbol`](/api-reference/assets/list-assets#response-data-items-symbol) in your data model, URLs, and cache keys.
* URL-encode path segments. Some symbols contain characters such as `.` or `_`.
* Pass the `symbol` and `type` from the list response to later calls. Don't rebuild them from display names.

### Refresh the catalog with one paginated list

Don't call [**Get asset**](/api-reference/assets/get-asset.md) (`GET /v1/assets/{asset_type}/{asset_symbol}`) once per asset to refresh your catalog. The list response already includes each asset's metadata, market data, and status. With [`page_size=100`](/api-reference/assets/list-assets#parameter-page-size), a full catalog of about 1,000 assets takes about 10 calls, instead of one call per asset.

Follow [`next_page_token`](/api-reference/assets/list-assets#response-next-page-token) until the response omits it. Treat the token as opaque, and fetch pages one after another.

```javascript JavaScript theme={null}
const BASE_URL = 'https://api.services.payward.com';

async function listAllAssets(country, quoteSymbol = 'USD') {
  const assets = [];
  let pageToken;
  do {
    const params = new URLSearchParams({ country, quote_symbol: quoteSymbol, page_size: '100' });
    if (pageToken) params.set('page_token', pageToken);

    const response = await fetch(`${BASE_URL}/v1/assets?${params}`);
    if (!response.ok) throw new Error(`List assets failed: ${response.status}`);
    const page = await response.json();

    assets.push(...page.data);
    pageToken = page.next_page_token;
  } while (pageToken);
  return assets;
}

const catalog = await listAllAssets('DE', 'EUR');
```

```python Python theme={null}
import requests

BASE_URL = "https://api.services.payward.com"


def list_all_assets(country, quote_symbol="USD"):
    assets = []
    page_token = None
    while True:
        params = {"country": country, "quote_symbol": quote_symbol, "page_size": 100}
        if page_token:
            params["page_token"] = page_token

        response = requests.get(f"{BASE_URL}/v1/assets", params=params, timeout=10)
        response.raise_for_status()
        page = response.json()

        assets.extend(page["data"])
        page_token = page.get("next_page_token")
        if not page_token:
            return assets


catalog = list_all_assets("DE", "EUR")
```

* Use a [`page_token`](/api-reference/assets/list-assets#parameter-page-token) only with the exact query that produced it. Don't reuse it after you change a filter, the sort order, or the quote asset, and don't store it for later.
* Collect all pages into a new list and swap it in when it's complete. If you update the visible list page by page, an asset can appear twice or disappear while you load.
* Filter on the server when it helps, with [`type`](/api-reference/assets/list-assets#parameter-type), [`deposit`](/api-reference/assets/list-assets#parameter-deposit), [`withdraw`](/api-reference/assets/list-assets#parameter-withdraw), and [`swap_trading`](/api-reference/assets/list-assets#parameter-swap-trading). Filter in your app when you need instant search, since the full list is small enough to hold in memory.

### Cache on your backend

The Assets API sends `Cache-Control: no-store`, so browsers and CDNs won't cache responses for you. Refresh each kind of data on its own schedule in your own cache, and share that cache between users by calling the API from your backend.

* **Cache per [`country`](/api-reference/assets/list-assets#parameter-country) and [`quote_symbol`](/api-reference/assets/list-assets#parameter-quote-symbol).** Availability depends on the country, and every price is in the requested quote currency.
* **Re-check availability when the user acts.** A list loaded five minutes ago is fine for browsing. Before you create a deposit address, list withdrawal methods, or start a swap, call [**Get asset**](/api-reference/assets/get-asset.md) (`GET /v1/assets/{asset_type}/{asset_symbol}`) again and check its [`status`](/api-reference/assets/list-assets#response-data-items-status). Still handle an error from the action endpoint, because availability can change between the two calls.
* **Keep the last good data when a refresh fails.** Keep showing the previous list and retry later instead of emptying the screen.

### Handle missing fields

Many fields are optional, and which ones are present differs by asset. In a typical catalog, a sizable share of assets have no [`price`](/api-reference/assets/list-assets#response-data-items-price), [`market_cap`](/api-reference/assets/list-assets#response-data-items-market-cap), or [`description`](/api-reference/assets/list-assets#response-data-items-description), and [`supply`](/api-reference/assets/list-assets#response-data-items-supply) is absent for fiat assets.

* Check that a field is present before you use it. A missing `price` means "unavailable", not zero.
* Render a neutral placeholder such as an em dash, and don't hide the asset unless your product requires a price.
* Treat [`logo`](/api-reference/assets/list-assets#response-data-items-logo), [`name`](/api-reference/assets/list-assets#response-data-items-name), [`symbol`](/api-reference/assets/list-assets#response-data-items-symbol), [`type`](/api-reference/assets/list-assets#response-data-items-type), [`status`](/api-reference/assets/list-assets#response-data-items-status), and [`decimals`](/api-reference/assets/list-assets#response-data-items-decimals) as always present, and build your list rows only from those.
* Don't assume an asset with a `price` has price history. See [Handle missing history](#handle-missing-history).

### Treat numbers as decimal strings

Prices, volumes, and supplies are decimal strings, so they arrive with full precision. Converting them to floating-point numbers can round them.

* Parse with a decimal library for any calculation. Convert to a floating-point number only to draw a chart or format a label.
* Validate amounts against the asset's precision. [`decimals.funding`](/api-reference/assets/list-assets#response-data-items-decimals-funding) is the number of decimal places allowed for deposits and withdrawals, and [`decimals.swap`](/api-reference/assets/list-assets#response-data-items-decimals-swap) is the number allowed for swaps.
* Use one quote asset, set by [`quote_symbol`](/api-reference/assets/list-assets#parameter-quote-symbol) and [`quote_type`](/api-reference/assets/list-assets#parameter-quote-type), on every call that feeds the same screen. The responses echo it, so you can assert that they match.

### Show price history with candles

For a chart, call [**List asset rates**](/api-reference/assets/list-asset-rates.md) (`GET /v1/assets/{asset_type}/{asset_symbol}/rates`) with an explicit window and interval. For example, a request for one-hour candles (`interval=PT60M`) over the last 14 days returns 336 candles. For a line chart, plot each candle's [`close`](/api-reference/assets/list-asset-rates#response-data-items-close) price in [`timestamp`](/api-reference/assets/list-asset-rates#response-data-items-timestamp) order. For a candlestick chart, use [`open`](/api-reference/assets/list-asset-rates#response-data-items-open), [`high`](/api-reference/assets/list-asset-rates#response-data-items-high), [`low`](/api-reference/assets/list-asset-rates#response-data-items-low), and `close`. The newest candle's `close` is the chart's latest point. To show what the asset trades at right now, use [`price`](/api-reference/assets/list-assets#response-data-items-price) from [**Get asset**](/api-reference/assets/get-asset.md) (`GET /v1/assets/{asset_type}/{asset_symbol}`): the last traded price.

* **Use exact interval values.** `interval` is an ISO 8601 duration: `PT1M` is one minute, `PT4H` is four hours, and `P1D` is one day. The API accepts these values exactly as written: `PT1M`, `PT5M`, `PT15M`, `PT30M`, `PT60M`, `PT4H`, `P1D`, `P7D`, and `P15D`. Send `PT60M` for hourly candles.
* **Set the window explicitly.** Send a window start (`start_timestamp`) and end (`end_timestamp`), so you get the same candles regardless of the API's defaults.
* **Page through every result.** Request [`page_size=100`](/api-reference/assets/list-asset-rates#parameter-page-size), then follow [`next_page_token`](/api-reference/assets/list-asset-rates#response-next-page-token) until it is absent, even if a page comes back empty. That's four requests for the 14-day, one-hour window.
* **Stay under the history limit.** History is limited to the most recent 5,760 candles, so pick an interval that keeps `window ÷ interval` below that number. One-minute candles reach back about four days. Hourly candles reach back about eight months.
* **Know that the newest candle is still open.** `end_timestamp` is exclusive. If your window includes the current interval, the last candle's `close` can still change.
* **Don't expect a full window.** The series can be shorter than the requested window.

#### Refresh only the newest candle

Completed candles never change, so don't download the whole window again. Keep your stored candles, then request from the newest one onward. The window start, `start_timestamp`, is inclusive, so the response starts with that candle again, now with its latest values. Replace it and append the rest.

```python Python theme={null}
from datetime import datetime, timedelta, timezone

import requests

BASE_URL = "https://api.services.payward.com"


def fetch_all_pages(path, params):
    rows, page_token = [], None
    while True:
        query = params + ([("page_token", page_token)] if page_token else [])
        response = requests.get(f"{BASE_URL}{path}", params=query, timeout=10)
        response.raise_for_status()
        body = response.json()
        rows.extend(body["data"])
        page_token = body.get("next_page_token")  # Absent on the last page, even if `data` is empty.
        if not page_token:
            return rows


def parse(timestamp):
    return datetime.fromisoformat(timestamp.replace("Z", "+00:00"))


def refresh_candles(held, asset_type, asset_symbol):
    now = datetime.now(timezone.utc)
    start = held[-1]["timestamp"] if held else (now - timedelta(days=14)).isoformat()
    fresh = fetch_all_pages(
        f"/v1/assets/{asset_type}/{asset_symbol}/rates",
        [
            ("country", "US"),
            ("interval", "PT60M"),
            ("start_timestamp", start),  # Inclusive: re-fetches the newest candle.
            ("end_timestamp", now.isoformat()),
        ],
    )
    cutoff = parse(fresh[0]["timestamp"]) if fresh else datetime.max.replace(tzinfo=timezone.utc)
    return [c for c in held if parse(c["timestamp"]) < cutoff] + fresh


candles = refresh_candles([], "crypto", "BTC")  # First load: 14 days.
candles = refresh_candles(candles, "crypto", "BTC")  # Later: one small request.
```

```javascript JavaScript theme={null}
const BASE_URL = 'https://api.services.payward.com';

async function fetchAllPages(path, params) {
  const rows = [];
  let pageToken;
  do {
    const query = new URLSearchParams(params);
    if (pageToken) query.set('page_token', pageToken);
    const response = await fetch(`${BASE_URL}${path}?${query}`);
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    const body = await response.json();
    rows.push(...body.data);
    pageToken = body.next_page_token; // Absent on the last page, even if `data` is empty.
  } while (pageToken);
  return rows;
}

async function refreshCandles(held, assetType, assetSymbol) {
  const twoWeeksAgo = new Date(Date.now() - 14 * 24 * 3600 * 1000).toISOString();
  const fresh = await fetchAllPages(`/v1/assets/${assetType}/${assetSymbol}/rates`, [
    ['country', 'US'],
    ['interval', 'PT60M'],
    ['start_timestamp', held.at(-1)?.timestamp ?? twoWeeksAgo], // Inclusive: re-fetches the newest candle.
    ['end_timestamp', new Date().toISOString()],
  ]);
  const cutoff = fresh.length ? Date.parse(fresh[0].timestamp) : Infinity;
  return [...held.filter(candle => Date.parse(candle.timestamp) < cutoff), ...fresh];
}

let candles = await refreshCandles([], 'crypto', 'BTC'); // First load: 14 days.
candles = await refreshCandles(candles, 'crypto', 'BTC'); // Later: one small request.
```

Drop candles that fall out of your window as you append new ones, so the list stays the same size.

#### Handle missing history

Not every asset in the catalog has price history. Expect these cases, and let the page render without a chart:

* **No candles.** Even for an asset that has a [`price`](/api-reference/assets/list-assets#response-data-items-price), every page of a window can come back empty. Show "No price history" instead of an empty chart.
* **An error from `/rates`.** [**List asset rates**](/api-reference/assets/list-asset-rates.md) can return `404`, or a server error, for an asset that the list returned. Don't retry a `404`. Retry a `5xx` a few times with backoff, then show the asset without a chart.
* **The quote asset itself.** Don't request `USD` priced in `USD`. Skip the chart when the asset is the quote asset.

One failing chart should never block the rest of the asset screen. Load the asset details and the candles independently.

### Handle errors and rate limits

Every error response has the same shape:

```jsonc theme={null}
{
  "error": {
    "type": "assets_error",
    "status": 400,
    "code": "bad_request",
    "instance": "0ab2b82401a117e0c7be00450b63c818", // Example trace ID. Every request gets its own.
    "causes": [{ "field": "country", "message": "must match pattern \"^[A-Z]{2}$\"" }]
  }
}
```

* **Retry only what can succeed.** Retry `408`, `429`, `500`, `502`, `503`, and `504` with exponential backoff and jitter, and cap the number of attempts. Don't retry other `4xx` responses. Fix the request instead.
* **Back off on `429`.** If the response includes a `Retry-After` header, wait at least that long before you retry. Otherwise, use exponential backoff.
* **Set a request timeout.** Abort requests that take longer than about 10 seconds, then retry them with backoff.
* **Log `instance`.** It matches the `X-Trace-Id` response header and identifies the request. Include it when you contact Payward support.
* **Make every parameter explicit.** Send the country, quote asset, and interval on every request instead of relying on defaults, so the same code gives the same result tomorrow.
* **Spread scheduled jobs.** Run catalog refreshes on a schedule, not on every page view, and serve your users from your cache.

## Migrating from the legacy Embed API to the Assets API

If you have used the legacy Embed API's asset endpoints, the Assets API gives you the same catalog, market data, and price history with far fewer calls. The biggest change is the refresh pattern: replace per-asset requests with [one paginated list](#refresh-the-catalog-with-one-paginated-list). Candles also give you open, high, low, and volume for every price point. The tables below map each request parameter and response field.

### Requests

| Embed API | Assets API |
| - | - |
| Host `https://nexus.kraken.com` | Host `https://api.services.payward.com` |
| Signed with `API-Key` and `API-Sign` | No authentication for the public endpoints |
| `Payward-Version` header | Not needed |
| None | [`country`](/api-reference/assets/list-assets#parameter-country), required on every call |
| `GET /b2b/assets` | [**List assets**](/api-reference/assets/list-assets.md) (`GET /v1/assets`) |
| `GET /b2b/assets/{asset}` | [**Get asset**](/api-reference/assets/get-asset.md) (`GET /v1/assets/{asset_type}/{asset_symbol}`). The path now includes the asset type. |
| `GET /b2b/assets/{asset}/rates` | [**List asset rates**](/api-reference/assets/list-asset-rates.md) (`GET /v1/assets/{asset_type}/{asset_symbol}/rates`) |
| `quote` | [`quote_symbol`](/api-reference/assets/list-assets#parameter-quote-symbol) and [`quote_type`](/api-reference/assets/list-assets#parameter-quote-type) |
| `lang` | `name` and `description` are in English. For other languages, store your own translations keyed by `type` and `symbol`. |
| `page[size]` and `page[number]` | [`page_size`](/api-reference/assets/list-assets#parameter-page-size) (up to 100) and [`page_token`](/api-reference/assets/list-assets#parameter-page-token). There is no page number or total count. |
| `sort` | [`sort`](/api-reference/assets/list-assets#parameter-sort) and [`sort_direction`](/api-reference/assets/list-assets#parameter-sort-direction) |
| `filter[tradable_only]` | [`swap_trading=true`](/api-reference/assets/list-assets#parameter-swap-trading) |
| `filter[platform_statuses][]` | [`deposit`](/api-reference/assets/list-assets#parameter-deposit) and [`withdraw`](/api-reference/assets/list-assets#parameter-withdraw). No filter matches a combined state such as `deposit_only`, so filter on [`status`](/api-reference/assets/list-assets#response-data-items-status) in your app. |
| `filter[assets][]` | Filter the list in your app, or get each asset. |
| `filter[user]` | The [user-scoped endpoints](/tabs/developer-documentation/market-data/assets.md#user-scoped-asset-views) |
| Rates `start_time` and `end_time` | `start_timestamp` and `end_timestamp` |

### Response fields

Responses wrap data in `data` instead of `result`. The list returns `data` as an array instead of `result.assets`.

| Embed API | Assets API |
| - | - |
| `id` (list) or `symbol` (get) | [`symbol`](/api-reference/assets/list-assets#response-data-items-symbol), plus [`type`](/api-reference/assets/list-assets#response-data-items-type) |
| `english_name` | [`name`](/api-reference/assets/list-assets#response-data-items-name) |
| `description` | [`description`](/api-reference/assets/list-assets#response-data-items-description) |
| `price` | [`price`](/api-reference/assets/list-assets#response-data-items-price) |
| `change_percent_1h`, `_24h`, `_7d`, `_30d`, `_1y` | [`price_change_percent.last_1h`](/api-reference/assets/list-assets#response-data-items-price-change-percent-last-1h), `last_24h`, `last_7d`, `last_30d`, `last_1y` |
| `change_value_24h` | Derive it from `price` and [`price_change_percent.last_24h`](/api-reference/assets/list-assets#response-data-items-price-change-percent-last-24h), as in the adapter below |
| `volume_value_24h` | [`volume.last_24h`](/api-reference/assets/list-assets#response-data-items-volume-last-24h) |
| `market_cap_value` | [`market_cap`](/api-reference/assets/list-assets#response-data-items-market-cap) |
| `market_cap_rank`, `trending_rank`, `listing_date` | Same names |
| `dominance_percent` | [`market_dominance`](/api-reference/assets/list-assets#response-data-items-market-dominance) |
| `circulating_supply`, `total_supply`, `max_supply` | [`supply.circulating`](/api-reference/assets/list-assets#response-data-items-supply-circulating), [`supply.total`](/api-reference/assets/list-assets#response-data-items-supply-total), [`supply.max`](/api-reference/assets/list-assets#response-data-items-supply-max) |
| `circulating_supply_value`, `total_supply_value`, `max_supply_value` | [`supply.in_quote.circulating`](/api-reference/assets/list-assets#response-data-items-supply-in-quote-circulating), [`supply.in_quote.total`](/api-reference/assets/list-assets#response-data-items-supply-in-quote-total), [`supply.in_quote.max`](/api-reference/assets/list-assets#response-data-items-supply-in-quote-max) |
| `ath_value` and `ath_date` | [`ath.value`](/api-reference/assets/list-assets#response-data-items-ath-value) and [`ath.timestamp`](/api-reference/assets/list-assets#response-data-items-ath-timestamp), a full timestamp instead of a date |
| `links.logo` | [`logo`](/api-reference/assets/list-assets#response-data-items-logo), with the same `width`, `height`, `href`, and `type` |
| `platform_status` | [`status.deposit.enabled`](/api-reference/assets/list-assets#response-data-items-status-deposit-enabled) and [`status.withdraw.enabled`](/api-reference/assets/list-assets#response-data-items-status-withdraw-enabled): `enabled` means both are `true`, `deposit_only` and `withdrawal_only` mean only that one is `true`, and `funding_temporarily_disabled` and `disabled` both mean neither is. The Assets API doesn't tell temporary from permanent. |
| `disabled_against` | [`status.swap_trading.disabled_against`](/api-reference/assets/list-assets#response-data-items-status-swap-trading-disabled-against) |
| `decimals`, `display_decimals`, `simple_trade_decimals` | [`decimals.funding`](/api-reference/assets/list-assets#response-data-items-decimals-funding) (decimal places for deposits and withdrawals) and [`decimals.swap`](/api-reference/assets/list-assets#response-data-items-decimals-swap) (for swaps). There's no display-precision field, so choose display formatting yourself. |
| `bullish_insights`, `bearish_insights` | [`buy_rate`](/api-reference/assets/list-assets#response-data-items-buy-rate): the percentage of the past 24 hours' trades that were buys. |
| `meta.total_items`, `meta.total_pages` | Follow [`next_page_token`](/api-reference/assets/list-assets#response-next-page-token) until it's absent. |
| Rates `rates[].price` | Rates [`data[].close`](/api-reference/assets/list-asset-rates#response-data-items-close), with [`open`](/api-reference/assets/list-asset-rates#response-data-items-open), [`high`](/api-reference/assets/list-asset-rates#response-data-items-high), [`low`](/api-reference/assets/list-asset-rates#response-data-items-low), and [`volume`](/api-reference/assets/list-asset-rates#response-data-items-volume) alongside |
| Rates `meta.page_price_change_value` and `_percent` | Compare the first and last `close`. |

To keep downstream code unchanged while you migrate, map each asset back to the Embed shape in one place:

```javascript JavaScript theme={null}
// Assumes the asset has a price. See "Handle missing fields".
function toEmbedShape(asset) {
  const price = Number(asset.price);
  const percent = Number(asset.price_change_percent?.last_24h);
  return {
    symbol: asset.symbol,
    english_name: asset.name,
    description: asset.description,
    circulating_supply: asset.supply?.circulating,
    total_supply: asset.supply?.total,
    max_supply: asset.supply?.max,
    market_cap_value: asset.market_cap,
    dominance_percent: asset.market_dominance,
    market_cap_rank: asset.market_cap_rank,
    // Approximate: last_24h is rounded to two decimals.
    change_value_24h: String(price - price / (1 + percent / 100)),
    change_percent_24h: asset.price_change_percent?.last_24h,
    volume_value_24h: asset.volume?.last_24h,
    ath_value: asset.ath?.value,
    ath_date: asset.ath?.timestamp?.slice(0, 10),
    links: { logo: asset.logo },
  };
}
```

```python Python theme={null}
from decimal import Decimal


# Assumes the asset has a price. See "Handle missing fields".
def to_embed_shape(asset):
    price = Decimal(asset["price"])
    percent = Decimal(asset["price_change_percent"]["last_24h"])
    return {
        "symbol": asset["symbol"],
        "english_name": asset["name"],
        "description": asset.get("description"),
        "circulating_supply": asset.get("supply", {}).get("circulating"),
        "total_supply": asset.get("supply", {}).get("total"),
        "max_supply": asset.get("supply", {}).get("max"),
        "market_cap_value": asset.get("market_cap"),
        "dominance_percent": asset.get("market_dominance"),
        "market_cap_rank": asset.get("market_cap_rank"),
        # Approximate: last_24h is rounded to two decimals.
        "change_value_24h": str(price - price / (1 + percent / 100)),
        "change_percent_24h": asset["price_change_percent"]["last_24h"],
        "volume_value_24h": asset.get("volume", {}).get("last_24h"),
        "ath_value": asset.get("ath", {}).get("value"),
        "ath_date": asset.get("ath", {}).get("timestamp", "")[:10] or None,
        "links": {"logo": asset["logo"]},
    }
```

## Related

* [Assets API guide](/tabs/developer-documentation/market-data/assets.md): the step-by-step discovery workflow.
* [**List assets**](/api-reference/assets/list-assets.md), [**Get asset**](/api-reference/assets/get-asset.md), and [**List asset rates**](/api-reference/assets/list-asset-rates.md): the API reference.
* [Deposits and withdrawals](/tabs/developer-documentation/payments/deposits-and-withdrawals.md): continue from a selected asset to a payment.
* [Swap](/tabs/developer-documentation/trade/swap.md): get an executable price instead of a display price.
