# List a patient's readings

Canonical page: https://docs.ovok.com/signals/standalone/api/observations/list-a-patients-readings

{/* Generated from the API Explorer document by scripts/generate-signals-api-pages.mjs. Edit ovok-core, not this page. */}


# List a patient's readings [#list-a-patients-readings]

| Method | Path |
| --- | --- |
| `GET` | `/v1/signals/api/observation/{patientId}` |

<Availability route="GET /v1/signals/api/observation/{patientId}" />

Newest first by clinical time, in v1's envelope `{items, total, page, pageSize, totalPages}` with nest's `nextCursor`. `from`, `to` and `code` (comma-separated) filter as in v1; `category` (comma-separated) keeps the readings carrying any of those FHIR category codes. With `from`, a reading whose clinical time is more than an hour ahead of when it was stored is not found: the read skips the storage older than that, so it never waits on it. `pageSize` defaults to 10; above 200 it needs both `from` and `to`, and then reaches 10000. A page may start at most 10000 rows in; walk further with `cursor`.

Each item is a flat timeline entry (`code`, `valueNumber`, `observedAt`, `category`, `valueSampledData`, `components`, `effectiveStart`, `effectiveEnd`, `deviceId`, …) with v1's `_id`, `id`, `patient`, `valueQuantity` and `createdAt` beside it. `fields=code,valueNumber` returns exactly those keys instead.

### Through ovok [#through-ovok]

- **Who can call it:** Manager apps, and users whose access policy grants the capabilities.
- **Capabilities, all required:** `signals_observations:read`. Project admins have every capability; client applications get no admin bypass.
- If your access covers only some patients (anyone but project admins, manager or submitter apps, and anyone whose Patient access has no criteria), the patient must be one you can read. A patient is named by its Signals id, or by its Medplum Patient id where Signals takes a `refId`; ovok asks Signals which patient a Signals id is.

## Request [#request]

### Path parameters [#path-parameters]

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `patientId` | string | Yes | The Signals patient id. |

### Query parameters [#query-parameters]

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `page` | number | No | 1-based, as v1 paged. A page may start at most 10000 rows in; walk further with `cursor`. |
| `pageSize` | number | No | v1's page size; defaults to 10. Wins over `limit` when both are sent. |
| `from` | string | No | Inclusive lower bound on clinical time; a reading timed over an hour after it was stored is missed. |
| `to` | string | No | Inclusive upper bound on the reading's clinical time. |
| `code` | string | No | One LOINC code, or several separated by commas. |
| `category` | string | No | One FHIR category code, or several separated by commas; a reading carrying any of them. |
| `limit` | number | No | — |
| `cursor` | string | No | — |
| `fields` | string | No | Only these keys of each item, separated by commas (`code,valueNumber,observedAt`). Every key when absent. A chart reading a day of readings needs a few of them. |

## Responses [#responses]

| Status | Meaning |
| --- | --- |
| `200` | One page of readings. |
| `400` | A path value holds a character ovok does not send to Signals, such as a raw `:` or `+`. Percent-encode it. The query carries a raw `#`, or more than 200 parameters. |
| `401` | Your ovok access token, or your client id and secret, are missing or invalid. |
| `403` | ovok refused the call: you lack a capability this route needs, or your session has no project. From Signals: Authenticated, but the client's role does not permit this, or it is not attached to the patient. |
| `404` | A patient the call names is not one you can read. From Signals: No such patient in this tenant. |
| `409` | Your project has no Signals tenant of its own (`SIGNALS_TENANT_NOT_OWN`), or it is moving to another one. |
| `422` | A patient id is not 1 to 64 letters, digits, `.`, `_`, `~` or `-`. From Signals: A query parameter failed validation, a large page lacked `from`/`to`, or the page starts too deep. |
| `429` | Too many requests. Retry after the seconds in `Retry-After`. |
| `500` | ovok hit an unexpected fault, such as your project having no Signals submitter. |
| `502` | Signals answered with something ovok couldn't use, or refused ovok's own credential. |
| `503` | Signals is unavailable. Retry after the seconds in `Retry-After`. |
| `504` | Signals did not answer in time. |

## Example [#example]

```bash
curl --request GET 'https://api.sandbox.ovok.com/v1/signals/api/observation/:patientId' \
  --user "${OVOK_CLIENT_ID}:${OVOK_CLIENT_SECRET}"
```
