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

# Core concepts

> How symbols, metrics, date ranges and dimensional cuts fit together, and the behaviours that surprise people

Every request is the same shape:

```
assets  ×  metrics  ×  date range  ×  (optional) cut
```

* **Assets** are identified by `symbol` (`aave`, `hype`, `kalshi`, `eq-coin`). Discover them via [`GET /asset/`](/docs/docs/api-reference/discovery/list-assets).
* **Metrics** are uppercase names (`LENDING_DEPOSITS`, `PERP_VOLUME`). Discover them per asset via [`GET /supported-metrics/`](/docs/docs/api-reference/discovery/list-supported-metrics).
* **Date range** is `startDate` and `endDate`, always `YYYY-MM-DD`. `granularity` rolls the result up to `WEEK`, `MONTH`, `QUARTER` or `YEAR`.
* **Cuts** split a series by `dimensionType`: by chain, protocol version, or market category.

## Five things worth knowing

### 1. Use `symbol` as the lookup key

`/asset/` returns both an `artemis_id` and a `symbol` for every asset. **`symbol` is the lookup key** for `symbols=` on `/v2/data/` and for `symbol=` on `/supported-metrics/`.

```bash theme={null}
curl -s "https://data-svc.artemisxyz.com/supported-metrics/?symbol=uni&APIKey=$ARTEMIS_API_KEY"
```

The two differ for many assets, so take `symbol` from `/asset/` rather than assuming:

| `artemis_id`  | `symbol`                |
| ------------- | ----------------------- |
| `hyperliquid` | `hype`                  |
| `compound`    | `comp`                  |
| `uniswap`     | `uni`                   |
| `maker`       | `sky`                   |
| `magiceden`   | `me`                    |
| `syrup`       | `syrup` (this is Maple) |

### 2. Know the aggregation type

Each metric aggregates differently, and it decides what `granularity` gives you:

| Type      | Meaning                                 | Examples                               |
| --------- | --------------------------------------- | -------------------------------------- |
| `SUM`     | Flows: add them up                      | `SPOT_VOLUME`, `PERP_VOLUME`, `FEES`   |
| `LAST`    | Stocks: end-of-period snapshot          | `TVL`, `OPEN_INTEREST`, `FUNDING_RATE` |
| `AVERAGE` | Balances and rates                      | `LENDING_DEPOSITS`, `BORROW_APY`       |
| `FIRST`   | Balance metrics carrying a period value | `STABLECOIN_SUPPLY`                    |

<Warning>
  **Never sum open interest.** It is an end-of-day snapshot of outstanding positions, not a flow. Summing 30 days of OI produces a number with no meaning. Volume sums; OI does not.
</Warning>

Every metric's type is in the `aggregation_type` field from `/supported-metrics/`. When a rolled-up figure is going into a model, it's worth checking it once against the daily series so you know exactly what the period value represents.

### 3. Errors arrive in the value position, with HTTP 200

When something about your request can't be served, you get a **string where the array would be**. The metric may be unavailable for that asset, or the `dimensionType` you asked for may not apply to it:

```json theme={null}
{ "asset": "aave", "metric": "LENDING_DAU",
  "data": "Metric not available for asset." }
```

Three distinct messages, three distinct meanings:

| Message                                     | Meaning                                                      |
| ------------------------------------------- | ------------------------------------------------------------ |
| `Metric not available for asset.`           | This metric isn't supported for this asset.                  |
| `Latest data not available for this asset.` | Supported, but no recent data.                               |
| `Dimension type does not exist.`            | The metric has no cut for the `dimensionType` you asked for. |

Type-check before iterating:

```python theme={null}
for s in resp.json()["series"]:
    if not isinstance(s["data"], list):
        print(f"skip {s['asset']}/{s['metric']}: {s['data']}")
        continue
    points = [(ts, v) for ts, v in s["data"] if v is not None]
    if points:
        print(f"{s['display_name']:12} {s['metric']:20} {points[-1][1]:,.0f}")
```

### 4. `null` is not the same as missing

The current period is normally present with a `null` value because it hasn't closed:

```json theme={null}
"data": [[1785888000000, 702689172.0], [1785974400000, null]]
```

Captured 2026-08-06, when that day had not yet closed. `data[-1]` is therefore `null`. Filter before taking a latest value.

Every symbol you request comes back, even one that doesn't exist. It just arrives carrying an error string instead of an array. So the response length always matches your request, and the thing to check is the *type* of each `data` field, not whether a symbol is missing.

### 5. `series_columns` tells you the tuple shape

```json theme={null}
"series_columns": ["timestamp", "value"]     // default: epoch ms
"series_columns": ["label", "value"]         // with summarize=true: display name
```

Read `series_columns` instead of assuming position `0` is a date. With `summarize=true` you also get an extra `<METRIC>_PCT_CHG` series per metric.

## Optional parameters

### `granularity`

```bash theme={null}
curl -s "https://data-svc.artemisxyz.com/v2/data/PERP_VOLUME?symbols=hype&startDate=2026-01-01&endDate=2026-08-01&granularity=MONTH&APIKey=$ARTEMIS_API_KEY"
```

Rolls up according to each metric's `aggregation_type`: `SUM` metrics are summed, `LAST` metrics take the period's final value, `AVERAGE` metrics are averaged.

**Each metric is labelled on its own calendar:**

* **Time series** (on-chain, stablecoins, equity `PRICE`) label by period **start**. A monthly series reads `2026-04-01`, `2026-05-01`.
* **Equity fundamentals** (`TOTAL_REVENUE`, `NET_INCOME`, `EBITDA`) label by fiscal-period **end**, matching how companies report. Coinbase's Q3 2025 revenue is dated `2025-09-30`.
* Fundamentals always resolve to fiscal periods, so `MONTH` on `TOTAL_REVENUE` returns fiscal quarters.

When combining the two, align on the period rather than the timestamp: Coinbase's `2025-09-30` and Hyperliquid's `2025-07-01` are both Q3 2025.

### `summarize`

Returns the **`endDate` value** for each metric, plus a `<METRIC>_PCT_CHG` series giving the change from `startDate` to `endDate`.

The date range is a **comparison** window, not an aggregation window: you get the latest value and how far it moved. That's what makes it ideal for leaderboards (see [Sector leaderboards](/docs/artemis-api/recipes/sector-leaderboards)). For a period total, use `granularity`.

### `dimensionType`

Splits one series into many. `asset` becomes `<dimension>-<symbol>`:

```bash theme={null}
curl -s "https://data-svc.artemisxyz.com/v2/data/LENDING_DEPOSITS?symbols=aave&startDate=2026-08-01&endDate=2026-08-01&dimensionType=CHAIN&APIKey=$ARTEMIS_API_KEY"
```

* **Most used:** `CHAIN`, `VERSION`, `CATEGORY`, `TOKEN`, `TOKEN_TYPE`, `SYMBOL` (23 in total)
* **Per metric:** the `cuts` array in `/supported-metrics/` lists the dimensions that metric supports
* **Unsupported value:** HTTP 422, listing every valid one
