REST API reference

Every endpoint of the CortexPlus REST API, generated from the published OpenAPI specification. Field descriptions come straight from the spec, in English.

Base URL and authentication

All endpoints live under https://api.cortexplus.io and accept and return JSON. Request bodies are limited to 1 MB, except audio and image uploads.

Send your key as Authorization: Bearer cortex_.... Create one in API keys. Endpoints marked no auth are used to create an account or sign in.

Authenticated request
curl -sS https://api.cortexplus.io/v1/auth/me \
  -H 'authorization: Bearer cortex_...'

Uploads, file limits, and deduplication

Check known file hashes before uploading, then create a signed upload and save the uploaded file as a memory.

POST /v1/uploads/known accepts 1–500 lowercase hexadecimal SHA-256 hashes matching ^[0-9a-f]{64}$. It returns { "known": [{ "sha256", "nodeId" }] }; hashes already in the account do not need to be uploaded again.

POST /v1/uploads accepts { "name", "contentType", "size" }. The optional size is the exact file size in bytes. The response includes key, uploadUrl, and expiresIn for the signed PUT.

If the supplied size exceeds the plan limit, the request is rejected before signing with HTTP 413 and { "error": "upload_too_large", "resource": "uploadMaxBytes", "requested", "limit" }. When you send size, the PUT must use that exact Content-Length.

The per-file limit is 500 MB on Free and 10 GB on paid plans.

POST /v1/memories accepts { "key", "sha256", "contentType", "name", "tags" }. The optional sha256 is lowercase hexadecimal and lets CortexPlus deduplicate repeated photos and videos per user. The response has "duplicate": true when the content already existed, so nothing is counted twice.

GET /v1/usage returns plan quotas, including quotas.uploadMaxBytes.

1. Check whether the file hash is already known
curl -sS https://api.cortexplus.io/v1/uploads/known \
  -H 'authorization: Bearer $CORTEX_API_KEY' \
  -H 'content-type: application/json' \
  -d '{"hashes":["'"$SHA256"'"]}'
2. Create an upload and send the file
upload=$(curl -sS https://api.cortexplus.io/v1/uploads \
  -H 'authorization: Bearer $CORTEX_API_KEY' \
  -H 'content-type: application/json' \
  -d "{\"name\":\"$FILE_NAME\",\"contentType\":\"$CONTENT_TYPE\",\"size\":$SIZE}")
KEY=$(printf '%s' "$upload" | jq -r '.key')
url=$(printf '%s' "$upload" | jq -r '.uploadUrl')
curl -sS -X PUT "$url" -H "Content-Type: $CONTENT_TYPE" --upload-file "$FILE"
3. Create the memory with its SHA-256
curl -sS https://api.cortexplus.io/v1/memories \
  -H 'authorization: Bearer $CORTEX_API_KEY' \
  -H 'content-type: application/json' \
  -d "{\"key\":\"$KEY\",\"sha256\":\"$SHA256\",\"contentType\":\"$CONTENT_TYPE\",\"name\":\"$FILE_NAME\",\"tags\":[]}"

Account and sign-in

POST /v1/signup No auth

Create a CortexPlus account.

Create an account or begin signing in. CortexPlus sends a 6-digit code by email; use the connect operation with that code and the email next.

Request body application/json

NameTypeDescription
email *string (email)Email address for the CortexPlus account.
name string
client stringName of the AI platform requesting the connection.

Responses

202 Successful response.

NameTypeDescription
sent *boolean
POST /v1/connect No auth

Connect a CortexPlus account.

Redeem the 6-digit code received by email. Save the returned apiKey in the connector configuration.

Request body application/json

NameTypeDescription
email *string (email)Email the code was sent to.
key *string6-digit code received by email.
client stringName of the AI platform requesting the connection.

Responses

200 Successful response.

NameTypeDescription
apiKey *string
email *string
name *string
POST /v1/auth/register No auth

Register an account.

Create a CortexPlus account. A 6-digit code is emailed and the account stays pending (202) until it is confirmed with /v1/auth/verify. When verification is disabled the response is a device session (201).

Request body application/json

NameTypeDescription
email *string (email)
name string
password *string8–∞ chars
deviceName string
platform string

Responses

201 Successful response.

NameTypeDescription
deviceToken *stringDevice credential (cxd_…); use it as the bearer token.
user *object

202 Successful response.

NameTypeDescription
verificationRequired *true
email *string
POST /v1/auth/login No auth

Log in and start a device session.

Log in with email and password and issue a device token for this app install.

Request body application/json

NameTypeDescription
email *string (email)
password *string
deviceName string
platform string

Responses

200 Successful response.

NameTypeDescription
deviceToken *stringDevice credential (cxd_…); use it as the bearer token.
user *object

