- Inbox — your personal feed of agent-delivered messages (for example, scheduled-task digests). It is scoped to you alone; admins never see another user’s inbox. Inbox messages carry rich content and can be deleted.
- Notifications — the workspace notification center: async results a tenant should see (recommendations, profile-ready, setup nudges, billing). Items can be addressed to you or be workspace-wide (visible to any member), and they are dismissed rather than deleted.
Bearer token and live under /v1/api.
Every request authenticates with
Authorization: Bearer hq_pat_.... All nine endpoints below accept either a personal access token (bearer_pat) or an oauth2 token.What each item carries
The two list payloads are shaped differently because the surfaces solve different problems. An inbox message (List inbox) carriesid, source_kind, schedule_id, schedule_name, title, body_markdown, ui_strings, delivered_at, and read_at. The body is Markdown, and when the message came from a schedule fire it includes the originating schedule’s id and name so the UI can group and link. Read state is a timestamp: read_at is null while unread.
A notification (List notifications) carries id, kind, title, body (optional), cta (optional), severity, status, and created_at. The body is optional plain text, there is an optional call-to-action (cta), and read state is an explicit status string (unread, read, or dismissed).
Read state differs between surfaces. The inbox tracks a
read_at timestamp (null = unread). Notifications track a status string. That is why the inbox supports re-marking a message unread, but notifications do not.The inbox
List your inbox
GET /v1/api/inbox returns one page of your messages, newest delivery first.ListResp: messages (the page), unread_count (unread across your whole inbox — drives the nav badge, independent of the current page/filter), total (rows matching the filter before paging), page, and page_size.Supported query params:unread=true— only messages whoseread_atis null.q=<text>— case-insensitive substring search over the title, body, and (for schedule digests) the schedule name.page=<n>— 1-based page index, clamped to>= 1.page_size=<n>— rows per page, clamped to1..=100, defaults to25.sort=recent(default, newest first) orsort=oldest.
Mark one message read or unread
Reading an inbox message just sets (or clears) its Both return
read_at timestamp.{ "ok": true } (mark read, mark unread). Because the lookup is scoped to your own inbox, a message that does not exist — or is not yours — returns 404.Mark the whole inbox read
POST /v1/api/inbox/read_all marks all of your unread messages read. It is idempotent — it returns ok even when nothing was unread.Delete a message
The inbox is the only surface where items are permanently deleted.Returns
{ "ok": true }, or 404 if the message does not exist or is not yours. See Delete inbox message.The notification center
List notifications
GET /v1/api/notifications returns up to 100 non-dismissed notifications, newest first. There are no query params — no filters, no pagination.NotificationsResp: items and unread (how many of the returned-scope rows are still unread — drives the bell badge). The scope includes notifications addressed to you and workspace-wide ones visible to any member. Dismissed notifications are excluded. See List notifications.Mark one notification read
POST /v1/api/notifications/{id}/read flips an unread notification to read and records the read time.unread state and always returns { "ok": true }. See Mark notification read.Mark all notifications read
POST /v1/api/notifications/read-all marks all of your unread notifications read and returns the count.read_all (which returns ok), this returns { "updated": <n> } — the number of rows updated. See Mark all notifications read.Dismiss a notification
Notifications are not deleted; they are dismissed. Always returns
POST /v1/api/notifications/{id}/dismiss sets status to dismissed, records the dismiss time, and removes it from future list responses.{ "ok": true }. See Dismiss notification.There is no “un-dismiss” and no inbox-style unread toggle for notifications. Dismissing is one-way: the item drops out of the list permanently.
Key differences at a glance
- Scope. Inbox is per-user (
owner_user_id); notifications are per-workspace and may be addressed to you or visible to every member. - Read state. Inbox uses a
read_attimestamp and supports re-marking unread; notifications use astatusstring and do not. - Removal. Inbox messages are
DELETEd; notifications are dismissed (and disappear from the list, but are not re-markable). - Listing. The inbox supports unread filtering, search, pagination, and sort; the notification list takes no params and caps at 100 newest non-dismissed items.
- Badges. Inbox
unread_countis whole-inbox; notificationunreadis over the returned scope. - Mark-all response. Inbox
read_allreturns{ "ok": true }; notificationsread-allreturns{ "updated": <n> }.