GET /v1/highlights Bearer key List today's highlighted memories.
Return the memories that should be highlighted today in the user timezone (persistent, due recurring and dated memories not yet handled today), with highlight occurrence, a comment summary and a subtask summary (`subtasks: { total, done }`).
Parameters
| Name | Type | Description |
|---|
| limit | integer · query | 1–200 |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| day * | string (date) | |
| timezone * | string | |
| items * | object[] | |
| items[].ancestors | object[] | |
| items[].interaction | object | |
| items[].parent | object | |
| items[].relevance | object | null | Computed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies. |
GET /v1/notifications Bearer key List inbox notifications.
Return the notification inbox, newest first. Page with before=nextCursor.
Parameters
| Name | Type | Description |
|---|
| limit | integer · query | 1–100 |
| before | string (date-time) · query | |
| unread | "true" | "false" · query | |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| items * | object[] | |
| items[].id * | string | |
| items[].type * | string | e.g. memory.highlights.daily, memory.task.due, finance.bill.due. |
| items[].category * | "memory" | "finance" | "capture" | "account" | |
| items[].title * | string | |
| items[].body * | string | |
| items[].data * | object | Deep-link hints: screen (memory, highlights, finance, usage) and id. |
| items[].nodeId * | string | null | |
| items[].createdAt * | string (date-time) | |
| items[].readAt * | string | null (date-time) | |
| nextCursor * | string | null | |
| unread * | integer | |
GET /v1/notifications/unread Bearer key Count unread notifications.
Responses
200 Successful response.
| Name | Type | Description |
|---|
| unread * | integer | |
POST /v1/notifications/read Bearer key Mark notifications as read.
Mark notifications as read. Requires the cortex.write scope.
Request body application/json
| Name | Type | Description |
|---|
| ids * | string[] | |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| ids * | string[] | |
| unread * | integer | |
POST /v1/notifications/read-all Bearer key Mark every notification as read.
Mark every notification as read. Requires the cortex.write scope.
Responses
200 Successful response.
| Name | Type | Description |
|---|
| ids * | string[] | |
| unread * | integer | |
POST /v1/notifications/archive Bearer key Remove notifications from the inbox.
Remove notifications from the inbox. Requires the cortex.write scope.
Request body application/json
| Name | Type | Description |
|---|
| ids * | string[] | |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| ids * | string[] | |
| unread * | integer | |
GET /v1/notifications/preferences Bearer key Get notification preferences.
Responses
200 Successful response.
| Name | Type | Description |
|---|
| categories | object | Per category ({memory, finance, capture, account}) channel switches. |
| digest | object | |
| digest.enabled | boolean | |
| digest.time | string | |
| quietHours | object | |
| quietHours.enabled | boolean | |
| quietHours.start | string | |
| quietHours.end | string | |
| preview | "title" | "full" | title keeps the memory content off the lock screen. |
PATCH /v1/notifications/preferences Bearer key Update notification preferences.
Partial merge of the preferences. Requires the cortex.write scope.
Request body application/json
| Name | Type | Description |
|---|
| categories | object | Per category ({memory, finance, capture, account}) channel switches. |
| digest | object | |
| digest.enabled | boolean | |
| digest.time | string | |
| quietHours | object | |
| quietHours.enabled | boolean | |
| quietHours.start | string | |
| quietHours.end | string | |
| preview | "title" | "full" | title keeps the memory content off the lock screen. |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| categories | object | Per category ({memory, finance, capture, account}) channel switches. |
| digest | object | |
| digest.enabled | boolean | |
| digest.time | string | |
| quietHours | object | |
| quietHours.enabled | boolean | |
| quietHours.start | string | |
| quietHours.end | string | |
| preview | "title" | "full" | title keeps the memory content off the lock screen. |
GET /v1/notifications/push Bearer key Which push providers are configured on the server.
Responses
200 Successful response.
| Name | Type | Description |
|---|
| fcm * | boolean | |
| webpush * | boolean | |
| vapidPublicKey * | string | null | |
PUT /v1/notifications/push Bearer key Register this device for push.
fcm needs pushToken (the Firebase registration token); webpush needs the browser subscription. With a device token the target is removed when the device is revoked. Requires the cortex.write scope.
Request body application/json
| Name | Type | Description |
|---|
| provider * | "fcm" | "webpush" | |
| pushToken | string | 0–4096 chars |
| subscription | object | |
| platform | string | e.g. android, ios, web. |
Responses
DELETE /v1/notifications/push Bearer key Stop push to a token or endpoint.
Requires the cortex.write scope.
Request body application/json
| Name | Type | Description |
|---|
| pushToken | string | |
| endpoint | string | |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| removed * | boolean | |
POST /v1/notifications/test Bearer key Send a test notification.
Create a test notification in the inbox and push it. Requires the cortex.write scope.
Responses
GET /v1/consolidation Bearer key Get the daily consolidation.
Return the consolidation brief and conversation turns. Requires the Subscription plan.
Parameters
| Name | Type | Description |
|---|
| day | string (date) · query | |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| day * | string (date) | |
| status * | "ready" | "running" | "failed" | "none" | |
| brief * | object | null | Daily brief with generatedAt, summary, sections and questions. |
| brief.day | string (date) | |
| brief.generatedAt | string (date-time) | |
| brief.summary | string | |
| brief.sections | object[] | |
| brief.questions | object[] | |
| turns * | object[] | |
| turns[].id * | string | |
| turns[].day * | string (date) | |
| turns[].createdAt * | string (date-time) | |
| turns[].transcript * | string | |
| turns[].reply * | string | |
| turns[].warning | string | |
| turns[].actions * | object[] | |
402 The account needs the Subscription plan.
| Name | Type | Description |
|---|
| error * | "subscription_required" | |
POST /v1/consolidation/run Bearer key Run the daily consolidation.
The operation is idempotent per day; force regenerates the consolidation. Requires the Subscription plan. Requires the cortex.write scope.
Request body application/json
| Name | Type | Description |
|---|
| force | boolean | |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| day * | string (date) | |
| status * | "ready" | "running" | "failed" | "none" | |
| brief * | object | null | Daily brief with generatedAt, summary, sections and questions. |
| brief.day | string (date) | |
| brief.generatedAt | string (date-time) | |
| brief.summary | string | |
| brief.sections | object[] | |
| brief.questions | object[] | |
| turns * | object[] | |
| turns[].id * | string | |
| turns[].day * | string (date) | |
| turns[].createdAt * | string (date-time) | |
| turns[].transcript * | string | |
| turns[].reply * | string | |
| turns[].warning | string | |
| turns[].actions * | object[] | |
402 The account needs the Subscription plan.
| Name | Type | Description |
|---|
| error * | "subscription_required" | |
GET /v1/consolidation/preferences Bearer key Get consolidation preferences.
Return the daily consolidation schedule. Requires the Subscription plan.
Responses
200 Successful response.
| Name | Type | Description |
|---|
| enabled * | boolean | |
| time * | string | |
| digestTime * | string | |
402 The account needs the Subscription plan.
| Name | Type | Description |
|---|
| error * | "subscription_required" | |
PATCH /v1/consolidation/preferences Bearer key Update consolidation preferences.
Merge the supplied schedule preferences. Requires the Subscription plan. Requires the cortex.write scope.
Request body application/json
| Name | Type | Description |
|---|
| enabled | boolean | |
| time | string | |
| digestTime | string | |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| enabled * | boolean | |
| time * | string | |
| digestTime * | string | |
402 The account needs the Subscription plan.
| Name | Type | Description |
|---|
| error * | "subscription_required" | |
POST /v1/consolidation/chat Bearer key Add a turn to the consolidation conversation.
Send text or audio to discuss the daily brief. Requires the Subscription plan. Requires the cortex.write scope.
Request body application/json
Responses
200 Successful response.
| Name | Type | Description |
|---|
| id * | string | |
| day * | string (date) | |
| createdAt * | string (date-time) | |
| transcript * | string | |
| reply * | string | |
| warning | string | |
| actions * | object[] | |
| actions[].id * | string | |
| actions[].type * | string | |
| actions[].status * | "applied" | "failed" | "undone" | |
| actions[].summary * | string | |
| actions[].nodeId * | string | null | |
| actions[].undoable * | boolean | |
402 The account needs the Subscription plan.
| Name | Type | Description |
|---|
| error * | "subscription_required" | |
POST /v1/consolidation/undo Bearer key Undo a consolidation action.
Undo a reversible action from a conversation turn. Requires the Subscription plan. Requires the cortex.write scope.
Request body application/json
| Name | Type | Description |
|---|
| actionId * | string | |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| action * | object | |
| action.id * | string | |
| action.type * | string | |
| action.status * | "applied" | "failed" | "undone" | |
| action.summary * | string | |
| action.nodeId * | string | null | |
| action.undoable * | boolean | |
402 The account needs the Subscription plan.
| Name | Type | Description |
|---|
| error * | "subscription_required" | |
POST /v1/uploads/known Bearer key Check known upload hashes.
Return which hashes the user already stored, with their nodeId, so the client can skip re-uploading. Requires the cortex.write scope.
Request body application/json
| Name | Type | Description |
|---|
| hashes * | string[] | |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| known * | object[] | |
| known[].sha256 * | string | |
| known[].nodeId * | string | |
GET /v1/photos Bearer key List photos.
List image and video memories ordered by capture time using cursor pagination. Supply changedSince to fetch photo-grid changes since a sync token.
Parameters
| Name | Type | Description |
|---|
| limit | integer · query | 1–100, default 60 |
| cursor | string · query | 1–∞ chars |
| changedSince | string · query | Sync token from an earlier photo-list or delta response. · 1–∞ chars |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| items * | object[] | |
| items[].ancestors | object[] | |
| items[].interaction | object | |
| items[].parent | object | |
| items[].relevance | object | null | Computed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies. |
| nextCursor * | string | null | |
| syncToken * | string | null | Token to use for the next photo-grid delta sync. |
| removed | string[] | Photo node IDs to remove from the local grid in delta mode. |
| reset | boolean | True when the supplied sync token is too old and the client must reload the full grid. |
GET /v1/blobs/fetch/{requestId} Bearer key Get the status of a machine blob fetch.
Return the status of a request to restore an evicted original attachment from a machine runner.
Parameters
| Name | Type | Description |
|---|
| requestId * | string (uuid) · path | Blob fetch request UUID. |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| status * | "ready" | "pending" | "expired" | "error" | |
| url | string (uri) | |
| expiresIn | number | |
POST /v1/blobs/replicated Bearer key Check confirmed machine replicas for blob hashes.
Returns hashes that have a replica on a non-revoked machine runner.
Request body application/json
| Name | Type | Description |
|---|
| sha256s * | string[] | |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| replicated * | object[] | |
| replicated[].sha256 * | string | |
| replicated[].size * | integer | |
GET /v1/context-packs Bearer key List context packs.
List saved AI session handoff summaries (context packs), optionally filtered by platform.
Parameters
| Name | Type | Description |
|---|
| platform | string · query | Platform filter, e.g. chatgpt or claude. |
| limit | integer · query | Maximum number of packs to return. · 1–50, default 20 |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| packs * | object[] | |
| packs[].id * | string | |
| packs[].title * | string | |
| packs[].platform * | string | null | |
| packs[].url * | string (uri) | |
| packs[].savedAt * | string | null | |
POST /v1/context-packs Bearer key Save a context pack.
Save an AI session handoff summary to CortexPlus memory. Secrets in the content are replaced by placeholders before storing; the secret values are never persisted. Requires the cortex.write scope.
Request body application/json
| Name | Type | Description |
|---|
| content * | string | Handoff summary in Markdown. |
| platform * | string | AI platform that wrote the summary, e.g. chatgpt or claude. |
| key * | string | Short stable slug for the topic. Sending the same platform and key again updates the pack instead of creating another. |
| title | string | |
| model | string | |
| messageCount | integer | 0–100000 |
| tags | string[] | |
Responses
201 Successful response.
| Name | Type | Description |
|---|
| id * | string | |
| title * | string | |
| url * | string (uri) | |
| created * | boolean | |
| redactions * | object[] | |
| redactions[].kind * | string | |
| redactions[].placeholder * | string | |
| redactions[].count * | integer | |
POST /v1/context-packs/resume Bearer key Resume a context pack.
Load a saved context pack by id or by semantic query to resume work started in another AI conversation.
Request body application/json
| Name | Type | Description |
|---|
| query | string | Topic to find the pack by, in natural language. |
| id | string | Pack id, as returned by listContextPacks. |
| maxChars | integer | 500–20000, default 6000 |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| text * | string | |
| pack * | object | null | |
| pack.id | string | |
| pack.title | string | |
| pack.url | string (uri) | |
| matches * | integer | |
GET /v1/study/due Bearer key List due flashcards.
List study flashcards due for review, oldest first.
Parameters
| Name | Type | Description |
|---|
| subject | string · query | Subject name or slug (`materia:<slug>` tag) to filter by. |
| limit | integer · query | Maximum number of flashcards to return. · 1–100, default 20 |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| items * | object[] | |
| items[].ancestors | object[] | |
| items[].interaction | object | |
| items[].parent | object | |
| items[].relevance | object | null | Computed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies. |
POST /v1/study/review Bearer key Review a flashcard.
Apply an SM-2 grade to a flashcard and return it with the new schedule. Returns 404 when the card does not exist. Requires the cortex.write scope.
Request body application/json
| Name | Type | Description |
|---|
| cardId * | string | Flashcard memory id. |
| grade * | "again" | "hard" | "good" | "easy" | |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| card * | object | Full node as returned by the CortexPlus backend. |
| card.ancestors | object[] | |
| card.interaction | object | |
| card.parent | object | |
| card.relevance | object | null | Computed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies. |
POST /v1/study/quiz Bearer key Generate a quiz.
Generate a multiple-choice quiz from the study material of a subject. Nothing is stored.
Request body application/json
| Name | Type | Description |
|---|
| subject * | string | Subject name or slug. |
| count | integer | 1–10, default 5 |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| items * | object[] | |
| items[].question * | string | |
| items[].options * | string[] | |
| items[].answerIndex * | integer | |
| items[].explanation * | string | |
| items[].sourceId * | string | null | |
List modes.
List the memory modes with per-user enabled flags and the selected mode.
Responses
200 Successful response.
| Name | Type | Description |
|---|
| items * | object[] | |
| selected * | string | |
POST /v1/modes/choose Bearer key Choose the enabled modes.
Enable exactly the given modes, disable the others except `all`, and mark the first-run mode choice as done. Requires the cortex.write scope.
Request body application/json
| Name | Type | Description |
|---|
| keys * | string[] | |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| items * | object[] | |
| selected * | string | |
POST /v1/sales/brief Bearer key Prepare a sales brief.
Summarize a client’s sales memories with the open deal, last contact, and next follow-up.
Request body application/json
| Name | Type | Description |
|---|
| client * | string | Client name or slug. |
| includeClosed | boolean | Include closed opportunities. |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| summary * | string | |
| openDeal * | | |
| lastContactAt * | string | null | |
| nextFollowup * | | |
| sources * | string[] | |
| clientNode * | | |
| comments * | object[] | |
| comments[].id * | string | |
| comments[].nodeId * | string | |
| comments[].body * | string | |
| comments[].createdAt * | string (date-time) | |
| comments[].updatedAt * | string (date-time) | |
| tasks * | object[] | |
| tasks[].ancestors | object[] | |
| tasks[].interaction | object | |
| tasks[].parent | object | |
| tasks[].relevance | object | null | Computed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies. |
| contacts * | object[] | |
| contacts[].ancestors | object[] | |
| contacts[].interaction | object | |
| contacts[].parent | object | |
| contacts[].relevance | object | null | Computed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies. |
| opportunities * | object[] | |
| opportunities[].ancestors | object[] | |
| opportunities[].interaction | object | |
| opportunities[].parent | object | |
| opportunities[].relevance | object | null | Computed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies. |
GET /v1/sales/opportunities/{id} Bearer key Get an opportunity with its related sales context.
Return an opportunity, its client, contacts, comments, tasks and related sales memories.
Parameters
| Name | Type | Description |
|---|
| id * | string · path | |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| node * | object | Full node as returned by the CortexPlus backend. |
| node.ancestors | object[] | |
| node.interaction | object | |
| node.parent | object | |
| node.relevance | object | null | Computed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies. |
| client * | | |
| contacts * | object[] | |
| contacts[].ancestors | object[] | |
| contacts[].interaction | object | |
| contacts[].parent | object | |
| contacts[].relevance | object | null | Computed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies. |
| comments * | object[] | |
| comments[].id * | string | |
| comments[].nodeId * | string | |
| comments[].body * | string | |
| comments[].createdAt * | string (date-time) | |
| comments[].updatedAt * | string (date-time) | |
| tasks * | object[] | |
| tasks[].ancestors | object[] | |
| tasks[].interaction | object | |
| tasks[].parent | object | |
| tasks[].relevance | object | null | Computed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies. |
| related * | object[] | |
| related[].ancestors | object[] | |
| related[].interaction | object | |
| related[].parent | object | |
| related[].relevance | object | null | Computed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies. |
404 Successful response.
| Name | Type | Description |
|---|
| error | string | |
GET /v1/finance/month Bearer key Summarize a finance month.
Return expenses, income, spending by category against budgets, and upcoming bills for a month.
Parameters
| Name | Type | Description |
|---|
| month * | string · query | Month to summarize. |
| timezone | string · query | IANA time zone; defaults to the account setting. |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| month * | string | |
| currency * | string | |
| expenses * | number | |
| income * | number | |
| byCategory * | object[] | |
| byCategory[].category * | string | |
| byCategory[].spent * | number | |
| byCategory[].budget * | number | null | |
| upcomingBills * | object[] | |
| upcomingBills[].ancestors | object[] | |
| upcomingBills[].interaction | object | |
| upcomingBills[].parent | object | |
| upcomingBills[].relevance | object | null | Computed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies. |
GET /v1/health/summary Bearer key Summarize health data.
Health data is only returned to API keys/agents when the user enabled `settings.healthAgentAccess`; otherwise the response is `{ "error": "health data is not shared with agents" }`. Summarize latest body metrics, 180-day series, flagged lab results, recent exams, routines and last workout.
Parameters
| Name | Type | Description |
|---|
| timezone | string · query | IANA time zone; defaults to the account setting. |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| latest * | object | |
| series * | object | |
| flaggedResults * | object[] | |
| flaggedResults[].nodeId * | string | |
| flaggedResults[].date * | string | |
| flaggedResults[].key * | string | |
| flaggedResults[].name * | string | |
| flaggedResults[].value * | number | null | |
| flaggedResults[].unit * | string | null | |
| flaggedResults[].flag * | "low" | "high" | |
| recentExams * | object[] | |
| recentExams[].ancestors | object[] | |
| recentExams[].interaction | object | |
| recentExams[].parent | object | |
| recentExams[].relevance | object | null | Computed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies. |
| routines * | object[] | |
| routines[].ancestors | object[] | |
| routines[].interaction | object | |
| routines[].parent | object | |
| routines[].relevance | object | null | Computed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies. |
| lastWorkout * | | |
GET /v1/health/metric Bearer key Get a health metric series.
Health data is only returned to API keys/agents when the user enabled `settings.healthAgentAccess`; otherwise the response is `{ "error": "health data is not shared with agents" }`. Get a body metric or lab result series.
Parameters
| Name | Type | Description |
|---|
| key * | string · query | Body metric key (weightKg, heightCm, bmi, bodyFatPct, muscleMassKg, visceralFat, bodyWaterPct, boneMassKg, basalMetabolismKcal, metabolicAge) or `lab:<resultKey>`, e.g. `lab:glicose`. |
| from | string (date) · query | First date in the metric series. |
| to | string (date) · query | Last date in the metric series. |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| key * | string | |
| unit * | string | null | |
| points * | object[] | |
| points[].date * | string | |
| points[].value * | number | |
| points[].nodeId * | string | |
| points[].source * | "measurement" | "exam" | |
GET /v1/nutrition/history Bearer key Get nutrient intake history.
Nutrient intake from logged meals, aggregated by day, week or month. Weekly and monthly values are daily averages over days with meals. Health-tagged memories hidden from the credential are excluded.
Parameters
| Name | Type | Description |
|---|
| from * | string (date) · query | First local date (inclusive). |
| to * | string (date) · query | Last local date (inclusive). Up to 366 days for `day`, 1830 for `week`/`month`. |
| granularity | "day" | "week" | "month" · query | Bucket size; weeks start on Monday. · default "day" |
| timezone | string · query | IANA time zone; defaults to the account setting. |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| from * | string (date) | |
| to * | string (date) | |
| granularity * | "day" | "week" | "month" | |
| timezone * | string | |
| nutrients * | object[] | |
| nutrients[].key * | string | |
| nutrients[].unit * | string | |
| buckets * | object[] | |
| buckets[].start * | string (date) | |
| buckets[].end * | string (date) | |
| buckets[].days * | integer | Days with at least one meal. |
| buckets[].meals * | integer | |
| buckets[].average * | object | Daily average over days with meals. |
| buckets[].total * | object | Values keyed by `<nutrient>:<unit>`, e.g. `enerc:kcal`, `procnt:g`, `vitc:mg`. |
| summary * | object | |
| summary.days * | integer | Days with at least one meal. |
| summary.meals * | integer | |
| summary.average * | object | Daily average over days with meals. |
| summary.total * | object | Values keyed by `<nutrient>:<unit>`, e.g. `enerc:kcal`, `procnt:g`, `vitc:mg`. |
GET /v1/nutrition/targets Bearer key Get recommended daily intake ranges.
Only returned to API keys/agents when the user enabled `settings.healthAgentAccess`; otherwise the response is `{ "error": "health data is not shared with agents" }`. Daily ranges per nutrient from the profile (birth date, sex, activity level), the latest weight/height and the active calorie goal; generic adult references when the profile is incomplete.
Parameters
| Name | Type | Description |
|---|
| timezone | string · query | IANA time zone; defaults to the account setting. |
Responses
200 Successful response.
| Name | Type | Description |
|---|
| profile * | object | Inputs used (birthDate, age, sex, activityLevel, weightKg, heightCm, calorieGoalKcal), `missing` fields and `supportedAge`. |
| basis * | "personal" | "generic" | |
| energyKcal * | object | |
| energyKcal.value * | number | |
| energyKcal.source * | "goal" | "eer" | "dv" | |
| energyKcal.eer | number | null | |
| targets * | object[] | |
| targets[].key * | string | |
| targets[].unit * | string | |
| targets[].min * | number | null | |
| targets[].max * | number | null | |
| targets[].target * | number | null | |
| targets[].source * | string | |