403 Request failed.

NameTypeDescription
error *string
field string
POST /v1/auth/verify No auth

Confirm the signup email and start a device session.

Confirm the email with the 6-digit code sent at signup and issue a device token for this app install.

Request body application/json

NameTypeDescription
email *string (email)
code *string6-digit code received by email.
deviceName string
platform string

Responses

200 Successful response.

NameTypeDescription
deviceToken *stringDevice credential (cxd_…); use it as the bearer token.
user *object
POST /v1/auth/verify/resend No auth

Send a new signup verification code.

Email a new verification code to a pending account. Requires the signup password.

Request body application/json

NameTypeDescription
email *string (email)
password *stringPassword chosen at signup.

Responses

202 Successful response.

NameTypeDescription
sent *boolean
POST /v1/auth/key No auth

Request an email sign-in code.

Send a 6-digit sign-in code to the account email address.

Request body application/json

NameTypeDescription
email *string (email)

Responses

202 Successful response.

NameTypeDescription
sent *boolean
expiresInMinutes *integer
POST /v1/auth/key/redeem No auth

Redeem an email sign-in code.

Redeem the 6-digit code received by email (with the same email) and issue a device token for this app install.

Request body application/json

NameTypeDescription
email *string (email)Email the code was sent to.
key *string6-digit code received by email.
deviceName string
platform string

Responses

200 Successful response.

NameTypeDescription
deviceToken *stringDevice credential (cxd_…); use it as the bearer token.
user *object
GET /v1/auth/me Bearer key

Get the current account.

Return the account behind the presented credential.

Responses

200 Successful response.

PATCH /v1/auth/me Bearer key

Update the current account profile.

Update the account display name and/or language, timezone, geolocation and health agent access settings.

Request body application/json

NameTypeDescription
name string1–100 chars
settings object
settings.language "pt-BR" | "en" | "es"
settings.timezone string1–∞ chars
settings.geolocation booleanRecord location sent with memory captures. · default true
settings.healthAgentAccess booleanShare health (`saude`) memories with AI assistants using API keys (MCP and integrations). · default false
settings.birthDate string | null (date)Birth date used for nutrition intake ranges; `null` clears it.
settings.sex "male" | "female" | nullBiological sex used for nutrition intake ranges; `null` clears it.
settings.activityLevel "sedentary" | "light" | "moderate" | "active" | nullPhysical activity level used for the estimated energy requirement.

Responses

200 Successful response.

DELETE /v1/auth/me Bearer key

Delete the current account.

Permanently delete the account and all associated data.

Request body application/json

NameTypeDescription
email *string

Responses

204 Account deleted.

POST /v1/auth/password Bearer key

Set or change the account password.

Set a password on a passwordless account, or change it when currentPassword is provided. Other device tokens are revoked.

Request body application/json

NameTypeDescription
newPassword *string8–∞ chars
currentPassword stringRequired when the account already has a password.

Responses

204 Password updated.

GET /v1/auth/devices Bearer key

List devices.

List the account’s active device tokens.

Responses

200 Successful response.

NameTypeDescription
items *object[]
currentDeviceId *string | nullId of the calling device when authenticated with a device token.
DELETE /v1/auth/devices/{id} Bearer key

Revoke a device.

Revoke a device token. Use the id current to revoke the device making this call (sign out).

Parameters

NameTypeDescription
id *string · pathDevice id, or the literal current.

Responses

204 Device revoked.

Memories

POST /v1/search Bearer key

Search memory.

Search the user’s CortexPlus memory.

Request body application/json

NameTypeDescription
query *stringText to search for in memory.
limit integer1–50, default 10

Responses

200 Successful response.

NameTypeDescription
results *object[]
results[].id *string
results[].title *string
results[].url *string (uri)
results[].text string
POST /v1/recall Bearer key

Recall context.

Build context from the user’s CortexPlus memory.

Request body application/json

NameTypeDescription
query *stringQuestion to answer from memory.
limit integer1–50, default 10
depth integer0–3, default 1
maxChars integer500–20000, default 6000

Responses

200 Successful response.

NameTypeDescription
text *string
matches *integer
GET /v1/memories/{id} Bearer key

Get a memory.

Retrieve one CortexPlus memory by id. With view=node the full node is returned, as the app routes return it.

Parameters

NameTypeDescription
id *string · pathMemory id.
view "node" · query

Responses

200 Successful response.

PATCH /v1/memories/{id} Bearer key

Update a memory.

Update a memory and return the full node.

Parameters

NameTypeDescription
id *string · pathMemory id.

Request body application/json

NameTypeDescription
title string
content string
type string
tags string[]
attributes object
parentId string | nullParent memory id; null detaches the memory. Cycles are rejected.

