## GET /openapi/v1/rwa

Returns a paginated list of real-world assets — tokenized stocks, commodities, currencies,
government securities, ETFs and real estate — with their latest price, market cap, 24-hour
volume and three percent-change windows. Asking for specific `id`s is also how you fetch
quotes for several of them at once: there is no separate quotes endpoint for RWAs.

**An RWA id is not an asset id.** RWAs and the crypto assets of `/assets` share one id
column, so an id from one endpoint finds nothing on the other: `/assets?id=<an RWA id>` is an
empty page, and so is `/rwa?id=<an asset id>`. A slug can belong to both an RWA and a crypto
asset; each endpoint answers with its own.

An asset that has been delisted does not appear. One that is about to be — no new data for
over a week — still appears, with `delisting: true`.

### Query parameters

| Parameter | Type | Default | Notes |
|:--|:--|:--|:--|
| `type` | string | — | One of `stock`, `commodity`, `currency`, `government_security`, `etf`, `real_estate`. Case-insensitive. `other` is a value the response can carry but not a filter: `type=other` is a `400` |
| `id` | comma-separated integers | — | At most 100. An id that is not a listed RWA is left out of the response, not an error — if none matches, the page is empty |
| `slug` | comma-separated strings | — | At most 100. Same rule as `id`. `id` and `slug` together must both match |
| `page`, `size`, `limit`, `offset` | integer | `size` 20 | As on `/assets`: at most 100 per page, `offset` at most 100000 |
| `sort` | string | `rank` | `rank`, `price`, `percent_change_24h`, `percent_change_7d`, `percent_change_30d`, `market_cap`, `volume_24h`, written `<key>[:asc\|desc]`; no direction is ascending |
| `select` | comma-separated strings | — | At most 100. Return only these item fields, plus `id`; a name not in the item fields below is a `400`. See [Choosing fields with `select`](#choosing-fields-with-select) |

**Ordering.** By default the list is in rank order, best first. An asset with no rank comes
**after** every ranked one — under the default order, under `sort=rank` and under
`sort=rank:desc` alike. That is the one exception to the rule that a `null` sorts first in
ascending order; for every other key here a `null` value is first ascending and last
descending, and equal values are ordered by `id`.

**If the ranking cannot be read**, a request in rank order — the default, `sort=rank`, or
`id`/`slug` without another `sort` — answers `503` with code `50300`, and can be retried. It
is never answered in some other order instead, so paging through the list cannot mix two
orders. If a ranking does not exist at all — for a `type` that currently has no assets, or
before our data has been ranked — the list is in `id` order and no item has a `rank`.

**A page can hold fewer rows than `size`.** The default order comes from a ranking that is
refreshed on its own schedule, and an asset delisted since its last refresh is left off the
page it would have been on. `total` still counts it until the next refresh.

### Response

```json
{
  "code": 0,
  "message": "success",
  "message_key": "SUCCESS",
  "result": {
    "items": [
      {
        "id": 90001,
        "rank": 1,
        "name": "Tether Gold",
        "symbol": "XAUT",
        "slug": "tether-gold",
        "logo": "https://s2.coinmarketcap.com/static/img/coins/64x64/5176.png",
        "type": "commodity",
        "price": "2650.12",
        "percent_change": { "24h": "0.41", "7d": "1.92", "30d": "5.1" },
        "market_cap": "1234567890",
        "volume_24h": "45678901",
        "delisting": false,
        "last_price_change_time": "2026-10-20T08:14:00Z"
      }
    ],
    "page": 1,
    "total_page": 12,
    "total": 231
  }
}
```

#### Item fields

| Field | Type | Notes |
|:--|:--|:--|
| `id` | number | The RWA id, a JSON **number**. Send it back to `?id=` as-is |
| `rank` | number | CoinMarketCap's site-wide RWA rank, starting at 1. **Absent** when the asset has none — the same rule as `/assets` — and also absent, with the rest of the item served, when a list sorted by another key or `/rwa/info` cannot read the ranking. Filtering by `type` does not change it: a commodity ranked 7th overall is `7` in the commodity list too |
| `name`, `symbol`, `slug` | string | |
| `logo` | string | Image URL. **Empty string** when there is none, never `null` |
| `type` | string | One of the six `type` values, or `other` when the asset has no class |
| `price` | string | USD. Never `null` |
| `percent_change` | object | Exactly three keys, `24h`, `7d` and `30d`, each a percentage as a string (`"0.41"` is 0.41%) or `null` |
| `market_cap` | string or `null` | USD |
| `volume_24h` | string or `null` | USD. `null` when CoinMarketCap has reported no volume, or a volume of 0, for the asset — whichever way the list is sorted |
| `delisting` | boolean | `true` when the asset is due to be delisted: no new data for over a week. A delisted asset is not returned at all |
| `last_price_change_time` | string or `null` | When the asset's values last **changed**, RFC3339 UTC. It is not when we last checked them: a price that has not moved keeps an old time while still being current. Do not use it to judge freshness. `null` when we do not have it |

### Examples

```bash
# The default listing: 20 RWAs in rank order
curl -H "X-Api-Key: <your-api-key>" \
  "https://open-api.coinworldcap.com/openapi/v1/rwa"

# The five biggest commodities by market cap
curl -H "X-Api-Key: <your-api-key>" \
  "https://open-api.coinworldcap.com/openapi/v1/rwa?type=commodity&sort=market_cap:desc&limit=5"

# Latest quotes for several RWAs at once
curl -H "X-Api-Key: <your-api-key>" \
  "https://open-api.coinworldcap.com/openapi/v1/rwa?id=90001,90002"
```

| HTTP status | `code` | When |
|:--|:--|:--|
| 400 | 40000 | A `type` outside the six above (`other` included); a `sort` key outside the list above, or a malformed `sort`; more than 100 values in `id` or `slug`; an `id` value that is not a non-negative integer; a `select` name that is not an item field, or more than 100 names; the paging limits of `/assets` |
| 503 | 50300 | The ranking could not be read in time, or at all, for a request in rank order. Retry |

The other errors are in [Errors](#errors), which covers every endpoint here. A filter that
matches nothing is an empty page, never a `404`.
