/api/v1/passports/{id}/measurementsЗаписване на измервания
**Само за паспорти на батерии** (Регламент (ЕС) 2023/1542, чл. 77, Приложение XIII, точка 4 — данни от употреба). Паспортът трябва да е публикуван; чернова или спрян паспорт връща 422 `passport_not_active`. Паспорт, който не е за батерия, връща 422 `not_a_battery`. Изпращайте 1–500 измервания на извикване, всяко като `{ fieldKey, value, measuredAt, externalId?, unit? }` — `measuredAt` е времеви печат по ISO 8601 и не трябва да е в бъдещето; `value` трябва да е най-много **16 KB след сериализация** (по-голяма стойност връща 400 `invalid_value`). Приемливите `fieldKey` са полетата за данни от употреба по Приложение XIII, точка 4: `stateOfHealth`, `stateOfCertifiedEnergy`, `remainingCapacity`, `remainingPowerCapability`, `remainingRoundTripEfficiency`, `evolutionOfSelfDischargeRate`, `currentInternalResistancePack`, `capacityFade`, `powerFade`, `internalResistanceIncrease`, `dynamicRatedCapacity`, `dynamicPowerCapability`, `dynamicInternalResistance`, `dynamicEnergyRoundTripEfficiency`, `dynamicExpectedLifetimeCycles`, `numberOfFullEquivalentChargingCycles`, `numberOfChargingEvents`, `currentStateOfCharge`, `negativeEvents`, `temperatureConditionsHistorical`.
Всяко измерване се съхранява. Най-новото по поле (по `measuredAt`) става текущата стойност на полето в паспорта и задава `dynamicDataAsOf`. По-старо измерване, пристигнало по-късно, се пази в историята, но не презаписва по-нова текуща стойност. Предоставянето на `externalId` прави измерването **идемпотентно**: повторно изпращане се отчита в `duplicates`, без да се съхранява или таксува отново. Поддържа се и заглавният параметър `Idempotency-Key` — същият ключ + същото тяло преизпълнява кеширания отговор за 24 ч.; същият ключ + различно тяло връща 422. OAuth scope: `passports:write`.
`batteryStatus` **не** е поле за измерване — промените в жизнения цикъл се извършват чрез таблото за управление. Батерия, подготвена за повторна употреба, промяна на предназначението или вторично производство, получава нов паспорт, свързан с оригиналния чрез `lineage` при създаване на паспорт. Поле, което Регламентът ограничава за дадена категория батерии, връща 422 `field_not_applicable` (напр. `stateOfCertifiedEnergy` е недостъпно за LMT батерии; петте метрики за остатъчен капацитет от Приложение VII, Част A са недостъпни за EV батерии). Алтернативна форма на адресиране е налична на `POST /api/v1/passports/by-serial/{serial}/measurements` — същото тяло, същият отговор. При несигурен сериен номер добавете `?gtin=<gtin>` за разграничаване.
Измерванията се броят спрямо **месечния** лимит на плана (`maxMeasurementsPerMonth`), а не спрямо дневния лимит за v1 записвания. Платените планове продължават да приемат и броят измервания след лимита без допълнително заплащане; Free планът спира при достигане на лимита. Преглеждането на паспорт никога не се таксува.
Параметри в пътя
- idзадължително
ObjectId
ID на паспорта.
Хедъри
- Authorizationзадължително
string
`Bearer <token>` — или `tp_` API ключ (Developer → API Keys; най-просто, за server-to-server), или OAuth 2.0 access token (Developer → OAuth Apps; за приложения, авторизирани от потребител, scoped и отзоваеми). Страницата Authentication съдържа пълния OAuth поток и списъка със scopes.
e.g. Bearer tp_REDACTED_xxxxxxxxxxxx
- Idempotency-Key
string
Незадължителен ключ за идемпотентност (UUID v4 или произволен непрозрачен низ ≤ 64 символа). Същият ключ + същото тяло преизпълнява кеширания отговор за 24 ч.; същият ключ + различно тяло връща 422.
Заявка
curl -sS -X POST \
https://app.tracepass.eu/api/v1/passports/6650b2c3d4e5f6a7b8c9d0e1/measurements \
-H "Authorization: Bearer tp_REDACTED_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"measurements": [
{
"fieldKey": "stateOfHealth",
"value": 96.4,
"measuredAt": "2027-03-01T06:00:00Z",
"externalId": "bms-7781-2027-03-01"
},
{
"fieldKey": "numberOfFullEquivalentChargingCycles",
"value": 112,
"measuredAt": "2027-03-01T06:00:00Z"
}
]
}'Отговор
{
"accepted": 2,
"storedCount": 2,
"materializedCount": 2,
"duplicates": 0,
"measurementIds": [
"6750a1b2c3d4e5f6a7b8c9d0",
"6750a1b2c3d4e5f6a7b8c9d1"
]
}