Responses

200 Successful response.

NameTypeDescription
ancestors object[]
ancestors[].id *string
ancestors[].title *string
ancestors[].type *string
ancestors[].tags *string[]
interaction object
interaction.lastAt *string | null (date-time)
interaction.days *integer | null
interaction.answered *boolean
parent object
parent.id *string
parent.title *string
parent.type *string
parent.tags *string[]
relevance object | nullComputed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies.
relevance.score integer0–100
relevance.level "low" | "normal" | "high" | "critical"
relevance.reasons string[]
relevance.snoozedUntil string | null (date)
relevance.aiDelta integer-20–20
DELETE /v1/memories/{id} Bearer key

Delete a memory.

Delete one CortexPlus memory by id.

Parameters

NameTypeDescription
id *string · pathMemory id.

Responses

204 Memory deleted.

GET /v1/memories/{id}/ancestors Bearer key

List parent memories.

Return the chain of parent memories, from the root down to the direct parent.

Parameters

NameTypeDescription
id *string · pathMemory id.

Responses

200 Successful response.

NameTypeDescription
items *object[]
items[].ancestors object[]
items[].interaction object
items[].parent object
items[].relevance object | nullComputed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies.
limit integer
offset integer
removed string[]
nextCursor string | null
syncToken string | null
reset boolean
GET /v1/memories/{id}/descendants Bearer key

List nested memories.

Return every memory nested under this one, breadth-first. Each item has depth (1 = direct child).

Parameters

NameTypeDescription
id *string · pathMemory id.
maxDepth integer · query≥ 1
limit integer · query1–2000, default 500

Responses

200 Successful response.

NameTypeDescription
items *object[]
items[].ancestors object[]
items[].interaction object
items[].parent object
items[].relevance object | nullComputed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies.
truncated *boolean
PUT /v1/memories/{id}/horizon Bearer key

Set the memory horizon.

Set how the memory is highlighted or expires. Requires the cortex.write scope.

Parameters

NameTypeDescription
id *string · pathMemory id.

Request body application/json

NameTypeDescription
kind *"persistent" | "recurring" | "dated" | "short"persistent: highlighted every day; recurring: highlighted every interval; dated: highlighted from date on; short: archived after days.
interval "daily" | "weekly" | "biweekly"Required when kind is recurring.
date string (date)Required when kind is dated (YYYY-MM-DD).
days integerShort-term lifetime; defaults to 7. · 1–365
notify booleanSend an own reminder (not for short). Without time it fires at 09:00 in the user timezone.
time stringReminder time (HH:MM) in the user timezone.

Responses

200 Successful response.

NameTypeDescription
ancestors object[]
ancestors[].id *string
ancestors[].title *string
ancestors[].type *string
ancestors[].tags *string[]
interaction object
interaction.lastAt *string | null (date-time)
interaction.days *integer | null
interaction.answered *boolean
parent object
parent.id *string
parent.title *string
parent.type *string
parent.tags *string[]
relevance object | nullComputed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies.
relevance.score integer0–100
relevance.level "low" | "normal" | "high" | "critical"
relevance.reasons string[]
relevance.snoozedUntil string | null (date)
relevance.aiDelta integer-20–20
DELETE /v1/memories/{id}/horizon Bearer key

Remove the memory horizon.

Stop highlighting the memory. Requires the cortex.write scope.

Parameters

NameTypeDescription
id *string · pathMemory id.

Responses

200 Successful response.

NameTypeDescription
ancestors object[]
ancestors[].id *string
ancestors[].title *string
ancestors[].type *string
ancestors[].tags *string[]
interaction object
interaction.lastAt *string | null (date-time)
interaction.days *integer | null
interaction.answered *boolean
parent object
parent.id *string
parent.title *string
parent.type *string
parent.tags *string[]
relevance object | nullComputed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies.
relevance.score integer0–100
relevance.level "low" | "normal" | "high" | "critical"
relevance.reasons string[]
relevance.snoozedUntil string | null (date)
relevance.aiDelta integer-20–20
POST /v1/memories/{id}/ack Bearer key

Mark a highlight as handled today.

Hide the memory from highlights until its next occurrence. Requires the cortex.write scope.

Parameters

NameTypeDescription
id *string · pathMemory id.

Responses

200 Successful response.

NameTypeDescription
ancestors object[]
ancestors[].id *string
ancestors[].title *string
ancestors[].type *string
ancestors[].tags *string[]
interaction object
interaction.lastAt *string | null (date-time)
interaction.days *integer | null
interaction.answered *boolean
parent object
parent.id *string
parent.title *string
parent.type *string
parent.tags *string[]
relevance object | nullComputed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies.
relevance.score integer0–100
relevance.level "low" | "normal" | "high" | "critical"
relevance.reasons string[]
relevance.snoozedUntil string | null (date)
relevance.aiDelta integer-20–20
POST /v1/memories/{id}/complete Bearer key

