My notifications
What the caller sees: the notification feed for the active workspace and their notification preferences, by preset or cell by cell.
Download the full API pública projection: openapi.json.
| Method | Path | What it does |
|---|---|---|
GET | /me/notification-preferences | The caller’s notification preferences, generated from the registry |
PUT | /me/notification-preferences | Change notification preferences (preset and/or single cells) |
GET | /me/notifications | In-app notification feed for the active workspace (keyset-paginated) |
GET /me/notification-preferences
The caller’s notification preferences, generated from the registry
Every notification type this member can receive in this workspace (filtered by role and vertical), grouped by category, with the state of each channel — bell (in_app), email, push, whatsapp: on/off (their choice, or the default when they never chose), locked (mandatory, with locked_reason), always (the bell of a type they must act on) or unavailable. WhatsApp is available only for types the workspace armed for staff WhatsApp. preset is important (the defaults), all or custom. Requires a workspace member; an sk_* API key gets 403.
curl https://api.vitrinadev.com/api/v1/me/notification-preferences \
-H "Authorization: Bearer $VITRINA_KEY"Example response (200)
{
"data": {
"preset": "important",
"push_enabled": true,
"categories": [
"inbox",
"agenda",
"sales",
"followups",
"approvals",
"payments",
"agents",
"integrations",
"safety",
"account"
],
"types": [
{
"key": "assigned",
"category": "inbox",
"slug": "assigned",
"mandatory": false,
"locked_reason": null,
"bell_mutable": false,
"delivery": "immediate",
"channels": {
"in_app": {
"state": "always",
"default": "on"
},
"email": {
"state": "off",
"default": "off"
},
"push": {
"state": "on",
"default": "on"
},
"whatsapp": {
"state": "on",
"default": "workspace"
}
}
},
{
"key": "agenda_booked",
"category": "agenda",
"slug": "agenda_booked",
"mandatory": false,
"locked_reason": null,
"bell_mutable": false,
"delivery": "immediate",
"channels": {
"in_app": {
"state": "always",
"default": "on"
},
"email": {
"state": "on",
"default": "on"
},
"push": {
"state": "on",
"default": "on"
},
"whatsapp": {
"state": "unavailable",
"default": null
}
}
},
{
"key": "payment_review_needed",
"category": "payments",
"slug": "payment_review_needed",
"mandatory": true,
"locked_reason": "customer_waiting",
"bell_mutable": false,
"delivery": "immediate",
"channels": {
"in_app": {
"state": "locked",
"default": "locked"
},
"email": {
"state": "on",
"default": "on"
},
"push": {
"state": "on",
"default": "on"
},
"whatsapp": {
"state": "on",
"default": "workspace"
}
}
}
]
}
}Answers: 200 · 400 · 401 · 403 · 404 · 409 · 429
PUT /me/notification-preferences
Change notification preferences (preset and/or single cells)
JSON-merged: only the cells named change, everything else is kept. preset: important returns to the defaults (clears every per-type choice); all switches every switchable cell on; any changes entry without a preset makes the preset custom. 400 for an unknown type, a channel the type does not use, a mandatory (locked) cell, or the bell of a type that always appears in the bell. Returns the fresh catalog.
curl -X PUT https://api.vitrinadev.com/api/v1/me/notification-preferences \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"changes": [
{
"key": "agenda_booked",
"channel": "email",
"enabled": false
},
{
"key": "coach.finding_ready",
"channel": "in_app",
"enabled": false
}
]
}'Example response (200)
{
"data": {
"preset": "important",
"push_enabled": true,
"categories": [
"inbox",
"agenda",
"sales",
"followups",
"approvals",
"payments",
"agents",
"integrations",
"safety",
"account"
],
"types": [
{
"key": "assigned",
"category": "inbox",
"slug": "assigned",
"mandatory": false,
"locked_reason": null,
"bell_mutable": false,
"delivery": "immediate",
"channels": {
"in_app": {
"state": "always",
"default": "on"
},
"email": {
"state": "off",
"default": "off"
},
"push": {
"state": "on",
"default": "on"
},
"whatsapp": {
"state": "on",
"default": "workspace"
}
}
},
{
"key": "agenda_booked",
"category": "agenda",
"slug": "agenda_booked",
"mandatory": false,
"locked_reason": null,
"bell_mutable": false,
"delivery": "immediate",
"channels": {
"in_app": {
"state": "always",
"default": "on"
},
"email": {
"state": "on",
"default": "on"
},
"push": {
"state": "on",
"default": "on"
},
"whatsapp": {
"state": "unavailable",
"default": null
}
}
},
{
"key": "payment_review_needed",
"category": "payments",
"slug": "payment_review_needed",
"mandatory": true,
"locked_reason": "customer_waiting",
"bell_mutable": false,
"delivery": "immediate",
"channels": {
"in_app": {
"state": "locked",
"default": "locked"
},
"email": {
"state": "on",
"default": "on"
},
"push": {
"state": "on",
"default": "on"
},
"whatsapp": {
"state": "on",
"default": "workspace"
}
}
}
]
}
}Answers: 200 · 400 · 401 · 403 · 404 · 409 · 429
GET /me/notifications
In-app notification feed for the active workspace (keyset-paginated)
The caller’s own bell, newest first. Only the last 14 days are returned (older rows expire and are deleted after 30 days); meta.unreadCount counts unread items inside that same window. Every row carries a typed target — where a click leads: record (one subject), list (a filtered list, e.g. the Búsquedas a daily summary counted) or page (a fixed screen) — never a URL. A live row is a standing condition (a broken channel, the approvals queue) refreshed in place and marked read when it ends. Requires a workspace member (a session or a personal token acting as one); an sk_* API key gets 403.
| Parameter | In | Type | Required | Constraints |
|---|---|---|---|---|
cursor | query | string | no | máx. 80 |
limit | query | integer | no | ≥ 1, ≤ 50 |
curl https://api.vitrinadev.com/api/v1/me/notifications \
-H "Authorization: Bearer $VITRINA_KEY"Example response (200)
{
"data": [
{
"id": "019a3b1c-2d4e-7f00-8a1b-2c3d4e5f6a70",
"type": "busqueda.daily_summary",
"category": "followups",
"actor_id": null,
"entity_type": "tenant",
"entity_id": "7b1f0c52-3e4a-4d8b-9c21-5a6b7c8d9e0f",
"data": {
"sent": 4,
"failed": 1,
"customers": [
"Camila Rojas",
"Diego Muñoz",
"Paula Soto"
],
"from": "2026-10-07T12:00:00.000Z",
"to": "2026-10-08T12:00:00.000Z"
},
"target": {
"kind": "list",
"screen": "busquedas",
"filter": {
"notified_from": "2026-10-07T12:00:00.000Z",
"notified_to": "2026-10-08T12:00:00.000Z",
"status": "any"
}
},
"secondary_target": {
"kind": "list",
"screen": "busquedas",
"filter": {
"notified_from": "2026-10-07T12:00:00.000Z",
"notified_to": "2026-10-08T12:00:00.000Z",
"notice": "failed",
"status": "any"
}
},
"live": false,
"read_at": null,
"created_at": "2026-10-08T12:00:04.512Z"
},
{
"id": "019a3a77-90ab-7c00-9d1e-2f3a4b5c6d7e",
"type": "agenda_booked",
"category": "agenda",
"actor_id": null,
"entity_type": "appointment",
"entity_id": "c4d5e6f7-0819-4a2b-8c3d-4e5f60718293",
"data": {},
"target": {
"kind": "record",
"record": "appointment",
"id": "c4d5e6f7-0819-4a2b-8c3d-4e5f60718293"
},
"secondary_target": null,
"live": false,
"read_at": "2026-10-08T09:15:00.000Z",
"created_at": "2026-10-07T21:40:11.003Z"
}
],
"meta": {
"pagination": {
"nextCursor": null
},
"unreadCount": 1
}
}Answers: 200 · 400 · 401 · 403 · 404 · 409 · 429