> For the complete documentation index, see [llms.txt](https://gitbook-docs.coinmetrics.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gitbook-docs.coinmetrics.io/reference-data/datonomy-overview/asset-taxonomy-metadata.md).

# Asset Taxonomy Metadata

## Overview

Asset taxonomy metadata returns the structure of datonomy itself, rather than the classification of any particular asset. It answers the question: what categories exist, and how do they nest? For a given taxonomy version it returns the complete set of subsectors, each carrying its class, sector, and subsector codes and names, so the full three-level hierarchy can be reconstructed from one response. It is the right source for populating a category picker, validating a code before querying, or labelling classifications retrieved from [Asset Taxonomy](/reference-data/datonomy-overview/asset-taxonomy.md).

## At a Glance

<table data-full-width="true"><thead><tr><th>Data type</th><th>Entities</th><th width="159">Frequency / cadence</th><th>Unit</th><th>Primary endpoint</th><th>Coverage</th></tr></thead><tbody><tr><td>Taxonomy structure (reference data)</td><td>Taxonomy versions</td><td>Reference data, changes only when a new taxonomy version is published</td><td>Categorical (codes and names)</td><td><code>/taxonomy-metadata/assets</code></td><td><a href="https://coverage.coinmetrics.io/assets-v2">🔗</a></td></tr></tbody></table>

## Schema

The response returns one object per taxonomy version. Each object carries the version's effective window and the complete list of its subsectors, flattened so that every entry repeats its parent class and sector.

| Field                 | Type               | Description                                                                                                                  | Notes                            |
| --------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
| `taxonomy_version`    | string             | Version identifier, in `<major>.<minor>` form.                                                                               | Required                         |
| `taxonomy_start_time` | string (date-time) | Date from which this taxonomy version is in effect.                                                                          | Required. Served as `YYYY-MM-DD` |
| `taxonomy_end_time`   | string (date-time) | Date at which this version stopped being in effect. Absent for the current version. See [Version windows](#version-windows). | Optional. Served as `YYYY-MM-DD` |
| `subsectors`          | array\[object]     | Every subsector defined in this version, ordered by `subsector_id`. See the sub-fields below.                                | Required                         |

### `subsectors` sub-fields

Each element of the `subsectors` array is one leaf of the hierarchy, denormalized to carry its full ancestry.

| Field          | Type   | Description                                                                                 | Notes    |
| -------------- | ------ | ------------------------------------------------------------------------------------------- | -------- |
| `class_id`     | string | Two-digit code for the class.                                                               | Optional |
| `class`        | string | First level of the taxonomy, describing the asset's fundamental purpose.                    | Optional |
| `sector_id`    | string | Four-digit code for the sector. The first two digits are the `class_id`.                    | Optional |
| `sector`       | string | Second level of the taxonomy, describing the asset's focus area within its class.           | Optional |
| `subsector_id` | string | Six-digit code for the subsector. The first four digits are the `sector_id`.                | Optional |
| `subsector`    | string | Third level of the taxonomy, describing the asset's specific product, service, or function. | Optional |

{% hint style="info" %}
**Conventions.** Codes are returned as JSON strings, not integers, so that leading digits are preserved. The version time fields are served in ISO-8601 calendar-date form (`2022-11-03`) rather than as full UTC timestamps, so they carry no time of day and no zone offset. A version is effective from the start of its stated start date. The response is a flat list of subsectors rather than a nested tree: classes and sectors are recovered by taking the distinct `class_id` and `sector_id` values, or from the positional code structure. A sector that contains a single subsector repeats its name at both levels, which is expected rather than an error.
{% endhint %}

## Methodology

### One row per subsector, ancestry repeated

The taxonomy is authored as a tree of classes, each containing sectors, each containing subsectors. Before it is served, the tree is flattened into one entry per subsector, and each entry is stamped with the names and codes of the sector and class it descends from. The array is then sorted by `subsector_id`, which also groups it by sector and by class because the codes are positional. Reading the hierarchy back therefore needs no recursion: the distinct pairs of `class_id` and `class` are the classes, and the distinct pairs of `sector_id` and `sector` are the sectors.

The consequence worth noting is that a class or sector exists in the response only if it has at least one subsector. There is no separate listing of empty branches.

### Version windows

Every version has a start time, and every version except the current one has an end time. These windows are validated when the data is loaded, and they must be strictly ordered and must not overlap. Where a version is authored without an explicit end and a later version exists, its end is set to the start of that next version, so the timeline is continuous with no gaps. The current version is served with no `taxonomy_end_time` at all rather than with an open-ended sentinel value.

### Version selection

The `version` parameter controls which versions are returned:

* No `version` and no time parameters: the latest version only.
* `version=<x.y>`: that specific version.
* `version=*`: every version, which is how to retrieve the full history of the structure.
* `start_time` or `end_time` without an explicit `version`: all versions are considered, then filtered by the time range.

A `start_time` filter keeps versions that begin at or after the given time. An `end_time` filter keeps only versions that have actually ended, and whose end falls at or before the given time, so the current version is excluded from an `end_time` query.

## Accessing the Data

Asset taxonomy metadata is served by the `/taxonomy-metadata/assets` endpoint. There are no entity filters. Requests are scoped by version or by a time range over the version windows.

{% tabs %}
{% tab title="Python Client" %}

```python
from coinmetrics.api_client import CoinMetricsClient

client = CoinMetricsClient("YOUR_API_KEY")

# The current taxonomy structure
metadata = client.get_taxonomy_assets_metadata().to_list()
subsectors = metadata[0]["subsectors"]
print(len(subsectors), "subsectors")

# Recover the class and sector levels from the flattened list
classes = {(s["class_id"], s["class"]) for s in subsectors}
sectors = {(s["sector_id"], s["sector"]) for s in subsectors}

# Every version ever published
history = client.get_taxonomy_assets_metadata(version="*").to_list()
```

{% endtab %}

{% tab title="Shell" %}

```bash
curl --compressed "https://api.coinmetrics.io/v4/taxonomy-metadata/assets?page_size=10000&api_key=$CM_API_KEY"
```

{% endtab %}

{% tab title="Python" %}

```python
import os
import requests

response = requests.get(
    "https://api.coinmetrics.io/v4/taxonomy-metadata/assets",
    params={
        "page_size": 10000,
        "api_key": os.environ["CM_API_KEY"],
    },
).json()
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Use `.to_list()` on this endpoint, not `.to_dataframe()`.** The version time fields are returned as calendar dates with no zone offset, which the client's dataframe conversion cannot parse. The nested `subsectors` array is also more natural to work with as plain dictionaries.
{% endhint %}

Responses are paginated by version, so a request for a single version returns a single page. The Python client follows pagination automatically, while direct HTTP callers page through results using `next_page_token`. Full parameter reference: see the API Reference for [`/taxonomy-metadata/assets`](https://docs.coinmetrics.io/api/v4/#operation/getTaxonomyMetadataAssets).

## Examples

### Example: the current taxonomy structure

The latest taxonomy version with its effective window and its subsector list. The `subsectors` array is truncated to its first four entries here. The live response carries the full set, and `taxonomy_end_time` is absent because this version is current. [Run this query](https://api.coinmetrics.io/v4/taxonomy-metadata/assets?api_key=YOUR_API_KEY).

```json
{
  "data": [
    {
      "taxonomy_version": "1.0",
      "taxonomy_start_time": "2022-11-03",
      "subsectors": [
        {
          "class_id": "10",
          "class": "Digital Currencies",
          "sector_id": "1010",
          "sector": "Value Transfer Coins",
          "subsector_id": "101010",
          "subsector": "Value Transfer Coins"
        },
        {
          "class_id": "10",
          "class": "Digital Currencies",
          "sector_id": "1020",
          "sector": "Specialized Coins",
          "subsector_id": "102010",
          "subsector": "Meme Coins"
        },
        {
          "class_id": "10",
          "class": "Digital Currencies",
          "sector_id": "1020",
          "sector": "Specialized Coins",
          "subsector_id": "102020",
          "subsector": "Privacy Coins"
        },
        {
          "class_id": "10",
          "class": "Digital Currencies",
          "sector_id": "1020",
          "sector": "Specialized Coins",
          "subsector_id": "102030",
          "subsector": "Remittance Coins"
        }
      ]
    }
  ]
}
```

## Coverage

{% embed url="<https://coverage.coinmetrics.io/assets-v2>" %}

## Usage

This endpoint is the structural companion to [Asset Taxonomy](/reference-data/datonomy-overview/asset-taxonomy.md). The usual pattern is to read the structure once and the classifications as often as needed.

1. **Load the hierarchy.** Call `/taxonomy-metadata/assets` to get every subsector for the current version, and derive the class and sector levels from the distinct codes.
2. **Validate or present codes.** Use it to populate a category selector, or to check that a `class_ids`, `sector_ids`, or `subsector_ids` filter refers to a code that actually exists before querying classifications.
3. **Label historical classifications.** When reconstructing point-in-time classifications with `version=*` on the assets endpoint, pull the matching versions here so that each historical code is labelled with the names that were in effect at the time.

## Limitations

* **Structure only, no assets.** This endpoint never tells you which assets are in a subsector, or how many. That is the [Asset Taxonomy](/reference-data/datonomy-overview/asset-taxonomy.md) endpoint.
* **Flat, not nested.** Classes and sectors are not returned as their own objects. They are recovered from the repeated fields on each subsector, so a branch with no subsectors would not appear at all.
* **Names can change across versions.** A code retains its position in the hierarchy, but its name can be revised in a later version. Code written against category names rather than codes may break across a version change.

## FAQ

### How do I get the classes and sectors rather than the subsectors?

Take the distinct values from the `subsectors` array. The pairs of `class_id` and `class` give the classes, and the pairs of `sector_id` and `sector` give the sectors. The Python Client tab above shows this in two lines.

### Why does a sector sometimes have the same name as its subsector?

Where a sector has not been subdivided, it contains a single subsector representing the whole sector, and the name is repeated at both levels. This keeps every asset classified at the same depth.

### Why is `taxonomy_end_time` missing from the response?

The field is present only once a version has been superseded. The current version has no end time.

### How do I see how the taxonomy has changed over time?

Pass `version=*` to return every version with its own effective window and subsector list, then diff the subsector sets between adjacent versions.

## Related

* [datonomy Overview](/reference-data/datonomy-overview.md): what datonomy is, how the hierarchy is structured, and how the pieces fit together.
* [Asset Taxonomy](/reference-data/datonomy-overview/asset-taxonomy.md): the classification of each covered asset into this structure.
* [datonomy Methodology](/reference-data/methodologies/datonomy-methodology.md): the published classification methodology.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://gitbook-docs.coinmetrics.io/reference-data/datonomy-overview/asset-taxonomy-metadata.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