Complete a memory.

Mark the memory as done and archive it. With `cascade: true`, every open subtask (descendant of type task) is completed too. Requires the cortex.write scope.

Parameters

NameTypeDescription
id *string · pathMemory id.

Request body application/json

NameTypeDescription
cascade boolean

Responses

200 Successful response.

NameTypeDescription
ancestors object[]
ancestors[].id *string
ancestors[].title *string
ancestors[].type *string
ancestors[].tags *string[]
interaction object
interaction.lastAt *string | null (date-time)
interaction.days *integer | null
interaction.answered *boolean
parent object
parent.id *string
parent.title *string
parent.type *string
parent.tags *string[]
relevance object | nullComputed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies.
relevance.score integer0–100
relevance.level "low" | "normal" | "high" | "critical"
relevance.reasons string[]
relevance.snoozedUntil string | null (date)
relevance.aiDelta integer-20–20
POST /v1/memories/{id}/reopen Bearer key

Reopen a memory.

Undo completion and bring the memory back from the archive. Requires the cortex.write scope.

Parameters

NameTypeDescription
id *string · pathMemory id.

Responses

200 Successful response.

NameTypeDescription
ancestors object[]
ancestors[].id *string
ancestors[].title *string
ancestors[].type *string
ancestors[].tags *string[]
interaction object
interaction.lastAt *string | null (date-time)
interaction.days *integer | null
interaction.answered *boolean
parent object
parent.id *string
parent.title *string
parent.type *string
parent.tags *string[]
relevance object | nullComputed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies.
relevance.score integer0–100
relevance.level "low" | "normal" | "high" | "critical"
relevance.reasons string[]
relevance.snoozedUntil string | null (date)
relevance.aiDelta integer-20–20
POST /v1/memories/{id}/archive Bearer key

Archive a memory.

Hide the memory from default listings and highlights. Requires the cortex.write scope.

Parameters

NameTypeDescription
id *string · pathMemory id.

Responses

200 Successful response.

NameTypeDescription
ancestors object[]
ancestors[].id *string
ancestors[].title *string
ancestors[].type *string
ancestors[].tags *string[]
interaction object
interaction.lastAt *string | null (date-time)
interaction.days *integer | null
interaction.answered *boolean
parent object
parent.id *string
parent.title *string
parent.type *string
parent.tags *string[]
relevance object | nullComputed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies.
relevance.score integer0–100
relevance.level "low" | "normal" | "high" | "critical"
relevance.reasons string[]
relevance.snoozedUntil string | null (date)
relevance.aiDelta integer-20–20
POST /v1/memories/{id}/unarchive Bearer key

Unarchive a memory.

Bring an archived memory back to default listings. Requires the cortex.write scope.

Parameters

NameTypeDescription
id *string · pathMemory id.

Responses

200 Successful response.

NameTypeDescription
ancestors object[]
ancestors[].id *string
ancestors[].title *string
ancestors[].type *string
ancestors[].tags *string[]
interaction object
interaction.lastAt *string | null (date-time)
interaction.days *integer | null
interaction.answered *boolean
parent object
parent.id *string
parent.title *string
parent.type *string
parent.tags *string[]
relevance object | nullComputed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies.
relevance.score integer0–100
relevance.level "low" | "normal" | "high" | "critical"
relevance.reasons string[]
relevance.snoozedUntil string | null (date)
relevance.aiDelta integer-20–20
GET /v1/memories/{id}/comments Bearer key

List memory comments.

Return the dated comments of a memory, newest first.

Parameters

NameTypeDescription
id *string · pathMemory id.
limit integer · query1–200, default 200
before string (date-time) · queryOnly comments created before this ISO time (pagination cursor).

Responses

200 Successful response.

NameTypeDescription
items *object[]
items[].id *string
items[].nodeId *string
items[].body *string
items[].createdAt *string (date-time)
items[].updatedAt string (date-time)
POST /v1/memories/{id}/comments Bearer key

Comment on a memory.

Add a dated comment; it also marks the highlight as handled today. Requires the cortex.write scope.

Parameters

NameTypeDescription
id *string · pathMemory id.

Request body application/json

NameTypeDescription
body *string1–5000 chars

Responses

201 Successful response.

NameTypeDescription
id *string
nodeId *string
body *string
createdAt *string (date-time)
updatedAt string (date-time)
GET /v1/memories/{id}/attachment Bearer key

Get a download URL for a memory's attachment.

