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

# List metrics

> List the metrics on a DataSet, with their groups

API versions: v1 (current) https://docs.odysseysignal.com/api/reference/list-metrics.md

`GET /v1/signals/{signal_id}/datasources/{datasource_id}/datasets/{dataset_id}/metrics`

Separate from the DataSet description because the list is long and a caller browsing DataSets does not need it yet. Each metric carries everything a query must send for it.

Authentication: an API key in `X-Api-Key`, or `Authorization: Bearer <token>`.

## Parameters

### Path parameters

- `signal_id` (string, required)
- `datasource_id` (string, required)
- `dataset_id` (string, required)

## Example request

```bash
curl "https://api.odysseysignal.app/v1/signals/{signal_id}/datasources/{datasource_id}/datasets/{dataset_id}/metrics" \
  -H "X-Api-Key: $ODYSSEY_API_KEY"
```

## Response 200

Content: `application/json`. Every metric on one DataSet, with the groups they belong to.

A group is a heading over a subset of this list, so the two come together.

- `environment` (string, nullable): The data environment the answer was read in, `prod` or `test`: the one Odyssey set on the Signal, or the one an Odyssey person picked for this call.
- `dataset_id` (string, required)
- `datasource_id` (string, required)
- `count` (integer, required)
- `groups` (array of objects, required): Editorial groupings from the metric catalogue — the shared one, not the data project — in the order it defines. Only groups with at least one visible metric.
  - `id` (string, required)
  - `name` (string, required)
  - `description` (string, nullable)
  - `metric_ids` (array of string, required)
- `metrics` (array of objects, required)
  - `id` (string, required): Stable metric key. Unique within this DataSet.
  - `qualified_id` (string, required): Dataset-qualified id, e.g. `visibility.mentions`. Used in logs, cache keys and metering; the same key can exist in more than one dataset.
  - `name` (string, required)
  - `description` (string, nullable)
  - `business_question` (string, nullable): What this metric answers, in plain language.
  - `group_id` (string, nullable)
  - `family` (string, nullable): Parent metric this one is a variant of, when applicable.
  - `unit` (string, required): percent | count | score | index | currency | rank. The value is already in this unit — never rescale it.
  - `value_type` (string, required): scalar | point
  - `kind` (string, required): scalar | verbatim. Verbatim metrics are not served by /query.
  - `range` (map of number, nullable): The span the value can take, `{min, max}`, in `unit` and after any display multiplier — a 0-10 score shown ×10 is `{min: 0, max: 100}`. A bound is null where the method has none; the whole field is null when neither is known.
  - `fields` (array of objects): Values each row carries beside `value`, under `fields`.
    - `name` (string, required)
    - `unit` (string, nullable): The unit the field is published in — never rescale it.
    - `description` (string, nullable)
  - `reference` (object, nullable): Present only when `context.reference` on this metric is its own reference figure, in its own unit, and not the competitor average; says what it is. Absent: the reference is the competitor average in the metric's unit.
    - `description` (string, required): What the reference figure is, in plain language. It is not the competitor average: name it as said here.
    - `unit` (string, required): The unit `context.reference` is published in, which may differ from the metric's own: never rescale it.
    - `range` (map of number, nullable): The span the reference can take, `{min, max}`, in its own `unit`, when known.
    - `method` (string, nullable): Internal. How the reference is computed.
    - `question_ids` (array of string, nullable): Internal. The survey questions behind the reference.
  - `decimals` (integer, required): Suggested precision for display.
  - `direction` (string, nullable): higher_is_better | lower_is_better | neutral, where it is not obvious from the metric itself.
  - `entity` (boolean, required): Whether the metric is measured per brand. A property of the metric — not something the caller determines.
  - `base_scope` (string, required): What `base` counts for this metric: respondent | question | episode | mention | response.
  - `base_description` (string, nullable): What the value is a proportion of.
  - `supported_dimensions` (array of string, required): Dimension ids this metric may be filtered on or grouped by.
  - `method` (string, nullable): Internal. How the value is computed. The server applies it — a query names the metric, not the method.
  - `parameters` (object, nullable): Internal. Parameters the method is applied with, such as a factor-based index. Part of what makes this metric the metric it is, and supplied by the server on its behalf.
  - `question_ids` (array of string, nullable): Internal. The survey questions behind the value.
  - `setting_sources` (map of string, nullable): Internal. Where each of `parameters`, and `direction`, was set: `metric` (the metric itself), `data_project` (the DataSource's catalogue) or `signal` (this Signal's override). The nearest wins, per setting.
  - `status` (string, required): stable | beta | deprecated

## Errors

Errors are `application/problem+json` (RFC 9457): `type`, `title`, `status`, `detail` and, for some, more fields that say how to fix the call. The `type` is `https://api.odysseysignal.app/problems/<code>`.

| Status | Code | When |
|---|---|---|
| 400 | `invalid-request` | The request is not valid for this DataSet; `detail` says why. |
| 401 | `unauthorized` | No credential, or one that is not accepted. |
| 403 | `forbidden` | The credential is valid but does not cover what was asked. |
| 404 | `not-found` | Nothing there, or nothing this credential may read. |
| 422 | `validation-failed` | The request does not match the contract; `errors` lists each field. |
| 429 | `rate_limited` | Too many requests, or the monthly quota is used up. |
| 503 | `unavailable` | A service behind the API did not answer; try again. |
