API reference
Tasks & Reminders API
Tasks are first-class, syncable to-dos — standalone or embedded in a note. Notes can also carry a lightweight reminder of their own.
Tasks are their own records — a client-generated UUID, a title, and scheduling
fields — that sync across devices like notes do (every write allocates a fresh
USN; deletes are tombstones). Reminders are simpler: a pair of timestamp fields
on a note itself. Everything on this page requires a bearer token with the
notes scope.
The task object
A task is just a title plus scheduling fields — there is no assignee, and no body of its own. For richer detail, embed the task in a note.
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Client-generated; stable across devices. |
note_id | string | Owning note id, or "" for a standalone task. |
title | string | Short plaintext label. |
due_at | int | null | Due moment, epoch-ms UTC. |
due_has_time | bool | true (default) = date+time; false = date-only, clients ignore the time portion. Only meaningful when due_at is set. |
reminder_at | int | null | Reminder moment, epoch-ms UTC. Stored and served only — notifications are your client’s job. |
recurrence | string | null | Recurrence rule — see Due dates & recurrence. |
priority | string | none | low | medium | high. Default none. |
flag | bool | Simple flagged/starred marker. |
done_at | int | null | Completion moment, epoch-ms. null = not done. |
position | int | Ordering index within its list or note (lower sorts first). |
usn | int | Server-assigned sync ordering. |
deleted | bool | Tombstone (soft-delete). |
created_at / updated_at | int | Epoch-ms UTC. |
{
"id": "9c2e7b10-4f6d-4c1a-9d3e-2b8a51c47f0a",
"note_id": "",
"title": "Renew passport",
"due_at": 1751000000000,
"due_has_time": true,
"reminder_at": null,
"recurrence": "yearly",
"priority": "high",
"flag": false,
"done_at": null,
"position": 0,
"usn": 12,
"deleted": false,
"created_at": 1750000000000,
"updated_at": 1750000000000
}
Every task mutation returns the task plus its newly assigned USN:
{ "task": { … }, "usn": N }.
Due dates & recurrence
Date-only vs timed. due_at is always a full timestamp, but due_has_time
says whether the time part means anything. Set due_has_time: false for a
“due Friday” style task; leave it (or set true) for “due Friday at 3pm”.
Recurrence rules. recurrence accepts two formats, validated on write
(unparseable values are rejected with 422 invalid_recurrence):
- Simple rules:
daily,weekly,monthly,yearly, andevery:N:days/every:N:weeks/every:N:months/every:N:years(N ≥ 1). Stored lower-cased and trimmed. - iCalendar RRULE (RFC 5545): any value starting with
FREQ=(anRRULE:prefix is fine), supportingFREQ(DAILY/WEEKLY/MONTHLY/YEARLY),INTERVAL,BYDAY(weekdays and nth-weekday like1FR/-1FR),BYMONTHDAY(1–31, or a negative day counted back from the end of the month —-1is the last day,-2the day before it), and anUNTIL/COUNTend condition. Stored verbatim, and case-sensitive: write it in upper case, becausefreq=monthlyis rejected.
| Example | Meaning |
|---|---|
every:2:weeks | every 2 weeks |
FREQ=WEEKLY;BYDAY=MO,WE,FR | weekly on Mon/Wed/Fri |
FREQ=MONTHLY;BYDAY=-1FR | monthly on the last Friday |
FREQ=MONTHLY;BYMONTHDAY=-1 | monthly on the last day of the month |
FREQ=WEEKLY;BYDAY=FR;UNTIL=20261231T235959Z | weekly on Friday until Dec 31 2026 |
Those middle two rows are easy to mix up. BYDAY=-1FR is the last Friday,
which in April 2026 is the 24th. BYMONTHDAY=-1 is the last day, which is
the 30th.
There is no DTSTART — the task’s due date anchors the series, and each
completion re-anchors it at the new due date.
Completing a recurring task advances it. POST /tasks/:id/done on a task
with a recurrence does not set done_at; instead the same task rolls forward
to its next occurrence — due_at and reminder_at advance, reminder_at
keeps its lead time relative to due_at, and done_at stays null. Simple
rules roll forward as fixed UTC intervals; RRULE occurrences are computed in
the user’s timezone, so BYDAY and BYMONTHDAY land on the right calendar
day. A recurring task with neither due_at nor reminder_at has nothing to
advance and simply completes.
UNTIL ends a series: once the last occurrence has passed, completing the task
completes it for good and it stops recurring. COUNT is accepted on write but
does not currently end a series — because each completion re-anchors the
rule at the new due date, the count starts over and the task repeats
indefinitely. Use UNTIL when you need a series to stop.
What happens at the end of a month
A task due on the 29th, 30th or 31st has to do something in a month that short, and the two formats do different things. The difference is worth spelling out. Take a task due Saturday 31 January 2026 and complete it over and over:
| Rule | The next few due dates | What it does |
|---|---|---|
monthly | Mar 3, Apr 3, May 3 | Overflows into the next month, then stays there |
FREQ=MONTHLY;BYMONTHDAY=31 | Mar 31, May 31, Jul 31 | Skips months with no 31st |
FREQ=MONTHLY;BYMONTHDAY=-1 | Feb 28, Mar 31, Apr 30 | Lands on the real last day, every month |
monthly overflows, then drifts. It adds one calendar month and keeps the
day number, so 31 January becomes “31 February” — which is really 3 March. The
task never finds its way back to the 31st: from then on it is a task due on the
3rd. The same happens to yearly on a leap day (29 Feb 2028 becomes 1 Mar
2029, and stays on the 1st), and to every:N:months whenever it lands on a
short month — every:2:months from 31 January gets as far as Mar 31, May 31
and Jul 31 before September pushes it to 1 October.
This behaviour may change — don’t depend on it. If a task needs to land on a particular day near the end of the month, use an RRULE.
BYMONTHDAY=31 skips. RFC 5545 leaves out dates that don’t exist rather
than moving them, so a task on the 31st simply doesn’t occur in February,
April, June, September or November. That is the right rule for “the 31st or not
at all” and the wrong one for “the end of every month”. A bare FREQ=MONTHLY
behaves the same way, because it takes its day number from the task’s due date.
BYMONTHDAY=-1 is the one that means “end of the month”. It resolves to
whatever the last day actually is — Feb 28, Mar 31, Apr 30 — and never skips a
month. INTERVAL works alongside it: FREQ=MONTHLY;INTERVAL=3;BYMONTHDAY=-1
from 31 January gives Apr 30, Jul 31, Oct 31.
The Harbor apps don’t offer “last day of the month” in their repeat pickers yet, so for now this is a rule you set through the API. A task configured this way keeps its rule, but the Apple apps currently summarise it as “day -1”.
Tasks inside notes
A note embeds a task with a <harbor-task id="<task-uuid>"> element (only the
id attribute is allowed). On every note write the server derives the
note↔task linkage from these blocks: a referenced task is claimed by the note,
and a task whose block was removed is deleted (tombstoned) — not detached
back to standalone. That makes cut/paste-moving a task between notes
unsupported: the first note’s save deletes the task before the second note’s
save can re-claim it. Linkage extraction is skipped for encrypted notes, so an
encrypted note’s tasks are not aggregated or indexed. A note’s “N of M done”
progress is derivable by counting done_at over
GET /notes/:id/tasks.
Create a task
POST /api/v1/tasks · scope: notes
All fields are optional. Pass your own id to create a task minted offline;
omit it and the server generates one.
| Field | Type | Required | Description |
|---|---|---|---|
id | string (UUID) | no | Client UUID; generated when omitted. Duplicate id → 409 conflict. |
note_id | string | no | Owning note id; "" or omitted = standalone. |
title | string | no | |
due_at | int (epoch-ms) | no | |
due_has_time | bool | no | false for a date-only due. Omitted defaults to true. |
reminder_at | int (epoch-ms) | no | |
recurrence | string | no | See Due dates & recurrence. |
priority | string | no | none / low / medium / high. Default none. |
flag | bool | no | |
position | int | no |
curl https://app.harbor.my/api/v1/tasks \
-H "Authorization: Bearer $HARBOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Renew passport",
"due_at": 1751000000000,
"priority": "high",
"recurrence": "yearly"
}'
Response 201 Created:
{
"task": {
"id": "9c2e7b10-4f6d-4c1a-9d3e-2b8a51c47f0a",
"note_id": "",
"title": "Renew passport",
"due_at": 1751000000000,
"due_has_time": true,
"reminder_at": null,
"recurrence": "yearly",
"priority": "high",
"flag": false,
"done_at": null,
"position": 0,
"usn": 12,
"deleted": false,
"created_at": 1750000000000,
"updated_at": 1750000000000
},
"usn": 12
}
Errors:
422 validation_failed— bad id or invalid JSON.422 invalid_priority/422 invalid_recurrence— bad enum or rule.409 conflict— the suppliedidalready exists.
Python
import os
import requests
BASE = "https://app.harbor.my/api/v1"
headers = {"Authorization": f"Bearer {os.environ['HARBOR_TOKEN']}"}
resp = requests.post(
f"{BASE}/tasks",
headers=headers,
json={
"title": "Renew passport",
"due_at": 1751000000000,
"priority": "high",
"recurrence": "yearly",
},
)
resp.raise_for_status()
body = resp.json()
print(body["task"]["id"], "usn", body["usn"])
JavaScript
const BASE = "https://app.harbor.my/api/v1";
const res = await fetch(`${BASE}/tasks`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.HARBOR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "Renew passport",
due_at: 1751000000000,
priority: "high",
recurrence: "yearly",
}),
});
const { task, usn } = await res.json();
console.log(task.id, "usn", usn);
Go
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
const base = "https://app.harbor.my/api/v1"
func main() {
payload, _ := json.Marshal(map[string]any{
"title": "Renew passport",
"due_at": 1751000000000,
"priority": "high",
"recurrence": "yearly",
})
req, _ := http.NewRequest("POST", base+"/tasks", bytes.NewReader(payload))
req.Header.Set("Authorization", "Bearer "+os.Getenv("HARBOR_TOKEN"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var out struct {
Task struct {
ID string `json:"id"`
} `json:"task"`
USN int `json:"usn"`
}
json.NewDecoder(res.Body).Decode(&out)
fmt.Println(out.Task.ID, "usn", out.USN)
}
List tasks
GET /api/v1/tasks · scope: notes
The aggregated task list across all notes plus standalone tasks. Tombstoned tasks are never returned.
| Field | Type | Required | Description |
|---|---|---|---|
limit | int | no | Default 100, hard cap 500 (clamped). |
offset | int | no | Default 0. |
order | string | no | Default due (asc), then usn. Sortable: due, priority, created, updated, position, usn; prefix - for descending. |
status | string | no | Default active (= not done). today = not done and due today (server-local day); done; all. |
due_before | int (epoch-ms) | no | Only tasks with due_at <= this value. |
note_id | string | no | Only tasks owned by that note; the literal none selects standalone tasks. |
curl "https://app.harbor.my/api/v1/tasks?status=today&order=due&limit=50" \
-H "Authorization: Bearer $HARBOR_TOKEN"
Response 200 OK:
{
"data": [
{
"id": "9c2e7b10-4f6d-4c1a-9d3e-2b8a51c47f0a",
"note_id": "",
"title": "Renew passport",
"due_at": 1751000000000,
"due_has_time": true,
"reminder_at": null,
"recurrence": "yearly",
"priority": "high",
"flag": false,
"done_at": null,
"position": 0,
"usn": 12,
"deleted": false,
"created_at": 1750000000000,
"updated_at": 1750000000000
}
],
"paging": { "limit": 50, "offset": 0, "total": 1, "has_more": false }
}
Errors:
422 validation_failed— unknown sort field, invalidstatus, or malformeddue_before.
One quirk worth knowing: order=priority sorts the stored string lexically
(high < low < medium < none), not semantically — pick the direction
that fits your view.
Python
import os
import requests
BASE = "https://app.harbor.my/api/v1"
headers = {"Authorization": f"Bearer {os.environ['HARBOR_TOKEN']}"}
resp = requests.get(
f"{BASE}/tasks",
headers=headers,
params={"status": "today", "order": "due", "limit": 50},
)
resp.raise_for_status()
for task in resp.json()["data"]:
print(task["title"], task["due_at"])
JavaScript
const BASE = "https://app.harbor.my/api/v1";
const params = new URLSearchParams({ status: "today", order: "due", limit: "50" });
const res = await fetch(`${BASE}/tasks?${params}`, {
headers: { Authorization: `Bearer ${process.env.HARBOR_TOKEN}` },
});
const { data, paging } = await res.json();
for (const task of data) console.log(task.title, task.due_at);
console.log("total:", paging.total);
Go
package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
const base = "https://app.harbor.my/api/v1"
func main() {
req, _ := http.NewRequest("GET", base+"/tasks?status=today&order=due&limit=50", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("HARBOR_TOKEN"))
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var out struct {
Data []struct {
Title string `json:"title"`
DueAt int64 `json:"due_at"`
} `json:"data"`
}
json.NewDecoder(res.Body).Decode(&out)
for _, t := range out.Data {
fmt.Println(t.Title, t.DueAt)
}
}
Get a task
GET /api/v1/tasks/:id · scope: notes
Fetch a single live task by UUID.
curl https://app.harbor.my/api/v1/tasks/9c2e7b10-4f6d-4c1a-9d3e-2b8a51c47f0a \
-H "Authorization: Bearer $HARBOR_TOKEN"
Response 200 OK: { "task": { … }, "usn": 12 } — the full
task object.
Errors:
404 not_found— no such task, or it has been tombstoned.
Update a task
PATCH /api/v1/tasks/:id · scope: notes
Partial update, last-write-wins: only the fields present in the body change,
and a fresh USN is allocated. Because JSON null and “field omitted” are
indistinguishable in a PATCH, nullable fields have explicit clear_* booleans.
done_at is not updatable here — completion goes through
POST /tasks/:id/done so recurrence is handled correctly.
| Field | Type | Required | Description |
|---|---|---|---|
note_id | string | no | Set the owning note; "" = standalone. |
title | string | no | |
due_at | int (epoch-ms) | no | |
clear_due_at | bool | no | true nulls due_at (ignored if due_at is also sent). |
due_has_time | bool | no | Toggle date-only (false) vs timed (true). |
reminder_at | int (epoch-ms) | no | |
clear_reminder_at | bool | no | true nulls reminder_at. |
recurrence | string | no | See Due dates & recurrence. |
clear_recurrence | bool | no | true nulls recurrence. |
priority | string | no | none / low / medium / high. |
flag | bool | no | |
position | int | no |
curl -X PATCH https://app.harbor.my/api/v1/tasks/9c2e7b10-4f6d-4c1a-9d3e-2b8a51c47f0a \
-H "Authorization: Bearer $HARBOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Renew US passport",
"priority": "medium",
"clear_recurrence": true
}'
Response 200 OK:
{
"task": {
"id": "9c2e7b10-4f6d-4c1a-9d3e-2b8a51c47f0a",
"title": "Renew US passport",
"priority": "medium",
"recurrence": null,
"done_at": null,
"usn": 13,
"deleted": false
},
"usn": 13
}
Errors:
404 not_found— no such live task.422 invalid_priority/422 invalid_recurrence— bad enum or rule.422 validation_failed— invalid JSON.
Delete a task
DELETE /api/v1/tasks/:id · scope: notes
Soft-delete (tombstone) a task with a fresh USN so the deletion propagates to
every device. Deleting a note-linked task also strips its <harbor-task> block
from the owning note in the same transaction (the note is re-derived and its
USN bumped). This cleanup is a no-op for standalone tasks; for an encrypted
owning note the server cannot edit ciphertext, so the client self-heals the
dangling block instead.
curl -X DELETE https://app.harbor.my/api/v1/tasks/9c2e7b10-4f6d-4c1a-9d3e-2b8a51c47f0a \
-H "Authorization: Bearer $HARBOR_TOKEN"
Response 204 No Content.
Errors:
404 not_found— missing or already tombstoned.
Complete a task
POST /api/v1/tasks/:id/done · scope: notes
Mark a task done. A non-recurring task gets done_at set (defaulting to the
server’s current time). A recurring task instead advances to its next
occurrence — done_at stays null and due_at/reminder_at roll forward
(see Due dates & recurrence).
| Field | Type | Required | Description |
|---|---|---|---|
done_time | int (epoch-ms) | no | Completion time for a non-recurring task; defaults to now. Must be >= 0. Ignored for a recurring advance. |
curl -X POST https://app.harbor.my/api/v1/tasks/9c2e7b10-4f6d-4c1a-9d3e-2b8a51c47f0a/done \
-H "Authorization: Bearer $HARBOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "done_time": 1750090000000 }'
Response 200 OK (non-recurring):
{
"task": {
"id": "9c2e7b10-4f6d-4c1a-9d3e-2b8a51c47f0a",
"title": "Renew US passport",
"done_at": 1750090000000,
"usn": 14,
"deleted": false
},
"usn": 14
}
For a recurring task the returned due_at is the next occurrence and
done_at is null.
Errors:
404 not_found— no such live task.422 validation_failed— negativedone_timeor invalid JSON.
Reopen a task
DELETE /api/v1/tasks/:id/done · scope: notes
Undo completion by nulling done_at, with a fresh USN. Idempotent — reopening
an already-open task just re-numbers it. Does not rewind recurrence.
curl -X DELETE https://app.harbor.my/api/v1/tasks/9c2e7b10-4f6d-4c1a-9d3e-2b8a51c47f0a/done \
-H "Authorization: Bearer $HARBOR_TOKEN"
Response 200 OK:
{
"task": {
"id": "9c2e7b10-4f6d-4c1a-9d3e-2b8a51c47f0a",
"done_at": null,
"usn": 15,
"deleted": false
},
"usn": 15
}
Errors:
404 not_found— no such live task.
List a note’s tasks
GET /api/v1/notes/:id/tasks · scope: notes
The tasks owned by a note (its <harbor-task> blocks), in stable in-note
order.
| Field | Type | Required | Description |
|---|---|---|---|
limit | int | no | Default 100, cap 500. |
offset | int | no | Default 0. |
order | string | no | Default position (asc), then created. Sortable: position, created, updated, due, usn. |
curl https://app.harbor.my/api/v1/notes/a1b2c3d4-8e2f-4b7a-9c0d-6f5e4d3c2b1a/tasks \
-H "Authorization: Bearer $HARBOR_TOKEN"
Response 200 OK:
{
"data": [
{
"id": "9c2e7b10-4f6d-4c1a-9d3e-2b8a51c47f0a",
"note_id": "a1b2c3d4-8e2f-4b7a-9c0d-6f5e4d3c2b1a",
"title": "Renew passport",
"position": 0,
"done_at": null,
"usn": 12,
"deleted": false
}
],
"paging": { "limit": 100, "offset": 0, "total": 1, "has_more": false }
}
Errors:
404 not_found— the note is missing or expunged.
Note reminders
A reminder is not a separate record — it is the reminder_time and
reminder_done_time fields (both epoch-ms UTC) on the note row itself, so it
syncs with the note’s USN machinery. A note “is a reminder” if and only if
reminder_time is non-null; a set reminder_done_time marks it completed but
keeps it listed under “done”. Every mutation below allocates a fresh USN and
returns { "note": { … }, "usn": N }.
Two rules apply across all reminder endpoints:
- Trash rule: a trashed note returns
409 note_in_trash(restore it first); a missing or expunged note returns404. - Notifications are out of scope — the API stores and serves reminder state; delivering the notification is your client’s job.
Encrypted-note reminders are included in the list (the times are not secret),
but the note’s title stays ciphertext for the client to decrypt.
List reminders
GET /api/v1/reminders · scope: notes
List the user’s reminders — live, non-trashed notes with reminder_time set.
Returns a collection of note objects.
| Field | Type | Required | Description |
|---|---|---|---|
limit | int | no | Default 100, hard cap 500 (clamped). |
offset | int | no | Default 0. |
order | string | no | Default reminder_time (asc). Sortable: reminder_time, updated_at, created_at, usn; prefix - for descending. |
status | string | no | Default active (active/upcoming = not completed; done/completed = completed; all). |
due_before | int (epoch-ms) | no | Only reminders with reminder_time <= this — an “upcoming/overdue” view. |
curl "https://app.harbor.my/api/v1/reminders?status=active&due_before=1750200000000" \
-H "Authorization: Bearer $HARBOR_TOKEN"
Response 200 OK:
{
"data": [
{
"id": "f4d8a6b2-1c3e-4f5a-8b7d-9e0c2a4b6d8f",
"title": "Pay invoice",
"notebook_id": "5b1f2c9a-7d3e-4a1b-8c6f-2e9d0b4a7c5e",
"reminder_time": 1750100000000,
"is_encrypted": false,
"usn": 95,
"deleted": false,
"updated_at": 1750000000000,
"created_at": 1749000000000
}
],
"paging": { "limit": 100, "offset": 0, "total": 1, "has_more": false }
}
Errors:
422 validation_failed— unknown sort field, invalidstatus, or malformeddue_before.
Set a note’s reminder
PUT /api/v1/notes/:id/reminder · scope: notes
Set or update a note’s reminder_time. POST /api/v1/notes/:id/reminder is an
equivalent alternate. Setting a time does not clear an existing
reminder_done_time — re-arm a completed reminder explicitly via the clear and
complete endpoints.
| Field | Type | Required | Description |
|---|---|---|---|
reminder_time | int (epoch-ms) | yes | The due moment, UTC. Must be >= 0. |
curl -X PUT https://app.harbor.my/api/v1/notes/f4d8a6b2-1c3e-4f5a-8b7d-9e0c2a4b6d8f/reminder \
-H "Authorization: Bearer $HARBOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "reminder_time": 1750100000000 }'
Response 200 OK:
{
"note": {
"id": "f4d8a6b2-1c3e-4f5a-8b7d-9e0c2a4b6d8f",
"title": "Pay invoice",
"reminder_time": 1750100000000,
"usn": 96
},
"usn": 96
}
Errors:
404 not_found— no live note.409 note_in_trash— restore the note first.422 validation_failed— missing or negativereminder_time, or invalid JSON.
Complete a note’s reminder
POST /api/v1/notes/:id/reminder/done · scope: notes
Mark a reminder done by setting reminder_done_time (defaults to the server’s
current time). reminder_time is kept, so the note stays listed under “done”.
Only a note that is a reminder can be completed.
POST /api/v1/notes/:id/reminder/complete is an equivalent alias.
| Field | Type | Required | Description |
|---|---|---|---|
done_time | int (epoch-ms) | no | Completion time; defaults to now. Must be >= 0. |
curl -X POST https://app.harbor.my/api/v1/notes/f4d8a6b2-1c3e-4f5a-8b7d-9e0c2a4b6d8f/reminder/done \
-H "Authorization: Bearer $HARBOR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "done_time": 1750090000000 }'
Response 200 OK:
{
"note": {
"id": "f4d8a6b2-1c3e-4f5a-8b7d-9e0c2a4b6d8f",
"title": "Pay invoice",
"reminder_time": 1750100000000,
"usn": 97
},
"usn": 97
}
Errors:
404 not_found— no live note.409 note_in_trash— restore the note first.422 not_a_reminder— the note has noreminder_timeset.422 validation_failed— negativedone_time, or invalid JSON.
Clear a note’s reminder
DELETE /api/v1/notes/:id/reminder · scope: notes
Remove a note’s reminder entirely: nulls both reminder_time and
reminder_done_time. Idempotent — clearing a note with no reminder still
succeeds and returns the re-numbered note.
curl -X DELETE https://app.harbor.my/api/v1/notes/f4d8a6b2-1c3e-4f5a-8b7d-9e0c2a4b6d8f/reminder \
-H "Authorization: Bearer $HARBOR_TOKEN"
Response 200 OK:
{
"note": {
"id": "f4d8a6b2-1c3e-4f5a-8b7d-9e0c2a4b6d8f",
"title": "Pay invoice",
"usn": 98
},
"usn": 98
}
Errors:
404 not_found— no live note.409 note_in_trash— restore the note first.
Related
- Notes API — the notes tasks embed in, and the note object returned by the reminder endpoints.
- API conventions — envelopes, pagination, timestamps, and the USN sync model.
- Errors — the error envelope and the full catalog of error codes.