Return a short-lived download URL for the memory attachment. The URL expires after expiresIn seconds. Returns 404 when the memory has no stored attachment.

Parameters

NameTypeDescription
id *string · pathMemory id.
variant "thumb" | "original" · queryReturn a thumbnail URL when available, otherwise the original attachment URL. · default "original"

Responses

200 Successful response.

NameTypeDescription
url *string (uri)
expiresIn *number
DELETE /v1/memories/{id}/photo Bearer key

Delete a memory photo.

Remove the attachment from the memory and delete its stored photo. Meals and notes are preserved. Requires the cortex.write scope.

Parameters

NameTypeDescription
id *string · pathMemory id.

Responses

200 Successful response.

POST /v1/memories/{id}/nutrition/retry Bearer key

Recalculate a meal's nutrient estimate.

Re-run the nutrition estimate for a meal memory with an optional replacement description, and return the updated node. Requires the cortex.write scope.

Parameters

NameTypeDescription
id *string · pathMemory id.

Request body application/json

NameTypeDescription
description string0–2000 chars

Responses

200 Successful response.

NameTypeDescription
node *objectFull node as returned by the CortexPlus backend.
node.ancestors object[]
node.interaction object
node.parent object
node.relevance object | nullComputed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies.
POST /v1/memories/{id}/repeat Bearer key

Register a meal again today.

Copy a ready meal to today without its attachment. Requires the cortex.write scope.

Parameters

NameTypeDescription
id *string · pathMemory id.

Request body application/json

NameTypeDescription
clientId string0–200 chars

Responses

200 Successful response.

NameTypeDescription
node *objectFull node as returned by the CortexPlus backend.
node.ancestors object[]
node.interaction object
node.parent object
node.relevance object | nullComputed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies.
duplicate *boolean
POST /v1/memories/{id}/nutrition/adjust Bearer key

Adjust a meal's nutrient estimate.

Recalculate a meal memory using a nutrition-label photo or a named product, and return the updated node. Requires the cortex.write scope.

Parameters

NameTypeDescription
id *string · pathMemory id.

Request body application/json

Responses

200 Successful response.

NameTypeDescription
node *objectFull node as returned by the CortexPlus backend.
node.ancestors object[]
node.interaction object
node.parent object
node.relevance object | nullComputed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies.
POST /v1/remember Bearer key

Remember a note.

Store a note in the user’s CortexPlus memory.

Request body application/json

NameTypeDescription
content *stringNote content to store.
title string
tags string[]
type stringdefault "note"
attributes objectAdditional node attributes.
parentId stringId of an existing memory to nest this note under.

Responses

201 Successful response.

NameTypeDescription
id *string
title string
POST /v1/uploads Bearer key

Create an audio, photo, or video upload.

Create a signed upload URL for an audio, photo, or video memory.

Request body application/json

NameTypeDescription
name *stringName of the audio file.
contentType *stringMIME type of the audio file.
size integerExact file size in bytes. When sent, oversized files are rejected before signing and the PUT must send this exact Content-Length. · ≥ 1
expiresIn integerPresigned URL lifetime in seconds. · 60–86400

Responses

200 Successful response.

NameTypeDescription
key *string
uploadUrl *string (uri)
expiresIn *integer
GET /v1/memories Bearer key

List memories.

List the account’s memories ordered by last update, or search them semantically with q. Supply changedSince to fetch memory changes since a sync token. Returns full nodes.

Parameters

NameTypeDescription
limit integer · query1–100, default 30
offset integer · queryNonzero offsets cannot be combined with changedSince. · ≥ 0, default 0
changedSince string · querySync token from an earlier memories list or delta response; cannot be combined with q. · 1–∞ chars
cursor string · queryDelta pagination cursor; only valid with changedSince. · 1–∞ chars
type string · query
tag string[] · queryRepeatable tag filter.
client string · query
excludePhotos boolean · queryHide image and video notes from generic memory lists.
q string · querySemantic search query.
mode "semantic" | "text" · querydefault "semantic"
parentId string · queryOnly direct children of this memory id; `root` returns only memories without a parent.
archived "false" | "true" | "all" · queryArchived memories (completed tasks, expired short-term memories) are hidden by default; `true` lists only them and `all` lists both. Ignored when q is set. · default "false"

Responses

200 Successful response.

NameTypeDescription
items *object[]
items[].ancestors object[]
items[].interaction object
items[].parent object
items[].relevance object | nullComputed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies.
limit integer
offset integer
removed string[]
nextCursor string | null
syncToken string | null
reset boolean
POST /v1/memories Bearer key

Save a memory.

Classify and save text from a note, task, or reminder, or ingest photos and videos by storage key. Binary audio is sent to storage and transcribed asynchronously; binary images are described and OCRed asynchronously.

