NetworkNotificationCreatedPayload network.notification.created@1

Generated at from openvibe-contracts v0.76.0 and openvibe-sdk v0.20.1.

Version
1.0.0
Owner
network
Visibility
first-party
Status
active
Compatibility
backward
Decision
ADR-005
Schema
https://openvibe.network/contracts/events/payloads/network.notification.created.v1.json

network.notification.created v1 (OpenVibe.Network server/notifications/notification-service.js; roadmap WS-E task 3, ADR-005 amendment 2). A notification was added to a person's inbox (Network is the only notification store, ADR-020). Written to Network's outbox in the transaction that stores the notification, so it exists if and only if the notification does; a muted category, a blocked sender or a go-live dedupe creates neither. Envelope: subject { type: user, id: <recipient usr_> }, visibility subject, actor system:network (never the sender: Events streams a subject event to its actor too), priority low. It is the person's realtime topic ("user:<id>" in the roadmap): a browser subscribes to `network.notification.*` on Events' /realtime/stream with a realtime ticket (identity.realtime-ticket-claims@1) and receives only its own; anyone else's subscription to the same pattern yields nothing. It carries what the notification badge needs and nothing it shows: never the title, the message, the link or the sender. The badge re-reads the unread count and the newest items from Network's API, which stays authoritative (reads, dismissals, other devices). Guests (anonymous accounts) and accounts without a usr_ subject get no event.

Fields

FieldTypeRequiredDescriptionConstraints
notification_idstringyesThe notification's id in Network's store (a UUID today): the id GET /api/notifications returns and POST /api/notifications/:id/read takes.
  • pattern ^[A-Za-z0-9_-]{1,64}$
typestringyesThe notification type (openvibe-shared notifications TYPES, e.g. STREAM_LIVE, CONTENT_REPLY, DEAL_WATCH_MATCH); GENERIC when the stored type has another shape.
  • pattern ^[A-Z][A-Z0-9_]{1,63}$
categorystringyesThe preference category it was filed under (social, chat, stream, service, moderation, system, ...).
  • pattern ^[a-z][a-z0-9_]{1,31}$
priorityenumyesThe notification's priority (the badge may ring or toast on high and critical).
  • one of "low", "normal", "high", "critical"
servicestring | nullThe service it is about (live, deals, trade, ...), or null.
  • pattern ^[a-z][a-z0-9-]{1,39}$
created_atstringyes
  • format date-time
unread_countintegeryesThe recipient's unread count right after this notification was stored, so a badge can update without a request. A later read elsewhere is not an event: the badge re-reads the count on focus and on its fallback poll.
  • minimum 0
  • maximum 9007199254740991

Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

Valid: no-service
{
  "notification_id": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
  "type": "WELCOME",
  "category": "system",
  "priority": "low",
  "service": null,
  "created_at": "2026-09-26T18:03:08.000Z",
  "unread_count": 0
}
Valid: stream-live
{
  "notification_id": "3f1c2b9a-6d4e-4f8a-9b1c-2d3e4f5a6b7c",
  "type": "STREAM_LIVE",
  "category": "stream",
  "priority": "normal",
  "service": "live",
  "created_at": "2026-09-26T18:03:08.000Z",
  "unread_count": 4
}
Rejected: carries-the-sender
{
  "notification_id": "3f1c2b9a-6d4e-4f8a-9b1c-2d3e4f5a6b7c",
  "type": "CONTENT_REPLY",
  "category": "social",
  "priority": "normal",
  "service": "live",
  "created_at": "2026-09-26T18:03:08.000Z",
  "unread_count": 1,
  "sender_id": 20
}
Rejected: carries-the-title
{
  "notification_id": "3f1c2b9a-6d4e-4f8a-9b1c-2d3e4f5a6b7c",
  "type": "STREAM_LIVE",
  "category": "stream",
  "priority": "normal",
  "service": "live",
  "created_at": "2026-09-26T18:03:08.000Z",
  "unread_count": 4,
  "title": "carol is live!"
}
Rejected: lowercase-type
{
  "notification_id": "3f1c2b9a-6d4e-4f8a-9b1c-2d3e4f5a6b7c",
  "type": "stream_live",
  "category": "stream",
  "priority": "normal",
  "service": "live",
  "created_at": "2026-09-26T18:03:08.000Z",
  "unread_count": 4
}
Rejected: no-unread-count
{
  "notification_id": "3f1c2b9a-6d4e-4f8a-9b1c-2d3e4f5a6b7c",
  "type": "STREAM_LIVE",
  "category": "stream",
  "priority": "normal",
  "service": "live",
  "created_at": "2026-09-26T18:03:08.000Z"
}
Rejected: unknown-priority
{
  "notification_id": "3f1c2b9a-6d4e-4f8a-9b1c-2d3e4f5a6b7c",
  "type": "STREAM_LIVE",
  "category": "stream",
  "priority": "urgent",
  "service": "live",
  "created_at": "2026-09-26T18:03:08.000Z",
  "unread_count": 4
}

Validate

const contracts = require('openvibe-contracts');
contracts.validate('network.notification.created@1', value);   // { valid, errors: [{ path, message }] }