---
title: История на измерванията
description: История на измерванията за паспорт на батерия — филтриране по ключ на поле и период, странициране с cursor до 200 на страница.
canonical: "https://www.tracepass.eu/bg/docs/list-measurements"
locale: bg
source: "https://www.tracepass.eu/bg/docs/list-measurements"
---

# История на измерванията

> История на измерванията за паспорт на батерия — филтриране по ключ на поле и период, странициране с cursor до 200 на страница.

```http
GET /api/v1/passports/{id}/measurements
```

Връща пълната история на измерванията за паспорт на батерия, от най-нови към най-стари (по `measuredAt`). Всеки запис е обект `PassportMeasurement` с полета `_id`, `passportId`, `fieldKey`, `value`, `measuredAt`, `receivedAt`, `externalId?`, `unit?`, `materialized` (дали този запис е станал текуща стойност на полето в паспорта) и `source`. **Само за паспорти на батерии** — паспорт, различен от батерия, връща 422 `not_a_battery`.

Филтрирайте с `?fieldKey=<key>` за конкретно поле, `?from=<ISO 8601>` и `?to=<ISO 8601>` за ограничаване на прозореца по `measuredAt`. Размерът на страницата се управлява с `?limit` (1–200, по подразбиране 50). Страницирайте с `?cursor=<nextCursor>` — подайте стойността `nextCursor` от отговора на предишната страница точно така, както е върната; тя е непрозрачна и вътрешният й формат не трябва да се разчита. Отговорът съдържа `hasMore: true` и ненулев `nextCursor`, когато има допълнителни резултати; `hasMore: false` означава, че сте достигнали последната страница.

Алтернативна форма на адресиране е налична на `GET /api/v1/passports/by-serial/{serial}/measurements` със същите параметри и форма на отговора. При несигурен сериен номер добавете `?gtin=<gtin>` за разграничаване. Само за четене; OAuth scope: `passports:read`.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Authorization` | header | string | yes | `Bearer <token>` — или `tp_` API ключ (Developer → API Keys; най-просто, за server-to-server), или OAuth 2.0 access token (Developer → OAuth Apps; за приложения, авторизирани от потребител, scoped и отзоваеми). Страницата Authentication съдържа пълния OAuth поток и списъка със scopes. |
| `id` | path | ObjectId | yes | ID на паспорта. |
| `fieldKey` | query | string | no | Филтриране по единичен ключ на поле (напр. `stateOfHealth`). |
| `from` | query | string (ISO 8601) | no | Измервания с `measuredAt` ≥ тази стойност. |
| `to` | query | string (ISO 8601) | no | Измервания с `measuredAt` ≤ тази стойност. |
| `limit` | query | integer | no | Размер на страницата (1–200, по подразбиране 50). |
| `cursor` | query | string | no | Стойността `nextCursor` от отговора на предишната страница. Непрозрачна — подайте я непроменена; не я разбирайте или конструирайте. |

## Examples

```bash
curl -sS \
  "https://app.tracepass.eu/api/v1/passports/6650b2c3d4e5f6a7b8c9d0e1/measurements?fieldKey=stateOfHealth&limit=50" \
  -H "Authorization: Bearer tp_REDACTED_xxxxxxxxxxxx"
```

```typescript
let cursor: string | null = null;
do {
  const url = new URL(
    `https://app.tracepass.eu/api/v1/passports/${id}/measurements`,
  );
  url.searchParams.set("fieldKey", "stateOfHealth");
  url.searchParams.set("limit", "50");
  if (cursor) url.searchParams.set("cursor", cursor);

  const res = await fetch(url.toString(), {
    headers: { Authorization: `Bearer ${process.env.TRACEPASS_API_KEY}` },
  });
  const { data, hasMore, nextCursor } = await res.json();
  for (const m of data) {
    console.log(m.measuredAt, m.value, m.materialized ? "(current)" : "");
  }
  cursor = nextCursor;
} while (cursor);
```

```python
import os, requests

cursor = None
while True:
    params = {"fieldKey": "stateOfHealth", "limit": 50}
    if cursor:
        params["cursor"] = cursor
    res = requests.get(
        f"https://app.tracepass.eu/api/v1/passports/{passport_id}/measurements",
        headers={"Authorization": f"Bearer {os.environ['TRACEPASS_API_KEY']}"},
        params=params,
    )
    res.raise_for_status()
    body = res.json()
    for m in body["data"]:
        print(m["measuredAt"], m["value"], "(current)" if m["materialized"] else "")
    if not body["hasMore"]:
        break
    cursor = body["nextCursor"]
```

## Responses

### 200 — Първа страница от историята

```json
{
  "data": [
    {
      "_id": "6750a1b2c3d4e5f6a7b8c9d0",
      "passportId": "6650b2c3d4e5f6a7b8c9d0e1",
      "fieldKey": "stateOfHealth",
      "value": 96.4,
      "measuredAt": "2027-03-01T06:00:00Z",
      "receivedAt": "2027-03-01T06:01:12Z",
      "externalId": "bms-7781-2027-03-01",
      "materialized": true,
      "source": "api:tp_abc123"
    },
    {
      "_id": "6740a1b2c3d4e5f6a7b8c9d0",
      "passportId": "6650b2c3d4e5f6a7b8c9d0e1",
      "fieldKey": "stateOfHealth",
      "value": 97.1,
      "measuredAt": "2027-02-01T06:00:00Z",
      "receivedAt": "2027-02-01T06:00:55Z",
      "materialized": false,
      "source": "api:tp_abc123"
    }
  ],
  "hasMore": false,
  "nextCursor": null
}
```

### 422 — Не е паспорт на батерия

```json
{ "error": "not_a_battery" }
```

### 404 — Не е намерен

```json
{ "error": "Passport not found" }
```

## Related

- [Записване на измервания](https://www.tracepass.eu/bg/docs/capture-measurements.md)
- [Последни измервания](https://www.tracepass.eu/bg/docs/latest-measurements.md)