Parameters

NameTypeDescription
Idempotency-Key string · headerClient-generated idempotency key; overrides clientId in the request body or query. · 8–100 chars
clientId string · queryClient id fallback for JSON or binary captures; body clientId takes precedence for JSON, and Idempotency-Key takes precedence over both. · 8–100 chars
capturedAt string (date-time) · queryISO capture time fallback for JSON or binary captures; body capturedAt takes precedence for JSON.
capturedAtSource "clock" | "exif" | "takeout" | "file" | "user" · queryCapture date source for JSON or binary captures; body capturedAtSource takes precedence for JSON.
auto "0" | "1" | "true" | "false" · queryBinary uploads: set to 1 to classify by content (meal, task, reminder, note) instead of mode.
lat number · queryCapture latitude for binary uploads; requires lon. · -90–90
lon number · queryCapture longitude for binary uploads; requires lat. · -180–180
accuracy number · queryOptional capture accuracy in meters for binary uploads. · ≥ 0

Request body application/json, audio/*, image/*

Option 1

NameTypeDescription
text *stringText to classify and save.
tags string[]
via string
location objectCapture coordinates recorded in attributes.location. The backend discards the value when the account geolocation setting is off.
location.lat *number-90–90
location.lon *number-180–180
location.accuracy number≥ 0
location.capturedAt string (date-time)
clientId string8–100 chars
capturedAt string (date-time)
capturedAtSource "clock" | "exif" | "takeout" | "file" | "user"
auto booleanClassify by content instead of mode: detects meals, tasks, reminders and notes and may create several linked memories.

Option 2

NameTypeDescription
key *stringR2 object key from createUpload.
sha256 stringOptional lowercase hex SHA-256 of the uploaded file; lets CortexPlus deduplicate repeated photos/videos per user.
durationSeconds number≥ 0
contentType stringaudio/*, image/* or video/* MIME type; video is ingested only by key, never as a binary body.
note stringOptional text explaining what a photo contains (used by the meal estimate). · 0–2000 chars
noteAudioKey stringOptional R2 key of an audio (from createUpload) explaining the photo; it is transcribed and used with note.
noteAudioSeconds numberDuration of the noteAudioKey audio. · ≥ 0
name string
tags string[]
via string
location objectCapture coordinates recorded in attributes.location. The backend discards the value when the account geolocation setting is off.
location.lat *number-90–90
location.lon *number-180–180
location.accuracy number≥ 0
location.capturedAt string (date-time)
clientId string8–100 chars
capturedAt string (date-time)
capturedAtSource "clock" | "exif" | "takeout" | "file" | "user"
auto booleanClassify by content instead of mode: detects meals, tasks, reminders and notes and may create several linked memories.

Option 3

NameTypeDescription
audioBase64 *stringBase64-encoded audio file, up to 25 MB after decoding.
contentType stringAudio MIME type.
name string
durationSeconds number≥ 0
tags string[]
via string
location objectCapture coordinates recorded in attributes.location. The backend discards the value when the account geolocation setting is off.
location.lat *number-90–90
location.lon *number-180–180
location.accuracy number≥ 0
location.capturedAt string (date-time)
clientId string8–100 chars
capturedAt string (date-time)
capturedAtSource "clock" | "exif" | "takeout" | "file" | "user"
auto booleanClassify by content instead of mode: detects meals, tasks, reminders and notes and may create several linked memories.

Responses

201 Successful response.

NameTypeDescription
id *string
clientId *string | null
duplicate *boolean
type *string
title *string
client *string | null
status *string | null
memory *string | null
review *string | null
resolved *boolean | null
url *string (uri)
GET /v1/tasks Bearer key

List tasks.

List open tasks and reminders from CortexPlus.

Parameters

NameTypeDescription
status string · queryTask status to filter by. · default "open"
client string · queryClient name or slug to filter by.
limit integer · queryMaximum number of tasks to return. · 1–50, default 20

Responses

200 Successful response.

NameTypeDescription
tasks *object[]
tasks[].id *string
tasks[].title *string
tasks[].client *string | null
tasks[].status *string | null
tasks[].dueAt *string | null
tasks[].url *string (uri)

API keys and usage

GET /v1/apikeys Bearer key

List API keys.

List the account’s API keys.

Responses

200 Successful response.

NameTypeDescription
items *object[]
POST /v1/apikeys Bearer key

Create an API key.

Create an API key. The plaintext key is returned only in this response.

Request body application/json

NameTypeDescription
label *string

Responses

201 Successful response.

DELETE /v1/apikeys/{id} Bearer key

Revoke an API key.

Revoke one API key by id.

Parameters

NameTypeDescription
id *string · pathAPI key id.

Responses

204 API key revoked.

GET /v1/usage Bearer key

Get usage summary.

Return the account’s usage counters and plan quotas.

Responses

200 Successful response.

Other endpoints

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

NameTypeDescription
limit integer · query1–200

Responses

200 Successful response.

NameTypeDescription
day *string (date)
timezone *string
items *object[]
items[].ancestors object[]
items[].interaction object
items[].parent object
items[].relevance object | nullComputed 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

NameTypeDescription
limit integer · query1–100
before string (date-time) · query
unread "true" | "false" · query

Responses

200 Successful response.

NameTypeDescription
items *object[]
items[].id *string
items[].type *stringe.g. memory.highlights.daily, memory.task.due, finance.bill.due.
items[].category *"memory" | "finance" | "capture" | "account"
items[].title *string
items[].body *string
items[].data *objectDeep-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.

NameTypeDescription
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

NameTypeDescription
ids *string[]

Responses

200 Successful response.

NameTypeDescription
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.

NameTypeDescription
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

NameTypeDescription
ids *string[]

Responses

200 Successful response.

NameTypeDescription
ids *string[]
unread *integer
GET /v1/notifications/preferences Bearer key

Get notification preferences.

Responses

200 Successful response.

NameTypeDescription
categories objectPer 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

NameTypeDescription
categories objectPer 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.

NameTypeDescription
categories objectPer 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.

NameTypeDescription
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

NameTypeDescription
provider *"fcm" | "webpush"
pushToken string0–4096 chars
subscription object
platform stringe.g. android, ios, web.

Responses

200 Successful response.

DELETE /v1/notifications/push Bearer key

Stop push to a token or endpoint.

Requires the cortex.write scope.

Request body application/json

NameTypeDescription
pushToken string
endpoint string

Responses

200 Successful response.

NameTypeDescription
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

200 Successful response.

GET /v1/consolidation Bearer key

Get the daily consolidation.

Return the consolidation brief and conversation turns. Requires the Subscription plan.

Parameters

NameTypeDescription
day string (date) · query

Responses

200 Successful response.

NameTypeDescription
day *string (date)
status *"ready" | "running" | "failed" | "none"
brief *object | nullDaily 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.

NameTypeDescription
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

NameTypeDescription
force boolean

Responses

200 Successful response.

NameTypeDescription
day *string (date)
status *"ready" | "running" | "failed" | "none"
brief *object | nullDaily 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.

NameTypeDescription
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.

NameTypeDescription
enabled *boolean
time *string
digestTime *string

402 The account needs the Subscription plan.

NameTypeDescription
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

NameTypeDescription
enabled boolean
time string
digestTime string

Responses

200 Successful response.

NameTypeDescription
enabled *boolean
time *string
digestTime *string

402 The account needs the Subscription plan.

NameTypeDescription
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.

NameTypeDescription
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.

NameTypeDescription
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

NameTypeDescription
actionId *string

Responses

200 Successful response.

NameTypeDescription
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.

NameTypeDescription
error *"subscription_required"
PATCH /v1/comments/{id} Bearer key

Edit a comment.

Replace the comment body. Requires the cortex.write scope.

Parameters

NameTypeDescription
id *string · pathComment id.

Request body application/json

NameTypeDescription
body *string1–5000 chars

Responses

200 Successful response.

NameTypeDescription
id *string
nodeId *string
body *string
createdAt *string (date-time)
updatedAt string (date-time)
DELETE /v1/comments/{id} Bearer key

Delete a comment.

Remove the comment. Requires the cortex.write scope.

Parameters

NameTypeDescription
id *string · pathComment id.

Responses

204 Comment deleted.

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

NameTypeDescription
hashes *string[]

Responses

200 Successful response.

NameTypeDescription
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

NameTypeDescription
limit integer · query1–100, default 60
cursor string · query1–∞ chars
changedSince string · querySync token from an earlier photo-list or delta response. · 1–∞ chars

Responses

200 Successful response.

NameTypeDescription
items *object[]
items[].ancestors object[]
items[].interaction object
items[].parent object
items[].relevance object | nullComputed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies.
nextCursor *string | null
syncToken *string | nullToken to use for the next photo-grid delta sync.
removed string[]Photo node IDs to remove from the local grid in delta mode.
reset booleanTrue 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

NameTypeDescription
requestId *string (uuid) · pathBlob fetch request UUID.

Responses

200 Successful response.

NameTypeDescription
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

NameTypeDescription
sha256s *string[]

Responses

200 Successful response.

NameTypeDescription
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

NameTypeDescription
platform string · queryPlatform filter, e.g. chatgpt or claude.
limit integer · queryMaximum number of packs to return. · 1–50, default 20

Responses

200 Successful response.

NameTypeDescription
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

NameTypeDescription
content *stringHandoff summary in Markdown.
platform *stringAI platform that wrote the summary, e.g. chatgpt or claude.
key *stringShort stable slug for the topic. Sending the same platform and key again updates the pack instead of creating another.
title string
model string
messageCount integer0–100000
tags string[]

Responses

201 Successful response.

NameTypeDescription
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

NameTypeDescription
query stringTopic to find the pack by, in natural language.
id stringPack id, as returned by listContextPacks.
maxChars integer500–20000, default 6000

Responses

200 Successful response.

NameTypeDescription
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

NameTypeDescription
subject string · querySubject name or slug (`materia:<slug>` tag) to filter by.
limit integer · queryMaximum number of flashcards to return. · 1–100, default 20

Responses

200 Successful response.

NameTypeDescription
items *object[]
items[].ancestors object[]
items[].interaction object
items[].parent object
items[].relevance object | nullComputed 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

NameTypeDescription
cardId *stringFlashcard memory id.
grade *"again" | "hard" | "good" | "easy"

Responses

200 Successful response.

NameTypeDescription
card *objectFull node as returned by the CortexPlus backend.
card.ancestors object[]
card.interaction object
card.parent object
card.relevance object | nullComputed 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

NameTypeDescription
subject *stringSubject name or slug.
count integer1–10, default 5

Responses

200 Successful response.

NameTypeDescription
items *object[]
items[].question *string
items[].options *string[]
items[].answerIndex *integer
items[].explanation *string
items[].sourceId *string | null
GET /v1/modes Bearer key

List modes.

List the memory modes with per-user enabled flags and the selected mode.

Responses

200 Successful response.

NameTypeDescription
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

NameTypeDescription
keys *string[]

Responses

200 Successful response.

NameTypeDescription
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

NameTypeDescription
client *stringClient name or slug.
includeClosed booleanInclude closed opportunities.

Responses

200 Successful response.

NameTypeDescription
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 | nullComputed 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 | nullComputed 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 | nullComputed 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

NameTypeDescription
id *string · path

Responses

200 Successful response.

NameTypeDescription
node *objectFull node as returned by the CortexPlus backend.
node.ancestors object[]
node.interaction object
node.parent object
node.relevance object | nullComputed 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 | nullComputed 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 | nullComputed 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 | nullComputed relevance (not stored): score 0-100, level, reason codes. null when no scorer applies.

404 Successful response.

NameTypeDescription
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

NameTypeDescription
month *string · queryMonth to summarize.
timezone string · queryIANA time zone; defaults to the account setting.

Responses

200 Successful response.

NameTypeDescription
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 | nullComputed 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

NameTypeDescription
timezone string · queryIANA time zone; defaults to the account setting.

Responses

200 Successful response.

NameTypeDescription
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 | nullComputed 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 | nullComputed 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

NameTypeDescription
key *string · queryBody metric key (weightKg, heightCm, bmi, bodyFatPct, muscleMassKg, visceralFat, bodyWaterPct, boneMassKg, basalMetabolismKcal, metabolicAge) or `lab:<resultKey>`, e.g. `lab:glicose`.
from string (date) · queryFirst date in the metric series.
to string (date) · queryLast date in the metric series.

Responses

200 Successful response.

NameTypeDescription
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

NameTypeDescription
from *string (date) · queryFirst local date (inclusive).
to *string (date) · queryLast local date (inclusive). Up to 366 days for `day`, 1830 for `week`/`month`.
granularity "day" | "week" | "month" · queryBucket size; weeks start on Monday. · default "day"
timezone string · queryIANA time zone; defaults to the account setting.

Responses

200 Successful response.

NameTypeDescription
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 *integerDays with at least one meal.
buckets[].meals *integer
buckets[].average *objectDaily average over days with meals.
buckets[].total *objectValues keyed by `<nutrient>:<unit>`, e.g. `enerc:kcal`, `procnt:g`, `vitc:mg`.
summary *object
summary.days *integerDays with at least one meal.
summary.meals *integer
summary.average *objectDaily average over days with meals.
summary.total *objectValues 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

NameTypeDescription
timezone string · queryIANA time zone; defaults to the account setting.

Responses

200 Successful response.

NameTypeDescription
profile *objectInputs 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

When something goes wrong

Failures answer with { "error": "..." } and a matching status: 401 without a key, 403 when the key is not allowed to write, 400 when the request is malformed, 404 for an unknown item, 429 when your plan limit is reached, and 503 when memory is briefly unreachable.

Reaching a limit never blocks reading — only new indexing pauses. You can raise it in Billing or compare plans on the pricing page.