every field of the 86 objects the API returns
Objects
The 86 objects the API returns, generated from the same components.schemas that openapi.json publishes. Every field is listed, with its type, whether it can be null, its allowed values where it has a fixed set, and whether the server derives it or the encryption covers it.
How a list is shaped
Every paged list answers with the same two fields.
{ "data": [], "next_cursor": null }next_cursor is an opaque string while more pages remain and null on the last one. It is present on every paged list. One list is not paged and omits the key entirely: GET /v1/webhooks. See keeping a copy in sync for what a walk does and does not guarantee.
Two properties worth reading first
- Server-derived fields are written by the server. Sending one in a request body is validation_failed, because request bodies reject unknown fields.
- Encrypted fields are ciphertext at rest. The server holds the key for the life of your request and no longer. See encryption.
The objects
AccessKey * AccessKeyCreated * AccessKeyList * AccountExport * AnytimeView * Attachment * AttachmentList * AttachmentPlace * AttachmentPlaceRemoved * AttachmentPlaceRow * CompletedView * Container * ContainerList * DayBucket * Delivery * DeliveryList * Event * Filter * FilterList * Grant * GrantList * Heading * HeadingCompleted * HeadingConverted * HeadingDeleted * HeadingList * InboxAttached * InboxBecameNote * InboxBecameTodo * InboxItem * InboxList * InboxMoved * InboxView * LinkTitle * Me * Note * NoteExport * NoteFolder * NoteFolderList * NoteLink * NoteLinkList * NoteLinkRef * NoteList * NoteNoteLink * NoteNoteLinkList * NoteNoteLinkRef * NotePlace * NotePlaceList * NoteVersion * NoteVersionDetail * NoteVersionList * NotesView * OverviewView * PingQueued * PlannedView * Problem * RedeliveryQueued * ScheduleReminder * SearchHit * SearchResult * Session * SessionDevice * SessionList * Settings * SignOutOthersResult * SomedayView * Subtask * SubtaskPromoted * SubtaskResult * Tag * TagList * TodayView * Todo * TodoList * TrashEmptied * TrashList * TrashedContainer * TrashedFilter * TrashedNote * TrashedNoteFolder * TrashedTag * TrashedTodo * Webhook * WebhookCreated * WebhookList * WebhookRotated
AccessKey
| field | type | notes | |
|---|---|---|---|
id |
string | always present | |
name |
string | always present | may be null. encrypted. The name the user gave this credential. null when the caller holds no key to decrypt it; see name_encrypted. |
name_encrypted |
string | optional | Present ONLY when the server could not decrypt name, because a first-party app session carries no master key here, and the apps decrypt this envelope on the device. Never rendered as text: it is v1.<nonce>.<ciphertext>. |
scopes |
array of string | always present | |
createdAt |
string (RFC 3339) | always present | server-derived |
expiresAt |
string (RFC 3339) | always present | When this credential stops working. Expiry is mandatory; there is no “never”. |
lastUsedAt |
string (RFC 3339) | always present | may be null. server-derived. Server-derived, written at most once every 15 minutes per credential. null = never used. |
tokenPrefix |
string | always present | may be null. The LAST four characters of the token (the name is historical): the apps show it as itk_… ••••7xZQ, so a user can tell two keys apart. The secret itself is returned exactly once, at creation. |
AccessKeyCreated
| field | type | notes | |
|---|---|---|---|
id |
string | always present | |
name |
string | always present | may be null. encrypted. The name the user gave this credential. null when the caller holds no key to decrypt it; see name_encrypted. |
name_encrypted |
string | optional | Present ONLY when the server could not decrypt name, because a first-party app session carries no master key here, and the apps decrypt this envelope on the device. Never rendered as text: it is v1.<nonce>.<ciphertext>. |
scopes |
array of string | always present | |
createdAt |
string (RFC 3339) | always present | server-derived |
expiresAt |
string (RFC 3339) | always present | When this credential stops working. Expiry is mandatory; there is no “never”. |
lastUsedAt |
string (RFC 3339) | always present | may be null. server-derived. Server-derived, written at most once every 15 minutes per credential. null = never used. |
tokenPrefix |
string | always present | may be null |
key |
string | always present | The secret, itk_…, returned exactly once and never again. Store it now; a lost key is re-minted, not recovered. |
AccessKeyList
| field | type | notes | |
|---|---|---|---|
data |
array of AccessKey | always present | |
next_cursor |
string | always present | may be null. Opaque. Hand it back as ?cursor= for the next page; null means this was the last page. Never construct or store one; it encodes (orderKey, id) of the last row and is only meaningful against the list that issued it. |
AccountExport
| field | type | notes | |
|---|---|---|---|
format |
string | always present | |
version |
number | always present | |
exportedAt |
string (RFC 3339) | always present | When this document was made. |
userId |
string | always present | The account’s user id (the export is the user’s own document, so the raw id is in it, as in the apps’ export). |
containers |
array of object | always present | |
todos |
array of object | always present | |
headings |
array of object | optional | Only when the account has headings. |
notes |
array of object | always present | |
noteFolders |
array of object | optional | Only when the account has some. |
noteLinks |
array of object | optional | Only when the account has some. |
notePlaces |
array of object | optional | Only when the account has some. Directly after noteLinks (or the last of noteFolders / notes). |
noteNoteLinks |
array of object | optional | Only when the account has some. |
noteVersions |
array of object | optional | Only when the account has some: every version the account keeps, in full. |
inbox |
array of object | always present | |
tags |
array of object | always present | |
attachments |
array of object | always present | |
attachmentPlaces |
array of object | optional | Only when the account has some. |
filters |
array of object | always present | |
settings |
object | always present | may be null. The settings row, the platform blobs included (the export is the one place they appear). |
files |
array of object | always present | Every stored file the account references. path is always null here (no bytes in this document): fetch them from the attachment or capture that holds them. |
AnytimeView
| field | type | notes | |
|---|---|---|---|
anytime |
array of string | always present | Open, sorted, undated to-dos whose deadline (if any) is still ahead. List order: no-project first, then the tree. |
Attachment
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The attachment id. Client-supplied at create, else an uppercase UUID the server issues. |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
parentType |
string | always present | One of todo, container, note, inbox today. What the attachment hangs off. note: a note’s own attachments. Render an unknown value generically rather than fail, so do not generate a closed union from this field. |
parentId |
string | always present | The row the attachment hangs off; read parentType to know which table. |
kind |
string | always present | One of url, text, image, file today. url and text are created with POST /attachments; image and file with POST /attachments/upload (or in the apps), and their bytes come from GET /attachments/{id}/file. note was retired: a note is a row of its own, at /notes. Render an unknown value generically rather than fail, so do not generate a closed union from this field. |
url |
string | always present | may be null. encrypted. The link (kind: "url"). |
text |
string | always present | may be null. encrypted. The body (kind: "text"). |
title |
string | always present | may be null. encrypted. A heading, or the filename of an image/file. |
mime |
string | always present | may be null. encrypted. The media type of the stored bytes. |
sizeBytes |
integer | always present | may be null. min -9007199254740991, max 9007199254740991. encrypted. The byte size of the stored bytes. |
sortKey |
string | always present | Server-issued fractional ordering key. The stated order of every content list is (sortKey, id). Opaque: compare it, never compute one. |
fileId |
string | always present | may be null. server-derived. Non-null exactly when GET /attachments/{id}/file can return bytes: an image or file row whose file has been uploaded. Always null on a url or text row (a link’s stored site icon is not a file). The wrapped file key is NEVER returned; the server decrypts on your behalf instead, so a revoked grant stops being able to read the blob. |
pending |
boolean | always present | server-derived. true for an image or file attached in an app before its upload finished: the bytes are still on the device that added it, and /file answers not_found until that device uploads them and stamps the row (an attachment.updated event). Always false on url and text rows. |
tags |
array of string | always present | encrypted. Tag NAMES on the attachment. Always present; [] when there are none. A tag here is a tag like any other: renaming or deleting it in /tags rewrites it here too. |
places |
array of AttachmentPlace | always present | Everywhere the attachment is, the PRIMARY first (it is parentType / parentId), then the others oldest first. One stored file, never a copy. Add a place with POST /attachments/{id}/places, remove one with DELETE /attachments/{id}/places/{parentId}. |
AttachmentList
| field | type | notes | |
|---|---|---|---|
data |
array of Attachment | always present | |
next_cursor |
string | always present | may be null. Opaque. Hand it back as ?cursor= for the next page; null means this was the last page. Never construct or store one; it encodes (orderKey, id) of the last row and is only meaningful against the list that issued it. |
AttachmentPlace
| field | type | notes | |
|---|---|---|---|
parentType |
todo, container, note |
always present | container is an area, a project or a subproject. |
parentId |
string | always present | The to-do, container or note. |
sortKey |
string | always present | The attachment’s order INSIDE this place (each place keeps its own). |
placeId |
string | always present | may be null. The place-row id, or null for the primary place (which is the attachment row itself). |
primary |
boolean | always present | true for the first place: the one older clients show. |
AttachmentPlaceRemoved
| field | type | notes | |
|---|---|---|---|
result |
removed, inbox |
always present | removed: the attachment is still in its other places (attachment is it, after the change). inbox: that was its LAST place, so it became an inbox item holding the same file (attachment is null, inbox is the new capture). |
attachment |
Attachment | always present | may be null |
inbox |
InboxItem | always present | may be null |
AttachmentPlaceRow
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The place-row id: what an attachment_place.* webhook event names. |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
attachmentId |
string | always present | The attachment this place belongs to. |
parentType |
todo, container, note |
always present | What the place is. |
parentId |
string | always present | The to-do, container or note. |
sortKey |
string | always present | Server-issued fractional ordering key. The stated order of every content list is (sortKey, id). Opaque: compare it, never compute one. |
CompletedView
| field | type | notes | |
|---|---|---|---|
containerCompleted |
object | always present | Container id (area, project or subproject) to its done to-dos INCLUDING its descendants’, newest completion first: the completed section at the foot of a container page. Only containers with some appear. Apps show the first 10, then more. |
completedDays |
array of object | always present | Newest day first. ?from=/?to= narrow the range; ?today= sets the reference day. |
Container
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The container id. Client-supplied at create, else an uppercase UUID the server issues. |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
kind |
area, project, subproject |
always present | |
name |
string | always present | encrypted. The container name. |
parentId |
string | always present | may be null. The parent container, or null for a root area. Changed with /move, never with PATCH. |
subtitle |
string | always present | may be null. encrypted. A one-line subtitle. |
description |
string | always present | may be null. encrypted. The free text on the row itself, up to 100,000 characters. Plain text, rendered as // comment lines at the top of the container’s page. It is not a note: a note is a row of its own, at /notes. |
symbol |
string | always present | may be null. encrypted. The icon name the apps render. |
colorHex |
string | always present | may be null. encrypted. A 6-digit hex colour, with or without the leading #. |
deadline |
string (yyyy-MM-dd) | always present | may be null. yyyy-MM-dd. A hard due date. A deadline alone does not schedule the container. |
priority |
low, medium, high |
always present | may be null. Display-only; it never affects ordering or counts. |
status |
active, archived |
always present | |
sortKey |
string | always present | Server-issued fractional ordering key. The stated order of every content list is (sortKey, id). Opaque: compare it, never compute one. |
trashedAt |
string (RFC 3339) | always present | may be null. server-derived. Set by /trash, cleared by /restore; null means the row is live. |
ContainerList
| field | type | notes | |
|---|---|---|---|
data |
array of Container | always present | |
next_cursor |
string | always present | may be null. Opaque. Hand it back as ?cursor= for the next page; null means this was the last page. Never construct or store one; it encodes (orderKey, id) of the last row and is only meaningful against the list that issued it. |
DayBucket
| field | type | notes | |
|---|---|---|---|
date |
string (yyyy-MM-dd) | always present | yyyy-MM-dd. The bucket’s local calendar day. |
items |
array of string | always present | To-do ids in the bucket, in display order. |
Delivery
| field | type | notes | |
|---|---|---|---|
id |
string | always present | This ATTEMPT. A redelivery is a new id carrying the same eventId. |
eventId |
string | always present | The event. STABLE across redeliveries, so de-duplicate on this, never on id. |
event |
string | always present | The event type, e.g. todo.updated. |
status |
pending, delivered, failed |
always present | |
attempts |
integer | always present | min -9007199254740991, max 9007199254740991 |
responseStatus |
integer | always present | may be null. min -9007199254740991, max 9007199254740991. The HTTP status the subscriber answered with, or null if it never answered. |
error |
string | always present | may be null. Why the last attempt failed (a refused address, a timeout, a non-2xx), or why it was never sent (not sent: …). |
createdAt |
string (RFC 3339) | always present | server-derived. When the delivery was queued. |
deliveredAt |
string (RFC 3339) | always present | may be null. When the subscriber accepted it; null until then. |
nextAttemptAt |
string (RFC 3339) | always present | may be null. When the retry ladder will try again; null when there is no further attempt. |
DeliveryList
| field | type | notes | |
|---|---|---|---|
data |
array of Delivery | always present | |
next_cursor |
string | always present | may be null. Opaque. Hand it back as ?cursor= for the next page; null means this was the last page. Never construct or store one; it encodes (orderKey, id) of the last row and is only meaningful against the list that issued it. |
Event
| field | type | notes | |
|---|---|---|---|
id |
string | always present | evt_…. One per change: the same on a retry, a redelivery, and every subscription that hears about the same change. De-duplicate on this. |
type |
string | always present | |
occurredAt |
string (RFC 3339) | always present | server-derived. When the change reached the API, usually within a second of the write. |
data |
object | always present | A THIN payload: the ids only, never row content. The server would have to decrypt an account to fill one, and a webhook body is a copy of the plaintext that would leave the account for good. Fetch the row over the API if you need it. |
Filter
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The filter id. Client-supplied at create, else an uppercase UUID the server issues. |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
name |
string | always present | encrypted. The filter name. |
criteria |
string | always present | encrypted. The criteria as a JSON string, with tag names (the write path seals the tag clauses to blind ids). POST and PATCH PARSE this and refuse anything malformed with validation_failed at /criteria, and what is stored is the engine’s own canonical serialisation, so what you read back may differ from your bytes while meaning exactly the same thing. |
inert |
boolean | always present | true when this server cannot parse the stored criteria: a document from a newer version, or a v1 one written before the grammar changed. An inert filter matches NOTHING (/filters/{id}/todos is empty, every count is 0) and the apps render it with a muted note. It is never partly applied: one clause this version does not understand makes the whole filter inert, because dropping the clause would silently WIDEN the filter. |
symbol |
string | always present | may be null. encrypted. The icon name the apps render. |
sortKey |
string | always present | Server-issued fractional ordering key. The stated order of every content list is (sortKey, id). Opaque: compare it, never compute one. |
trashedAt |
string (RFC 3339) | always present | may be null. Set by /filters/{id}/trash, cleared by /restore; null means the filter is live. A filter in the trash matches nothing and is left out of GET /filters unless include_trashed=true. |
FilterList
| field | type | notes | |
|---|---|---|---|
data |
array of Filter | always present | |
next_cursor |
string | always present | may be null. Opaque. Hand it back as ?cursor= for the next page; null means this was the last page. Never construct or store one; it encodes (orderKey, id) of the last row and is only meaningful against the list that issued it. |
Grant
| field | type | notes | |
|---|---|---|---|
id |
string | always present | |
name |
string | always present | may be null. encrypted. The name the user gave this credential. null when the caller holds no key to decrypt it; see name_encrypted. |
name_encrypted |
string | optional | Present ONLY when the server could not decrypt name, because a first-party app session carries no master key here, and the apps decrypt this envelope on the device. Never rendered as text: it is v1.<nonce>.<ciphertext>. |
scopes |
array of string | always present | |
createdAt |
string (RFC 3339) | always present | server-derived |
expiresAt |
string (RFC 3339) | always present | When this credential stops working. Expiry is mandatory; there is no “never”. |
lastUsedAt |
string (RFC 3339) | always present | may be null. server-derived. Server-derived, written at most once every 15 minutes per credential. null = never used. |
clientId |
string | always present | may be null |
redirectHost |
string | always present | may be null. The REAL callback host: localhost, 127.0.0.1, claude.ai. Shown so a user can tell two connections of the same app apart. |
known |
boolean | always present | Whether this client is one the server recognises by name rather than only by registration. |
localProgram |
boolean | always present | Derived from redirectHost: the grant belongs to a program running on the user’s own computer. |
GrantList
| field | type | notes | |
|---|---|---|---|
data |
array of Grant | always present | |
next_cursor |
string | always present | may be null. Opaque. Hand it back as ?cursor= for the next page; null means this was the last page. Never construct or store one; it encodes (orderKey, id) of the last row and is only meaningful against the list that issued it. |
Heading
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The heading id. Client-supplied at create, else an uppercase UUID the server issues. |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
projectId |
string | always present | The project or subproject the heading groups to-dos in. Never an area. Fixed for the heading’s life. |
name |
string | always present | encrypted. The heading’s name, shown as typed. |
sortKey |
string | always present | Server-issued fractional ordering key. The stated order of every content list is (sortKey, id). Opaque: compare it, never compute one. |
openCount |
integer | always present | min -9007199254740991, max 9007199254740991. server-derived. Server-derived: the open, live to-dos under the heading (the count the apps show after its name). |
HeadingCompleted
| field | type | notes | |
|---|---|---|---|
heading |
Heading | always present | The heading after the batch (it stays). |
completedTodoIds |
array of string | always present | The open to-dos completed, in their order. A recurring one rolled to its next occurrence, exactly as /todos/{id}/complete does. |
HeadingConverted
| field | type | notes | |
|---|---|---|---|
subproject |
Container | always present | The new subproject, named as the heading was. |
movedTodoIds |
array of string | always present | The to-dos moved into it (every to-do under the heading: open, someday, done and trashed), in their order. |
deletedHeadingId |
string | always present | The heading, now deleted. |
HeadingDeleted
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The deleted heading. |
projectId |
string | always present | The project the tasks stay in. |
clearedTodoIds |
array of string | always present | The to-dos whose headingId was cleared, in their order. They keep their project and their order; each also fires todo.updated. |
HeadingList
| field | type | notes | |
|---|---|---|---|
data |
array of Heading | always present | |
next_cursor |
string | always present | may be null. Opaque. Hand it back as ?cursor= for the next page; null means this was the last page. Never construct or store one; it encodes (orderKey, id) of the last row and is only meaningful against the list that issued it. |
InboxAttached
| field | type | notes | |
|---|---|---|---|
todo |
null | always present | may be null. Always null here, because the capture ATTACHED to the target instead of becoming a to-do. |
attachmentId |
string | always present | may be null. The attachment that was created on the target. |
status |
string | always present | One of moved, attached today. The capture row’s new status. Render an unknown value generically rather than fail, so do not generate a closed union from this field. |
InboxBecameNote
| field | type | notes | |
|---|---|---|---|
todo |
null | always present | may be null. Always null here. A note capture never becomes a to-do, with or without a parentId. |
note |
Note | always present | |
status |
string | always present | One of moved today. The capture row’s new status. Render an unknown value generically rather than fail, so do not generate a closed union from this field. |
InboxBecameTodo
| field | type | notes | |
|---|---|---|---|
todo |
Todo | always present |
InboxItem
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The capture-row id. Client-supplied at create, else an uppercase UUID the server issues. |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
kind |
string | always present | One of text, url, image, file, note today. text, url and note are created with POST /inbox; image and file with POST /inbox/upload (as the apps’ share sheet makes them). Render an unknown value generically rather than fail, so do not generate a closed union from this field. |
status |
open, moved, attached, archived, someday |
always present | server-derived. moved and attached are set by /move; archived by /archive and by /delete (which also deletes a held file); someday by /someday. A capture row is never removed. |
text |
string | always present | may be null. encrypted. The captured text (kind: "text", and the body of a note). |
url |
string | always present | may be null. encrypted. The captured URL (kind: "url"). |
title |
string | always present | may be null. encrypted. The page title the API fetched for a URL, or the filename/caption of an image or file. null until it is fetched; render the URL’s host and path meanwhile. |
whenDate |
string (yyyy-MM-dd) | always present | may be null. yyyy-MM-dd. The date quick-add parsed out of the capture; it rides onto the to-do a /move creates. |
capturedAt |
string (RFC 3339) | always present | may be null. When the item was captured. This is the apps’ own stamp, which may predate createdAt for an offline capture. |
movedTodoId |
string | always present | may be null. server-derived. The to-do /move created from this item, so a client can follow or undo it. |
movedNoteId |
string | always present | may be null. server-derived. The NOTE /move created from this item, when its kind is note. The two are never both set: a capture becomes one row or the other, never both. |
sortKey |
string | always present | Server-issued fractional ordering key. The stated order of every content list is (sortKey, id). Opaque: compare it, never compute one. |
mime |
string | always present | may be null. encrypted. The media type of an image/file capture. |
sizeBytes |
integer | always present | may be null. min -9007199254740991, max 9007199254740991. encrypted. The byte size of an image/file capture. Stored as an ENCRYPTED column so the exact size does not leak, and decoded back to a number here. |
pending |
boolean | always present | server-derived. true for an open (or parked) image or file capture whose upload has not finished: its bytes are still on the device that shared it, so /move answers conflict until that device uploads them (an inbox.updated event). false once it is uploaded, and for a capture that was already filed or deleted (which holds no file either). Always false for the other kinds. |
InboxList
| field | type | notes | |
|---|---|---|---|
data |
array of InboxItem | always present | |
next_cursor |
string | always present | may be null. Opaque. Hand it back as ?cursor= for the next page; null means this was the last page. Never construct or store one; it encodes (orderKey, id) of the last row and is only meaningful against the list that issued it. |
InboxMoved
No fields of its own.
InboxView
| field | type | notes | |
|---|---|---|---|
unsortedTodos |
array of string | always present | Open to-dos with no parent, no date and no sorted answer, by sortKey. Resolve against /todos. |
inboxCaptures |
array of string | always present | Open capture rows, in capture order. Resolve against /inbox. Two arrays because they index different tables. |
inboxWhenDates |
object | always present | Capture-row id → the date quick-add parsed for it. |
LinkTitle
| field | type | notes | |
|---|---|---|---|
title |
string | always present | may be null. The page’s og:title when it has one, otherwise its <title>: entities decoded, whitespace collapsed, at most 500 characters. null when the page could not be read for any reason (unreachable, not public, not text/html, too slow, no title). A null is an answer, not an error: name the link by its address. |
host |
string | always present | The hostname of the URL you sent (not of any page a redirect led to). |
Me
| field | type | notes | |
|---|---|---|---|
sub |
string | always present | The pairwise pseudonymous subject id, base64url(HMAC(serverKey, audience ‖ userId)), different for every OAuth client and every access key, so two apps cannot correlate the same person. A first-party app session gets the raw Appwrite user id. Webhook payloads carry the same value for the same access key or OAuth client; a subscription made in an app carries an id of its own, never the raw one. |
scopes |
array of string | always present | The scopes this credential holds right now, as stored on its row (which the user can edit in the app). tasks:read / tasks:write appear as themselves: they stand for every content scope, and every :write includes its :read (see /scopes). |
grant |
object | always present | may be null. null for a first-party app session, which has no grant row. |
webhooks |
object | always present | Webhook health for this account. |
Note
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The note id. Client-supplied at create, else an uppercase UUID the server issues. |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
parentId |
string | always present | may be null. The FIRST of placeIds, or null when the note has no place. Kept for callers written before a note could be in several projects; read placeIds. Never a to-do (to-dos are LINKED, see links). |
placeIds |
array of string | always present | The areas, projects and subprojects the note is in, oldest first (its where in the apps). A note shows in each of them. A place whose container is in the trash is hidden in the apps and comes back when it is restored. Add one with POST /notes/{id}/places, remove one with DELETE /notes/{id}/places/{containerId}, or set them all with PATCH {"placeIds": [...]}. |
folderId |
string | always present | may be null. The note folder it is in (/note-folders), or null. Independent of parentId: a note can be in a folder AND attached. Changed with PATCH. |
pinned |
boolean | always present | Pinned notes sort first in every notes list the apps draw. Changed with PATCH {"pinned": true}. |
pinnedAt |
string (RFC 3339) | always present | may be null. When it was pinned, or null. |
colorHex |
string | always present | may be null. encrypted. #RRGGBB: the tint behind the note in the apps’ lists and cards. null for no colour. |
editedAt |
string (RFC 3339) | always present | When the note’s title or body last changed (the apps’ “edited” line). Pinning, unpinning, moving it between folders, attaching it and trashing it never change it; updatedAt moves on every write. The v3 order is pinned first, then editedAt descending. |
links |
array of NoteLinkRef | always present | The to-dos this note is LINKED to (many-to-many), oldest link first. A link to a to-do in the trash is hidden here and comes back when it is restored. Add one with POST /notes/{id}/links. |
noteLinks |
array of NoteNoteLinkRef | always present | The other notes this note is LINKED with, oldest link first. Links are two-way: the other note lists this one too. A link to a note in the trash is hidden here. Add one with POST /notes/{id}/note-links, or by writing [title](note:ID) in the body. |
tags |
array of string | always present | encrypted. The note’s tags, by NAME (lowercase, as the apps normalize them). Set with PATCH {"tags": [...]}; a tag that does not exist yet is created. |
title |
string | always present | may be null. encrypted. The heading. OPTIONAL: a note without one is shown by the first line of its body. |
body |
string | always present | encrypted. The note itself, Markdown, up to 100,000 characters. The API stores and returns it VERBATIM: it neither renders it nor validates the syntax. It may be EMPTY ("") when the note has a title: a note needs a title or a body. The apps render a fixed subset, plus embeds: , [name](att:ID), [title](note:ID), [title](task:ID) and [name](container:ID) (see the notes guide). |
sortKey |
string | always present | Server-issued fractional ordering key. The stated order of every content list is (sortKey, id). Opaque: compare it, never compute one. |
trashedAt |
string (RFC 3339) | always present | may be null. server-derived. Set by /trash, cleared by /restore; null means the row is live. |
NoteExport
| field | type | notes | |
|---|---|---|---|
format |
markdown, text |
always present | |
files |
array of object | always present | encrypted. One file per note, in the apps’ export layout. Markdown files open with front matter (id, title, folder, where, tags, pinned, created, edited, tasks, notes, attachments), then # title and the body with every embed rewritten to standard Markdown pointing at the exported files. |
attachments |
array of object | always present | The files and pictures the export refers to (with attachments=include). Fetch each one’s bytes from GET /attachments/{id}/file and save them at path. |
NoteFolder
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The folder id. Client-supplied at create, else an uppercase UUID the server issues. |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
name |
string | always present | encrypted. The folder’s name. |
colorHex |
string | always present | may be null. encrypted. #RRGGBB, or null for the default (the text colour). |
symbol |
string | always present | may be null. encrypted. An SF Symbol name for its icon, or null for folder. |
parentId |
string | always present | may be null. The folder it sits in, or null at the top level. Folders nest ONE level only. Changed with /move. |
sortKey |
string | always present | Server-issued fractional ordering key. The stated order of every content list is (sortKey, id). Opaque: compare it, never compute one. |
trashedAt |
string (RFC 3339) | always present | may be null. server-derived. Set by /trash, cleared by /restore. Only the folder is stamped: its subfolders and notes are in the trash WITH it. |
noteCount |
integer | always present | min -9007199254740991, max 9007199254740991. server-derived. Server-derived: the live notes directly in this folder (not in its subfolders), as the sidebar shows it. |
NoteFolderList
| field | type | notes | |
|---|---|---|---|
data |
array of NoteFolder | always present | |
next_cursor |
string | always present | may be null. Opaque. Hand it back as ?cursor= for the next page; null means this was the last page. Never construct or store one; it encodes (orderKey, id) of the last row and is only meaningful against the list that issued it. |
NoteLink
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The link id. Client-supplied at create, else an uppercase UUID the server issues. |
noteId |
string | always present | The note. |
todoId |
string | always present | The to-do. |
createdAt |
string (RFC 3339) | always present | When the link was made. When two devices made the same link offline, the OLDEST survives. |
NoteLinkList
| field | type | notes | |
|---|---|---|---|
data |
array of NoteLink | always present |
NoteLinkRef
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The link id (the id a note.linked / note.unlinked event carries). |
todoId |
string | always present | The linked to-do. |
createdAt |
string (RFC 3339) | always present | When the link was made. |
NoteList
| field | type | notes | |
|---|---|---|---|
data |
array of Note | always present | |
next_cursor |
string | always present | may be null. Opaque. Hand it back as ?cursor= for the next page; null means this was the last page. Never construct or store one; it encodes (orderKey, id) of the last row and is only meaningful against the list that issued it. |
NoteNoteLink
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The link id (what a note.note_linked event carries). |
noteIds |
array of string | always present | The two notes, the smaller id first. Links are two-way: neither note owns the link. |
createdAt |
string (RFC 3339) | always present | When the link was made. When two devices linked the same pair offline, the OLDEST survives. |
NoteNoteLinkList
| field | type | notes | |
|---|---|---|---|
data |
array of NoteNoteLink | always present |
NoteNoteLinkRef
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The link id. |
noteId |
string | always present | The OTHER note. |
createdAt |
string (RFC 3339) | always present | When the link was made. |
NotePlace
| field | type | notes | |
|---|---|---|---|
id |
string | always present | may be null. The place id (what a note.place_added event carries), or null for a place recorded only in an older app’s data that no app has copied into a place yet. |
noteId |
string | always present | The note. |
containerId |
string | always present | The area, project or subproject. |
live |
boolean | always present | server-derived. Server-derived: false while that container (or one above it) is in the trash or archived. The apps hide such a place. |
createdAt |
string (RFC 3339) | always present | When the place was added. Places are listed oldest first; the first is the note’s parentId. |
NotePlaceList
| field | type | notes | |
|---|---|---|---|
data |
array of NotePlace | always present |
NoteVersion
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The version id. |
noteId |
string | always present | The note. |
kind |
string | always present | One of stretch, checkpoint, original, replaced, restore today. What made the version: stretch (the end of an editing stretch), checkpoint (every 30 minutes of continuous editing), original (the text before the first edit the history knows, or a new note’s first text: the apps show it as created), replaced (text that lost when two devices edited at once) or restore (the text that was current when an older version was restored). Render an unknown value generically rather than fail, so do not generate a closed union from this field. |
deviceName |
string | always present | encrypted. The kind of device that wrote it: mac, iphone, ipad, android, web, api (a REST call) or ai (an AI connected over MCP). Empty or other for a text that came from elsewhere. |
deviceId |
string | always present | encrypted. The writing device’s id: a device of the account, or api:<id> / ai:<id> for the credential that wrote it. Empty when unknown. |
wordsAdded |
integer | always present | min -9007199254740991, max 9007199254740991. encrypted. Words added against the version before it. |
wordsRemoved |
integer | always present | min -9007199254740991, max 9007199254740991. encrypted. Words removed against the version before it. |
editedAt |
string (RFC 3339) | always present | When the text was in this state. The history is newest first by this time. |
current |
boolean | always present | server-derived. Server-derived: this version holds the note’s current title and body (the apps’ now). |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
NoteVersionDetail
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The version id. |
noteId |
string | always present | The note. |
kind |
string | always present | One of stretch, checkpoint, original, replaced, restore today. What made the version: stretch (the end of an editing stretch), checkpoint (every 30 minutes of continuous editing), original (the text before the first edit the history knows, or a new note’s first text: the apps show it as created), replaced (text that lost when two devices edited at once) or restore (the text that was current when an older version was restored). Render an unknown value generically rather than fail, so do not generate a closed union from this field. |
deviceName |
string | always present | encrypted. The kind of device that wrote it: mac, iphone, ipad, android, web, api (a REST call) or ai (an AI connected over MCP). Empty or other for a text that came from elsewhere. |
deviceId |
string | always present | encrypted. The writing device’s id: a device of the account, or api:<id> / ai:<id> for the credential that wrote it. Empty when unknown. |
wordsAdded |
integer | always present | min -9007199254740991, max 9007199254740991. encrypted. Words added against the version before it. |
wordsRemoved |
integer | always present | min -9007199254740991, max 9007199254740991. encrypted. Words removed against the version before it. |
editedAt |
string (RFC 3339) | always present | When the text was in this state. The history is newest first by this time. |
current |
boolean | always present | server-derived. Server-derived: this version holds the note’s current title and body (the apps’ now). |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
title |
string | always present | may be null. encrypted. The note’s title in this version. |
body |
string | always present | encrypted. The note’s body in this version, Markdown. |
previousVersionId |
string | always present | may be null. The version before it (by editedAt), the one diff compares against; null for the oldest. |
diff |
object | optional | With ?diff=true: the word diff against previousVersionId, the marks the apps draw (added words, removed words). |
NoteVersionList
| field | type | notes | |
|---|---|---|---|
data |
array of NoteVersion | always present | Newest first, except that the version holding the current text (current: true) always comes first, as the apps list it. |
currentVersionId |
string | always present | may be null. The version equal to the note’s current text, or null when no version holds it yet (it arrived from another device before that device wrote its version). |
NotesView
| field | type | notes | |
|---|---|---|---|
notesView |
object | always present |
OverviewView
| field | type | notes | |
|---|---|---|---|
navCounts |
object | always present | The sidebar badges. A closed-world contract: fixtures/views.json asserts it byte-identical. overview = today + overdue + planned + anytime − unsorted overdue. |
homeCounts |
object | always present | The numbers the apps’ home screen shows, row for row. Each is its navCounts twin except inbox, planned, notes and attachments, which count what those pages list. |
containerOpenCounts |
object | always present | Container id → recursive open-to-do count. An area counts its own to-dos plus its projects’. |
containerPies |
object | always present | Container id → the done/open pair the progress pie draws. Only containers with a task (open, done or someday, in it or its subprojects; trashed ones do not count) appear: a project that holds only notes, links or files has no entry, and the apps draw no pie and no count for it. |
overviewTreeOrder |
array of string | always present | Every live container id (not archived or trashed, itself or by an ancestor), empty ones included, in sidebar order, which is the order everything else in this payload refers to. The overview draws each of them. |
overviewNoProject |
array of string | always present | Open to-dos with no container that are NOT unsorted, by sortKey. Rendered FIRST, before the tree. |
containerItems |
object | always present | Container id to its ITEM BAND: that container’s direct open to-dos AND its live notes, INTERLEAVED in one sortKey order. An area has one too (its own to-dos). The key standalone is the parentless band: every open parentless to-do, unsorted ones included, and the standalone notes. It is a sort-key space, not a list. One array holds ids from two tables on purpose, because the band is one ordering space. Resolve an id against /todos and /notes. Only non-empty bands appear. |
topbar |
object | always present | |
priorities |
object | always present | Row id → priority, for to-dos and containers alike. Display only. |
excludedContainerIds |
array of string | always present | Containers excluded because they are ARCHIVED (trash is trashExcluded, which /trash owns). |
excludedTodoIds |
array of string | always present | To-dos excluded because their container is archived. |
PingQueued
PlannedView
| field | type | notes | |
|---|---|---|---|
plannedDays |
array of DayBucket | always present | EXACTLY six buckets, today+1 … today+6. Empty days are present with an empty items. Grouped by the scheduled date only. |
plannedLater |
array of DayBucket | always present | The dates after today+6 that hold something, ascending. Empty dates never appear. |
dayBucketContainers |
object | always present | Day (yyyy-MM-dd) → containers whose deadline falls on it, for today+1 … today+6. |
Problem
RFC 9457 application/problem+json. Branch on type, never on detail. type is a stable URI that also resolves to the page explaining the code; detail is prose written for a human and may change.
| field | type | notes | |
|---|---|---|---|
type |
string (uri) | always present | A stable URI under https://devs.inittasks.com/errors/. This is the machine-readable code. |
title |
string | always present | A short, stable summary of the code. Does not vary per occurrence. |
status |
integer | always present | The HTTP status, repeated in the body. |
detail |
string | optional | What went wrong this time. Never carries row content, a token, or anything derived from a key. |
instance |
string | optional | The path that produced it, /v1/…. |
request_id |
string | optional | The same value as the X-Request-Id header. Quote it in a support request. It is the only handle that ties your call to the server log, and the log carries no bodies. |
errors |
array of object | optional | Field-level complaints on a validation_failed. Every offending field is listed, not just the first. |
retry_after |
integer | optional | Seconds to wait, on a rate_limited. The same value as the Retry-After header. |
tagId |
string | optional | On a tag_exists: the id of the tag that already has the name. Send the rename again with "merge": true to merge into it. |
RedeliveryQueued
| field | type | notes | |
|---|---|---|---|
delivery |
Delivery | always present |
ScheduleReminder
ONE of before or at. A to-do holds at most 5, kept in the order they ring.
| field | type | notes | |
|---|---|---|---|
before |
integer | optional | min -9007199254740991, max 9007199254740991. Minutes before the start (0 = at the start). Present on a reminder that follows the to-do’s start: it moves when the date or the time moves. |
at |
string | optional | A fixed local-naive moment, yyyy-MM-ddTHH:mm (24-hour, no seconds, no offset). Present on a reminder that stays put. |
SearchHit
| field | type | notes | |
|---|---|---|---|
kind |
todo, container, note, inbox, attachment |
always present | Which resource id belongs to. |
id |
string | always present | |
label |
string | always present | encrypted. The row’s primary display text: title, name, captured text, or URL. |
field |
title, name, subtitle, description, subtasks, body, tags, text, url |
always present | Which field the query matched, so a client can say “matched in the description”. |
crumb |
string | always present | may be null. encrypted. The direct parent container’s name, or null for a root row. |
trashed |
boolean | always present | True when the row is in the trash: trashed itself, or under a trashed container. Only ever true with include_trashed=true; an archived subtree is never returned. |
SearchResult
| field | type | notes | |
|---|---|---|---|
data |
array of SearchHit | always present | |
next_cursor |
string | always present | may be null. Opaque. Hand it back as ?cursor= for the next page; null means this was the last page. Never construct or store one; it encodes (orderKey, id) of the last row and is only meaningful against the list that issued it. |
Session
| field | type | notes | |
|---|---|---|---|
id |
string | always present | |
createdAt |
string (RFC 3339) | always present | server-derived. When the session was opened. |
current |
boolean | always present | Whether this is the session the calling credential is using. |
clientName |
string | always present | may be null |
clientVersion |
string | always present | may be null |
deviceName |
string | always present | may be null |
osName |
string | always present | may be null |
provider |
string | always present | may be null. How the session was created: email, apple, google, token. |
deviceType |
string | always present | One of phone, tablet, desktop, web, unknown today. What KIND of device this session belongs to, for the symbol the list draws. From the enrolled device’s formFactor (browser is reported as web); when the device has none (an older enrolment), derived from its platform (ios/android → phone, macos/cli → desktop, web → web). A session with no enrolled device, such as a key or a connected app, is unknown. ⚠ Both source columns are encrypted, so a first-party app session, which carries no master key here, sees unknown on every row and derives the symbol from the device row itself, as the apps already do. Render an unknown value generically rather than fail, so do not generate a closed union from this field. |
device |
SessionDevice | always present | may be null. The enrolled device that signed in with this session. null for a session a key or a connected app owns, and for a sign-in that never enrolled a device. |
lastActiveAt |
string (RFC 3339) | always present | may be null. server-derived. The enrolled device’s lastSeenAt; failing that the owning grant’s lastUsedAt; failing that null. One value the list can render whatever kind of session this is. |
grant |
AccessKey or Grant | always present | may be null. The access key or connected app that owns this session, so a screen can say which one it belongs to. null for a person’s own sign-in. No IP address is kept or shown. |
SessionDevice
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The enrolled device’s id. |
name |
string | always present | may be null. encrypted. The name the device gave itself when it enrolled. null when the caller holds no key to decrypt it; see name_encrypted. |
name_encrypted |
string | optional | Present ONLY when the server could not decrypt name, because a first-party app session carries no master key here. Never rendered as text: it is v1.<nonce>.<ciphertext>. |
platform |
string | always present | may be null. encrypted. ios, macos, android, web or cli. null when the caller holds no key; see platform_encrypted. |
platform_encrypted |
string | optional | The same rule as name_encrypted, and it applies to every encrypted column an operational endpoint returns. |
lastSeenAt |
string (RFC 3339) | always present | may be null. server-derived. The device stamps it at most once every 15 minutes, on launch and on the first sync past the interval. Not encrypted, so it is readable by every caller. |
SessionList
| field | type | notes | |
|---|---|---|---|
data |
array of Session | always present | |
next_cursor |
string | always present | may be null. Opaque. Hand it back as ?cursor= for the next page; null means this was the last page. Never construct or store one; it encodes (orderKey, id) of the last row and is only meaningful against the list that issued it. |
Settings
| field | type | notes | |
|---|---|---|---|
weekStart |
monday, sunday |
always present | The first day of the week in the apps: the date picker’s first column, and the day next week suggests. No view, bucket or count depends on it. Shared with the apps. ⚠ PATCH accepts null to mean “no preference”, and the server then answers with the default, monday. So a read-back is never null. |
reminderDefaultTime |
string | always present | The time a reminder gets when it is switched on: HH:mm on a 24-hour clock, meaning that wall-clock time on whichever device fires it. ⚠ NEVER null here: PATCH null restores the default and this answers 09:00, the same rule weekStart follows. Synced with the account. |
overdueNudgeTime |
string | always present | may be null. One notification a day listing anything overdue, at this HH:mm local time; null means it is OFF. ⚠ Unlike reminderDefaultTime, null here is a STATE, not an absent preference: the switch and the time are one value, so there is no “on at no time”. Synced with the account, but it only fires on devices whose own notifications switch is on, and that switch is device-local and has no API. |
calendarPrefs |
object | always present | The calendar choices every device shares. The calendars live on each device (the apps read the device’s own calendars); only these choices sync. |
SignOutOthersResult
| field | type | notes | |
|---|---|---|---|
signedOut |
integer | always present | min -9007199254740991, max 9007199254740991. Sessions ended. |
kept |
integer | always present | min -9007199254740991, max 9007199254740991. Sessions kept because an access key or a connected app holds them (the caller’s own is kept too and not counted). |
SomedayView
| field | type | notes | |
|---|---|---|---|
somedayV2 |
object | always present | |
containerSomeday |
object | always present | Container id → its direct parked to-dos. Only containers that have some appear. |
Subtask
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The subtask id: a lowercase UUID, stable for the life of the subtask (a duplicate gets new ones). |
title |
string | always present | encrypted. One line, at most 120 characters. |
done |
boolean | always present | Ticked. Ticking the last one does not complete the to-do; completing the to-do leaves open subtasks unticked. |
SubtaskPromoted
| field | type | notes | |
|---|---|---|---|
todo |
Todo | always present | The NEW to-do the subtask became: open, right after its parent, in the same project, heading and day. |
from |
Todo | always present | The to-do it came from, without the subtask. |
SubtaskResult
| field | type | notes | |
|---|---|---|---|
subtask |
Subtask | always present | |
todo |
Todo | always present | The to-do after the change, with its whole subtasks list. |
Tag
| field | type | notes | |
|---|---|---|---|
id |
string | always present | tg_ + 32 hex, which is HMAC(k_id, name), NOT a UUID. A tag’s identity IS its name, so renaming a tag gives it a new id, and the old id answers 308 to it. |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
name |
string | always present | encrypted. The tag name, normalised to lower case with runs of whitespace collapsed. |
colorHex |
string | always present | may be null. encrypted. A 6-digit hex colour, or null for the theme default. |
sortKey |
string | always present | Server-issued fractional ordering key. The stated order of every content list is (sortKey, id). Opaque: compare it, never compute one. |
trashedAt |
string (RFC 3339) | always present | may be null. Set by /tags/{id}/trash, cleared by /restore; null means the tag is live. A tag in the trash is hidden from every list in the apps and from GET /tags (unless include_trashed=true), and no filter matches it, but its to-dos, notes and attachments keep its name, so a restore brings everything back. Creating a tag with its name restores it. |
TagList
| field | type | notes | |
|---|---|---|---|
data |
array of Tag | always present | |
next_cursor |
string | always present | may be null. Opaque. Hand it back as ?cursor= for the next page; null means this was the last page. Never construct or store one; it encodes (orderKey, id) of the last row and is only meaningful against the list that issued it. |
TodayView
| field | type | notes | |
|---|---|---|---|
overdue |
array of string | always present | Open to-dos whose deadline has passed, unsorted ones included (the one overlap with the inbox). List order: no-project first, then the tree. |
fromEarlier |
array of string | always present | Open, not overdue, scheduled on a day before the reference day. List order. |
todayItems |
array of string | always present | The today block: not overdue, not from earlier, not unsorted, scheduled or due on the reference day. List order. |
doneToday |
array of string | always present | To-dos completed on the reference day. |
todayContainers |
array of string | always present | Containers whose DEADLINE is the reference day. Display-only surfacing; never counted. |
overdueContainers |
array of string | always present | Containers whose deadline has passed. |
Todo
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The to-do id. Client-supplied at create, else an uppercase UUID the server issues. |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
title |
string | always present | encrypted. The to-do title. |
parentId |
string | always present | may be null. The area, project or subproject this to-do sits in (an area can hold to-dos), or null for no project. Changed with /move. |
headingId |
string | always present | may be null. The heading this to-do sits under inside its project (/headings), or null. Always a heading of THIS to-do’s parentId: moving the to-do to another container clears it. A heading that was deleted, or that belongs to another project, reads as null. |
subtitle |
string | always present | may be null. encrypted. A one-line subtitle. |
description |
string | always present | may be null. encrypted. The free text on the to-do itself, up to 100,000 characters. Plain text. It is not a note: a note is a row of its own, at /notes. |
tags |
array of string | always present | Tag NAMES, never ids (they are stored as blind ids; the API resolves them both ways). Always present; an untagged to-do returns []. |
sorted |
boolean | always present | true once a when or where answer has been given (a date, anytime, someday, a container, or "no project"). It is the stored flag, not inbox membership: a dated or filed to-do can say false and still be sorted by its date or parent. Set it with sorted: true on create/PATCH; nothing clears it. |
whenDate |
string (yyyy-MM-dd) | always present | may be null. yyyy-MM-dd. The day the to-do is scheduled for. null = unscheduled (the anytime list once sorted, the inbox while not). |
deadline |
string (yyyy-MM-dd) | always present | may be null. yyyy-MM-dd. A hard due date. A deadline alone does NOT schedule the to-do. |
status |
open, someday, done |
always present | Changed by the actions (/complete, /uncomplete, /someday, /anytime, and /move, which un-parks), never set by PATCH, because each is a transition with side effects. One write changes it as a consequence: a PATCH that gives a someday to-do a whenDate, a deadline, a recurrenceRule or a whenTime makes it open, because a dated to-do is not parked. |
priority |
low, medium, high |
always present | may be null. Display-only; it never affects ordering or counts. |
colorHex |
string | always present | may be null. encrypted. A 6-digit hex colour, with or without the leading #. |
colorStyle |
text, fill |
always present | may be null. fill for any colour set since September 2026 (a colour is a highlight behind the row, and the apps draw it that way whatever this says); text on older rows; null with no colour. |
reminderTime |
string | always present | may be null. encrypted. A LOCAL-NAIVE 24-hour instant, yyyy-MM-ddTHH:mm: no seconds, no offset, no Z. It means that wall-clock time on the device that fires it, so it never shifts when the user travels. |
recurrenceRule |
string | always present | may be null. encrypted. The recurrence rule. null = a one-off to-do. |
recurrenceAnchor |
string (yyyy-MM-dd) | always present | may be null. yyyy-MM-dd. Server-derived. The date the series is anchored to (its grid starts here). /complete moves whenDate to the next occurrence and leaves this where it is. |
completedAt |
string (RFC 3339) | always present | may be null. server-derived. Stamped by /complete, cleared by /uncomplete. |
trashedAt |
string (RFC 3339) | always present | may be null. server-derived. Set by /trash, cleared by /restore; null means the row is live. |
sortKey |
string | always present | Server-issued fractional ordering key. The stated order of every content list is (sortKey, id). Opaque: compare it, never compute one. |
whenTime |
string | always present | may be null. encrypted. The start time on whenDate, HH:mm 24-hour, local-naive (it stays 09:00 when the user travels). null = no start (an all-day to-do). Always null while there is no whenDate. |
durationMin |
integer | always present | may be null. min -9007199254740991, max 9007199254740991. encrypted. The length in minutes, 5 to 1440. It can exist without a start: it is the block’s length once the to-do gets one. |
reminders |
array of ScheduleReminder | always present | Every reminder, at most 5, in the order they ring. reminderTime is the earliest of them. Always present; [] when there are none. A to-do written before 2026-10-05 with only a reminderTime reads as one at reminder. |
subtasks |
array of Subtask | always present | The checklist inside the to-do, in order: at most 50. A subtask is a title and a tick only, never a date, tag or note. Always present; [] when there are none. |
TodoList
| field | type | notes | |
|---|---|---|---|
data |
array of Todo | always present | |
next_cursor |
string | always present | may be null. Opaque. Hand it back as ?cursor= for the next page; null means this was the last page. Never construct or store one; it encodes (orderKey, id) of the last row and is only meaningful against the list that issued it. |
headings |
array of Heading | optional | Only with ?group_by=heading, and only when the credential holds containers:read (heading names are project data): the project’s headings in order. data is then in PAGE order: the to-dos with no heading first, then each heading’s to-dos in this order. Match a to-do to its group with its headingId. |
TrashEmptied
| field | type | notes | |
|---|---|---|---|
deleted |
integer | always present | min -9007199254740991, max 9007199254740991. How many rows were permanently deleted. Not recoverable. |
TrashList
| field | type | notes | |
|---|---|---|---|
data |
array of TrashedTodo or TrashedNote or TrashedContainer or TrashedNoteFolder or TrashedTag or TrashedFilter | always present | |
next_cursor |
string | always present | may be null. Opaque. Hand it back as ?cursor= for the next page; null means this was the last page. Never construct or store one; it encodes (orderKey, id) of the last row and is only meaningful against the list that issued it. |
TrashedContainer
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The container id. Client-supplied at create, else an uppercase UUID the server issues. |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
kind |
area, project, subproject |
always present | |
name |
string | always present | encrypted. The container name. |
parentId |
string | always present | may be null. The parent container, or null for a root area. Changed with /move, never with PATCH. |
subtitle |
string | always present | may be null. encrypted. A one-line subtitle. |
description |
string | always present | may be null. encrypted. The free text on the row itself, up to 100,000 characters. Plain text, rendered as // comment lines at the top of the container’s page. It is not a note: a note is a row of its own, at /notes. |
symbol |
string | always present | may be null. encrypted. The icon name the apps render. |
colorHex |
string | always present | may be null. encrypted. A 6-digit hex colour, with or without the leading #. |
deadline |
string (yyyy-MM-dd) | always present | may be null. yyyy-MM-dd. A hard due date. A deadline alone does not schedule the container. |
priority |
low, medium, high |
always present | may be null. Display-only; it never affects ordering or counts. |
status |
active, archived |
always present | |
sortKey |
string | always present | Server-issued fractional ordering key. The stated order of every content list is (sortKey, id). Opaque: compare it, never compute one. |
trashedAt |
string (RFC 3339) | always present | may be null. server-derived. Set by /trash, cleared by /restore; null means the row is live. |
type |
string | always present | Always "container". Branch on this; never on which other members happen to be present. |
purgesAt |
string (RFC 3339) | always present | server-derived. Server-derived: trashedAt + 30 days, the instant this row becomes eligible for the automatic purge. |
daysLeft |
integer | always present | min -9007199254740991, max 9007199254740991. server-derived. Server-derived: whole days until purgesAt, rounded UP, never below 0: ceil((purgesAt − now) / 24 h). The apps show it as “28 days left”, in red at 5 or fewer. |
TrashedFilter
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The filter id. Client-supplied at create, else an uppercase UUID the server issues. |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
name |
string | always present | encrypted. The filter name. |
criteria |
string | always present | encrypted. The criteria as a JSON string, with tag names (the write path seals the tag clauses to blind ids). POST and PATCH PARSE this and refuse anything malformed with validation_failed at /criteria, and what is stored is the engine’s own canonical serialisation, so what you read back may differ from your bytes while meaning exactly the same thing. |
inert |
boolean | always present | true when this server cannot parse the stored criteria: a document from a newer version, or a v1 one written before the grammar changed. An inert filter matches NOTHING (/filters/{id}/todos is empty, every count is 0) and the apps render it with a muted note. It is never partly applied: one clause this version does not understand makes the whole filter inert, because dropping the clause would silently WIDEN the filter. |
symbol |
string | always present | may be null. encrypted. The icon name the apps render. |
sortKey |
string | always present | Server-issued fractional ordering key. The stated order of every content list is (sortKey, id). Opaque: compare it, never compute one. |
trashedAt |
string (RFC 3339) | always present | may be null. Set by /filters/{id}/trash, cleared by /restore; null means the filter is live. A filter in the trash matches nothing and is left out of GET /filters unless include_trashed=true. |
type |
string | always present | Always "filter". Branch on this; never on which other members happen to be present. |
purgesAt |
string (RFC 3339) | always present | server-derived. Server-derived: trashedAt + 30 days, the instant this row becomes eligible for the automatic purge. |
daysLeft |
integer | always present | min -9007199254740991, max 9007199254740991. server-derived. Server-derived: whole days until purgesAt, rounded UP, never below 0: ceil((purgesAt − now) / 24 h). The apps show it as “28 days left”, in red at 5 or fewer. |
TrashedNote
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The note id. Client-supplied at create, else an uppercase UUID the server issues. |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
parentId |
string | always present | may be null. The FIRST of placeIds, or null when the note has no place. Kept for callers written before a note could be in several projects; read placeIds. Never a to-do (to-dos are LINKED, see links). |
placeIds |
array of string | always present | The areas, projects and subprojects the note is in, oldest first (its where in the apps). A note shows in each of them. A place whose container is in the trash is hidden in the apps and comes back when it is restored. Add one with POST /notes/{id}/places, remove one with DELETE /notes/{id}/places/{containerId}, or set them all with PATCH {"placeIds": [...]}. |
folderId |
string | always present | may be null. The note folder it is in (/note-folders), or null. Independent of parentId: a note can be in a folder AND attached. Changed with PATCH. |
pinned |
boolean | always present | Pinned notes sort first in every notes list the apps draw. Changed with PATCH {"pinned": true}. |
pinnedAt |
string (RFC 3339) | always present | may be null. When it was pinned, or null. |
colorHex |
string | always present | may be null. encrypted. #RRGGBB: the tint behind the note in the apps’ lists and cards. null for no colour. |
editedAt |
string (RFC 3339) | always present | When the note’s title or body last changed (the apps’ “edited” line). Pinning, unpinning, moving it between folders, attaching it and trashing it never change it; updatedAt moves on every write. The v3 order is pinned first, then editedAt descending. |
links |
array of NoteLinkRef | always present | The to-dos this note is LINKED to (many-to-many), oldest link first. A link to a to-do in the trash is hidden here and comes back when it is restored. Add one with POST /notes/{id}/links. |
noteLinks |
array of NoteNoteLinkRef | always present | The other notes this note is LINKED with, oldest link first. Links are two-way: the other note lists this one too. A link to a note in the trash is hidden here. Add one with POST /notes/{id}/note-links, or by writing [title](note:ID) in the body. |
tags |
array of string | always present | encrypted. The note’s tags, by NAME (lowercase, as the apps normalize them). Set with PATCH {"tags": [...]}; a tag that does not exist yet is created. |
title |
string | always present | may be null. encrypted. The heading. OPTIONAL: a note without one is shown by the first line of its body. |
body |
string | always present | encrypted. The note itself, Markdown, up to 100,000 characters. The API stores and returns it VERBATIM: it neither renders it nor validates the syntax. It may be EMPTY ("") when the note has a title: a note needs a title or a body. The apps render a fixed subset, plus embeds: , [name](att:ID), [title](note:ID), [title](task:ID) and [name](container:ID) (see the notes guide). |
sortKey |
string | always present | Server-issued fractional ordering key. The stated order of every content list is (sortKey, id). Opaque: compare it, never compute one. |
trashedAt |
string (RFC 3339) | always present | may be null. server-derived. Set by /trash, cleared by /restore; null means the row is live. |
type |
string | always present | Always "note". Branch on this; never on which other members happen to be present. |
purgesAt |
string (RFC 3339) | always present | server-derived. Server-derived: trashedAt + 30 days, the instant this row becomes eligible for the automatic purge. |
daysLeft |
integer | always present | min -9007199254740991, max 9007199254740991. server-derived. Server-derived: whole days until purgesAt, rounded UP, never below 0: ceil((purgesAt − now) / 24 h). The apps show it as “28 days left”, in red at 5 or fewer. |
TrashedNoteFolder
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The folder id. Client-supplied at create, else an uppercase UUID the server issues. |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
name |
string | always present | encrypted. The folder’s name. |
colorHex |
string | always present | may be null. encrypted. #RRGGBB, or null for the default (the text colour). |
symbol |
string | always present | may be null. encrypted. An SF Symbol name for its icon, or null for folder. |
parentId |
string | always present | may be null. The folder it sits in, or null at the top level. Folders nest ONE level only. Changed with /move. |
sortKey |
string | always present | Server-issued fractional ordering key. The stated order of every content list is (sortKey, id). Opaque: compare it, never compute one. |
trashedAt |
string (RFC 3339) | always present | may be null. server-derived. Set by /trash, cleared by /restore. Only the folder is stamped: its subfolders and notes are in the trash WITH it. |
noteCount |
integer | always present | min -9007199254740991, max 9007199254740991. server-derived. Server-derived: the live notes directly in this folder (not in its subfolders), as the sidebar shows it. |
type |
string | always present | Always "note_folder". Branch on this; never on which other members happen to be present. |
purgesAt |
string (RFC 3339) | always present | server-derived. Server-derived: trashedAt + 30 days, the instant this row becomes eligible for the automatic purge. |
daysLeft |
integer | always present | min -9007199254740991, max 9007199254740991. server-derived. Server-derived: whole days until purgesAt, rounded UP, never below 0: ceil((purgesAt − now) / 24 h). The apps show it as “28 days left”, in red at 5 or fewer. |
TrashedTag
| field | type | notes | |
|---|---|---|---|
id |
string | always present | tg_ + 32 hex, which is HMAC(k_id, name), NOT a UUID. A tag’s identity IS its name, so renaming a tag gives it a new id, and the old id answers 308 to it. |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
name |
string | always present | encrypted. The tag name, normalised to lower case with runs of whitespace collapsed. |
colorHex |
string | always present | may be null. encrypted. A 6-digit hex colour, or null for the theme default. |
sortKey |
string | always present | Server-issued fractional ordering key. The stated order of every content list is (sortKey, id). Opaque: compare it, never compute one. |
trashedAt |
string (RFC 3339) | always present | may be null. Set by /tags/{id}/trash, cleared by /restore; null means the tag is live. A tag in the trash is hidden from every list in the apps and from GET /tags (unless include_trashed=true), and no filter matches it, but its to-dos, notes and attachments keep its name, so a restore brings everything back. Creating a tag with its name restores it. |
type |
string | always present | Always "tag". Branch on this; never on which other members happen to be present. |
purgesAt |
string (RFC 3339) | always present | server-derived. Server-derived: trashedAt + 30 days, the instant this row becomes eligible for the automatic purge. |
daysLeft |
integer | always present | min -9007199254740991, max 9007199254740991. server-derived. Server-derived: whole days until purgesAt, rounded UP, never below 0: ceil((purgesAt − now) / 24 h). The apps show it as “28 days left”, in red at 5 or fewer. |
TrashedTodo
| field | type | notes | |
|---|---|---|---|
id |
string | always present | The to-do id. Client-supplied at create, else an uppercase UUID the server issues. |
createdAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the row’s creation instant as Appwrite stamped it ($createdAt). |
updatedAt |
string (RFC 3339) | always present | server-derived. RFC 3339; the instant the SERVER last wrote the row ($updatedAt). This is the field ?updated_since= compares against. It is never a time a client stamped. |
title |
string | always present | encrypted. The to-do title. |
parentId |
string | always present | may be null. The area, project or subproject this to-do sits in (an area can hold to-dos), or null for no project. Changed with /move. |
headingId |
string | always present | may be null. The heading this to-do sits under inside its project (/headings), or null. Always a heading of THIS to-do’s parentId: moving the to-do to another container clears it. A heading that was deleted, or that belongs to another project, reads as null. |
subtitle |
string | always present | may be null. encrypted. A one-line subtitle. |
description |
string | always present | may be null. encrypted. The free text on the to-do itself, up to 100,000 characters. Plain text. It is not a note: a note is a row of its own, at /notes. |
tags |
array of string | always present | Tag NAMES, never ids (they are stored as blind ids; the API resolves them both ways). Always present; an untagged to-do returns []. |
sorted |
boolean | always present | true once a when or where answer has been given (a date, anytime, someday, a container, or "no project"). It is the stored flag, not inbox membership: a dated or filed to-do can say false and still be sorted by its date or parent. Set it with sorted: true on create/PATCH; nothing clears it. |
whenDate |
string (yyyy-MM-dd) | always present | may be null. yyyy-MM-dd. The day the to-do is scheduled for. null = unscheduled (the anytime list once sorted, the inbox while not). |
deadline |
string (yyyy-MM-dd) | always present | may be null. yyyy-MM-dd. A hard due date. A deadline alone does NOT schedule the to-do. |
status |
open, someday, done |
always present | Changed by the actions (/complete, /uncomplete, /someday, /anytime, and /move, which un-parks), never set by PATCH, because each is a transition with side effects. One write changes it as a consequence: a PATCH that gives a someday to-do a whenDate, a deadline, a recurrenceRule or a whenTime makes it open, because a dated to-do is not parked. |
priority |
low, medium, high |
always present | may be null. Display-only; it never affects ordering or counts. |
colorHex |
string | always present | may be null. encrypted. A 6-digit hex colour, with or without the leading #. |
colorStyle |
text, fill |
always present | may be null. fill for any colour set since September 2026 (a colour is a highlight behind the row, and the apps draw it that way whatever this says); text on older rows; null with no colour. |
reminderTime |
string | always present | may be null. encrypted. A LOCAL-NAIVE 24-hour instant, yyyy-MM-ddTHH:mm: no seconds, no offset, no Z. It means that wall-clock time on the device that fires it, so it never shifts when the user travels. |
recurrenceRule |
string | always present | may be null. encrypted. The recurrence rule. null = a one-off to-do. |
recurrenceAnchor |
string (yyyy-MM-dd) | always present | may be null. yyyy-MM-dd. Server-derived. The date the series is anchored to (its grid starts here). /complete moves whenDate to the next occurrence and leaves this where it is. |
completedAt |
string (RFC 3339) | always present | may be null. server-derived. Stamped by /complete, cleared by /uncomplete. |
trashedAt |
string (RFC 3339) | always present | may be null. server-derived. Set by /trash, cleared by /restore; null means the row is live. |
sortKey |
string | always present | Server-issued fractional ordering key. The stated order of every content list is (sortKey, id). Opaque: compare it, never compute one. |
whenTime |
string | always present | may be null. encrypted. The start time on whenDate, HH:mm 24-hour, local-naive (it stays 09:00 when the user travels). null = no start (an all-day to-do). Always null while there is no whenDate. |
durationMin |
integer | always present | may be null. min -9007199254740991, max 9007199254740991. encrypted. The length in minutes, 5 to 1440. It can exist without a start: it is the block’s length once the to-do gets one. |
reminders |
array of ScheduleReminder | always present | Every reminder, at most 5, in the order they ring. reminderTime is the earliest of them. Always present; [] when there are none. A to-do written before 2026-10-05 with only a reminderTime reads as one at reminder. |
subtasks |
array of Subtask | always present | The checklist inside the to-do, in order: at most 50. A subtask is a title and a tick only, never a date, tag or note. Always present; [] when there are none. |
type |
string | always present | Always "todo". Branch on this; never on which other members happen to be present. |
purgesAt |
string (RFC 3339) | always present | server-derived. Server-derived: trashedAt + 30 days, the instant this row becomes eligible for the automatic purge. |
daysLeft |
integer | always present | min -9007199254740991, max 9007199254740991. server-derived. Server-derived: whole days until purgesAt, rounded UP, never below 0: ceil((purgesAt − now) / 24 h). The apps show it as “28 days left”, in red at 5 or fewer. |
Webhook
| field | type | notes | |
|---|---|---|---|
id |
string | always present | wh_ + base64url, NOT a UUID. |
url |
string | always present | The https endpoint deliveries are POSTed to. Sealed at rest. |
events |
array of todo.created, todo.updated, todo.deleted, note.created, note.updated, note.deleted, note_folder.created, note_folder.updated, note_folder.deleted, note.linked, note.unlinked, note.place_added, note.place_removed, note.note_linked, note.note_unlinked, note_version.created, note_version.updated, note_version.deleted, container.created, container.updated, container.deleted, heading.created, heading.updated, heading.deleted, inbox.created, inbox.updated, inbox.deleted, tag.created, tag.updated, tag.deleted, filter.created, filter.updated, filter.deleted, attachment.created, attachment.updated, attachment.deleted, attachment_place.created, attachment_place.updated, attachment_place.deleted, webhook.ping, webhook.disabled |
always present | |
description |
string | always present | may be null |
active |
boolean | always present | The server sets this to false after three days of failed deliveries; GET /me counts how many were disabled that way. PATCH it back to true once the endpoint is fixed. Deliveries still waiting when it went off are not replayed: they are closed as failed, and can be redelivered. |
createdAt |
string (RFC 3339) | always present | server-derived |
WebhookCreated
| field | type | notes | |
|---|---|---|---|
id |
string | always present | wh_ + base64url, NOT a UUID. |
url |
string | always present | The https endpoint deliveries are POSTed to. Sealed at rest. |
events |
array of todo.created, todo.updated, todo.deleted, note.created, note.updated, note.deleted, note_folder.created, note_folder.updated, note_folder.deleted, note.linked, note.unlinked, note.place_added, note.place_removed, note.note_linked, note.note_unlinked, note_version.created, note_version.updated, note_version.deleted, container.created, container.updated, container.deleted, heading.created, heading.updated, heading.deleted, inbox.created, inbox.updated, inbox.deleted, tag.created, tag.updated, tag.deleted, filter.created, filter.updated, filter.deleted, attachment.created, attachment.updated, attachment.deleted, attachment_place.created, attachment_place.updated, attachment_place.deleted, webhook.ping, webhook.disabled |
always present | |
description |
string | always present | may be null |
active |
boolean | always present | The server sets this to false after three days of failed deliveries; GET /me counts how many were disabled that way. PATCH it back to true once the endpoint is fixed. Deliveries still waiting when it went off are not replayed: they are closed as failed, and can be redelivered. |
createdAt |
string (RFC 3339) | always present | server-derived |
secret |
string | always present | The signing secret, whsec_…, returned exactly once and never re-shown. Verify every delivery’s X-InitTasks-Signature with it; if it is lost, rotate. |
WebhookList
| field | type | notes | |
|---|---|---|---|
data |
array of Webhook | always present |
WebhookRotated
| field | type | notes | |
|---|---|---|---|
id |
string | always present | wh_ + base64url, NOT a UUID. |
url |
string | always present | The https endpoint deliveries are POSTed to. Sealed at rest. |
events |
array of todo.created, todo.updated, todo.deleted, note.created, note.updated, note.deleted, note_folder.created, note_folder.updated, note_folder.deleted, note.linked, note.unlinked, note.place_added, note.place_removed, note.note_linked, note.note_unlinked, note_version.created, note_version.updated, note_version.deleted, container.created, container.updated, container.deleted, heading.created, heading.updated, heading.deleted, inbox.created, inbox.updated, inbox.deleted, tag.created, tag.updated, tag.deleted, filter.created, filter.updated, filter.deleted, attachment.created, attachment.updated, attachment.deleted, attachment_place.created, attachment_place.updated, attachment_place.deleted, webhook.ping, webhook.disabled |
always present | |
description |
string | always present | may be null |
active |
boolean | always present | The server sets this to false after three days of failed deliveries; GET /me counts how many were disabled that way. PATCH it back to true once the endpoint is fixed. Deliveries still waiting when it went off are not replayed: they are closed as failed, and can be redelivered. |
createdAt |
string (RFC 3339) | always present | server-derived |
secret |
string | always present | The signing secret, whsec_…, returned exactly once and never re-shown. Verify every delivery’s X-InitTasks-Signature with it; if it is lost, rotate. |
previousSecretValidUntil |
string (RFC 3339) | always present | The PREVIOUS secret keeps verifying until this instant (24 h), and both secrets sign every delivery meanwhile, so a subscriber can deploy the new one without dropping the events that arrive mid-deploy. |