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

# List Panels (v2)

> Browse the panel catalog as biomarker groups

The same catalog as [List Panels](/api/panels/list-panels), describing each panel as the **groups** it requires rather than a flat list of biomarker IDs.

A group holds **interchangeable** biomarkers, and exactly one of them is measured — hs-CRP *or* CRP, serum *or* EDTA plasma. Which one is decided per draw by lab routing. So v1's flat `biomarker_ids` over-states what a draw returns: a panel listing 120 IDs delivers around 90 results.

<Note>
  Count **groups**, not biomarker IDs, when telling a patient what they get — and read `required`
  first. An optional group is ordered only when a routing Aniva is already paying for can carry it,
  so it may never be delivered.
</Note>

v1 is **not deprecated** and keeps serving the flat union of every group's members.

## Request

### Query parameters

<ParamField query="rate_card" type="string">
  Override which rate card the `yours` price uses: `retail`, `subscription`, or a billing-account
  slug your key may use. Defaults to the card on your API key's billing account, else retail.
</ParamField>

<Warning>
  `test_location_id` is not accepted here. v1 only validated that it existed — panel pricing is
  location-independent.
</Warning>

## Response

Returns an array of panels.

<ResponseField name="id" type="string">
  Stable panel identifier (UUID) — pass this to [Add Panels](/api/appointments/add-panels).
</ResponseField>

<ResponseField name="name" type="string">
  Display name.
</ResponseField>

<ResponseField name="biomarker_groups" type="object[]">
  What the panel requires. Empty for custom container panels — their membership lives
  per-appointment, so use [Add Individual
  Biomarkers](/api/appointments/add-individual-biomarkers).

  <Expandable title="group">
    <ResponseField name="biomarker_ids" type="number[]">
      Interchangeable ways to satisfy the group. Exactly one is measured. Cross-reference against
      [List Biomarkers](/api/biomarkers/list-biomarkers).
    </ResponseField>

    <ResponseField name="required" type="boolean">
      A required group is always ordered. `false` means optional — ordered opportunistically, and
      possibly not at all.
    </ResponseField>

    <ResponseField name="inclusion_condition" type="string | null">
      Demographic gate on the whole group, evaluated against the patient when the panel is attached
      to an appointment: `sex=2`, `age>50`, combinable with `&&` / `||` (`sex` is ISO/IEC 5218 — 1
      male, 2 female). `null` applies to everyone. The catalog has no patient in context, so gated
      groups are listed here ungated — [Preview
      Containers](/api/appointments/preview-containers) is the patient-aware answer.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="pricing" type="object | null">
  Per-panel pricing — `null` unless your key has the `prices_view` scope, or for panels without a
  fixed catalog price (e.g. the custom container). Carries `retail` and `yours`, each a [price
  breakdown](/api/biomarkers/list-biomarkers#price-objects) (a single group, no `goa_lines`) or
  `null`.
</ResponseField>

## Error responses

| Status | Description                                               |
| ------ | --------------------------------------------------------- |
| `400`  | Validation error — e.g. unknown/unauthorised `rate_card`. |
| `403`  | Forbidden — missing `panels_access` scope.                |
| `500`  | Internal server error.                                    |

<RequestExample>
  ```bash cURL theme={null}
  curl --url 'https://anivahealth.com/api/v2/panels' \
    --header 'x-api-key: YOUR_API_KEY'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  [
    {
      "id": "f1c2d4a3-7b8e-4f2a-9c1d-2e3f4a5b6c7d",
      "name": "Hormones (Female)",
      "biomarker_groups": [
        { "biomarker_ids": [42], "required": true, "inclusion_condition": null },
        { "biomarker_ids": [43, 44], "required": true, "inclusion_condition": null },
        { "biomarker_ids": [51], "required": true, "inclusion_condition": "sex=2" },
        { "biomarker_ids": [52], "required": false, "inclusion_condition": null }
      ],
      "pricing": {
        "retail": {
          "total_cents": 14900,
          "groups": [{ "price_cents": 14900, "biomarker_ids": [] }]
        },
        "yours": {
          "total_cents": 11900,
          "groups": [{ "price_cents": 11900, "biomarker_ids": [] }]
        }
      }
    },
    {
      "id": "9c1d2e3f-4a5b-4c7d-8e9f-0a1b2c3d4e5f",
      "name": "Custom",
      "biomarker_groups": [],
      "pricing": null
    }
  ]
  ```
</ResponseExample>
