Notifications
Your notification centre: tasks given to you, due or overdue, deals of yours assigned, won or lost, your approval requests decided; which of them also come by e-mail.
| Operation | Summary | Scope | Idempotency-Key |
|---|---|---|---|
GET /v1/me/notification-settings |
Get which notifications come by e-mail | read |
|
PUT /v1/me/notification-settings |
Choose which notifications come by e-mail | read |
|
GET /v1/me/notifications |
List your notifications | read |
|
POST /v1/me/notifications/read |
Mark notifications read | read |
GET /v1/me/notification-settings
Get which notifications come by e-mail
The kinds of notification you also get by e-mail (none until you choose), to your sign-in
address, gathered into one message per sending, and whether this system sends e-mail at all
(email_available: never from a test copy). 409 for an API key or an agent.
| Required scope | read (admin implies every scope) |
| Operation id | get_notification_settings_v1_me_notification_settings_get |
Example request
curl "$ERP_URL/v1/me/notification-settings" \
-H "Authorization: Bearer $ERP_KEY"
Responses
| Status | Meaning | Body |
|---|---|---|
| 200 | OK | NotificationSettingsOut |
| 401 | Missing or invalid API key (unauthorized). |
ErrorEnvelope |
| 403 | The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). |
ErrorEnvelope |
| 422 | Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. |
HTTPValidationError |
Example response (shape)
{
"email_kinds": [
"task_assigned",
"task_due"
]
}
PUT /v1/me/notification-settings
Choose which notifications come by e-mail
Choose the kinds you also get by e-mail; an empty list stops every e-mail. What is already in the centre is not e-mailed afterwards. 409 for an API key or an agent.
| Required scope | read (admin implies every scope) |
| Idempotency-Key | not used |
| Operation id | put_notification_settings_v1_me_notification_settings_put |
Request body
application/json (required): NotificationSettings
| Field | Type | Required | Description |
|---|---|---|---|
email_kinds |
array of "approval_decided" | "deal_assigned" | "deal_lost" | "deal_won" | "task_assigned" | "task_due" | "task_overdue" | "webhook_disabled" |
yes | The kinds you also get by e-mail (none by default). Every notification is in the notification centre whatever this says. |
Example request
curl -X PUT "$ERP_URL/v1/me/notification-settings" \
-H "Authorization: Bearer $ERP_KEY" \
-H "Content-Type: application/json" \
-d '{
"email_kinds": [
"task_assigned",
"task_due"
]
}'
Responses
| Status | Meaning | Body |
|---|---|---|
| 200 | OK | NotificationSettingsOut |
| 401 | Missing or invalid API key (unauthorized). |
ErrorEnvelope |
| 403 | The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). |
ErrorEnvelope |
| 409 | The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). |
ErrorEnvelope |
| 422 | Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. |
HTTPValidationError |
Example response (shape)
{
"email_kinds": [
"task_assigned",
"task_due"
]
}
GET /v1/me/notifications
List your notifications
Your notification centre, the newest first: tasks given to you, due or overdue, deals of
yours assigned, won or lost by someone else, your approval requests decided, and (for
administrators) a webhook stopped because it kept failing. Reading it also writes the task
reminders that came due since (a task of yours reminds you the day it is due and once more
when that day passed; one whose day passed more than 7 days ago no longer does). unread is
the count of unread ones, approvals_waiting the approval requests you may decide now. A key
or an agent of a person (an AI assistant) reads that person's list, without marking anything
read; one the system issued has none: the list is empty.
| Required scope | read (admin implies every scope) |
| Operation id | list_notifications_v1_me_notifications_get |
Parameters
| In | Name | Type | Required | Description |
|---|---|---|---|---|
| query | unread |
boolean | Only the unread ones. (default false) |
|
| query | limit |
integer | Most returned, the newest first. (min 1; max 200; default 50) |
Example request
curl "$ERP_URL/v1/me/notifications" \
-H "Authorization: Bearer $ERP_KEY"
Responses
| Status | Meaning | Body |
|---|---|---|
| 200 | OK | NotificationList |
| 401 | Missing or invalid API key (unauthorized). |
ErrorEnvelope |
| 403 | The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). |
ErrorEnvelope |
| 422 | Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. |
HTTPValidationError |
Example response (shape)
{
"unread": 1,
"approvals_waiting": 1,
"items": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"kind": "approval_decided",
"params": {},
"link": "string",
"created_at": "2026-09-21T09:30:00Z",
"read_at": "2026-09-21T09:30:00Z"
}
]
}
POST /v1/me/notifications/read
Mark notifications read
Mark the given notifications of yours (ids), or every unread one (all), read. Returns
your list as GET /v1/me/notifications does. 409 for an API key or an agent.
| Required scope | read (admin implies every scope) |
| Idempotency-Key | not used |
| Operation id | read_notifications_v1_me_notifications_read_post |
Request body
application/json (required): MarkRead
| Field | Type | Required | Description |
|---|---|---|---|
ids |
array of string (uuid) | These notifications. (max items 200) | |
all |
boolean | Every unread one of yours. (default false) |
Example request
curl -X POST "$ERP_URL/v1/me/notifications/read" \
-H "Authorization: Bearer $ERP_KEY" \
-H "Content-Type: application/json" \
-d '{
"all": true
}'
Responses
| Status | Meaning | Body |
|---|---|---|
| 200 | OK | NotificationList |
| 401 | Missing or invalid API key (unauthorized). |
ErrorEnvelope |
| 403 | The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). |
ErrorEnvelope |
| 409 | The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). |
ErrorEnvelope |
| 422 | Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. |
HTTPValidationError |
Example response (shape)
{
"unread": 1,
"approvals_waiting": 1,
"items": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"kind": "approval_decided",
"params": {},
"link": "string",
"created_at": "2026-09-21T09:30:00Z",
"read_at": "2026-09-21T09:30:00Z"
}
]
}
Schemas
MarkRead
| Field | Type | Required | Description |
|---|---|---|---|
ids |
array of string (uuid) | These notifications. (max items 200) | |
all |
boolean | Every unread one of yours. (default false) |
NotificationList
| Field | Type | Required | Description |
|---|---|---|---|
unread |
integer | yes | How many of yours are unread. |
approvals_waiting |
integer | yes | Approval requests you may decide now (four eyes): the Approvals page lists them. |
items |
array of NotificationOut |
yes | Yours, the newest first. |
NotificationOut
| Field | Type | Required | Description |
|---|---|---|---|
id |
string (uuid) | yes | The notification's id (to mark it read). |
kind |
"approval_decided" | "deal_assigned" | "deal_lost" | "deal_won" | "task_assigned" | "task_due" | "task_overdue" | "webhook_disabled" |
yes | What happened: task_assigned (someone gave you a task), task_due (a task of yours is due), task_overdue (its day passed), deal_assigned (someone made you a deal's owner), deal_won, deal_lost (a deal you own, moved by someone else), approval_decided (your request was approved or rejected), webhook_disabled (an endpoint kept failing and was stopped; administrators). |
params |
object | yes | The values the screen words it with, by kind: subject, due_on, deal, customer, by (who did it), number, title, amount, currency, reason, status, object_type, url. |
link |
string or null | yes | Where the web UI opens it (a path). |
created_at |
string (date-time) | yes | When it happened. |
read_at |
string (date-time) or null | yes | When you read it; null while unread. |
NotificationSettings
| Field | Type | Required | Description |
|---|---|---|---|
email_kinds |
array of "approval_decided" | "deal_assigned" | "deal_lost" | "deal_won" | "task_assigned" | "task_due" | "task_overdue" | "webhook_disabled" |
yes | The kinds you also get by e-mail (none by default). Every notification is in the notification centre whatever this says. |
NotificationSettingsOut
| Field | Type | Required | Description |
|---|---|---|---|
email_kinds |
array of "approval_decided" | "deal_assigned" | "deal_lost" | "deal_won" | "task_assigned" | "task_due" | "task_overdue" | "webhook_disabled" |
yes | The kinds you also get by e-mail (none by default). Every notification is in the notification centre whatever this says. |
email_available |
boolean | yes | Whether this system sends e-mail (a mail server is set up and this is not a test copy). False: the choice is kept and nothing is sent. |
email |
string or null | yes | Where e-mail goes: your sign-in address. |