Skip to main content
The Assets API returns catalog data, availability, and market data in one response. Those fields change at very different speeds: an asset’s logo rarely changes, deposits 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.
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
  2. Implementing asset features reliably
  3. 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 (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 An asset list with search and filters next to Bitcoin's details and a 14-day chart of 1-hour candles 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:

Choose the right endpoint

Asset prices and rates are for display. Use the Swap API for an executable price.

Implementing asset features reliably

Identify assets by type and symbol

Every asset-specific endpoint takes both asset_type and asset_symbol in the path. Store and compare assets as that pair, for example crypto/BTC, not as a bare symbol.
  • Keep type next to 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 (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, a full catalog of about 1,000 assets takes about 10 calls, instead of one call per asset. Follow next_page_token until the response omits it. Treat the token as opaque, and fetch pages one after another.
  • Use a 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, deposit, withdraw, and 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 and 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 (GET /v1/assets/{asset_type}/{asset_symbol}) again and check its 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, market_cap, or description, and 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, name, symbol, type, status, and 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.

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 is the number of decimal places allowed for deposits and withdrawals, and decimals.swap is the number allowed for swaps.
  • Use one quote asset, set by quote_symbol and 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 (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 price in timestamp order. For a candlestick chart, use open, high, 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 from Get asset (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, then follow 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.
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, 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 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:
  • 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. Candles also give you open, high, low, and volume for every price point. The tables below map each request parameter and response field.

Requests

Response fields

Responses wrap data in data instead of result. The list returns data as an array instead of result.assets. To keep downstream code unchanged while you migrate, map each asset back to the Embed shape in one place: