Axiomatic

Notifications & Alerts

Stay informed about critical events with in-app notifications, configurable preferences, and automated reminders.

Overview

Axiomatic's notification system keeps you informed about important events without requiring you to constantly check the app. Notifications appear in real-time via the bell icon in the top navigation bar, and can be configured per type and delivery channel.

Notification Types

TypeTriggerExample
approval_pendingA journal entry requires your approval"Journal entry JE-042 is awaiting your approval"
approval_resolvedA journal entry you submitted was approved or rejected"Your journal entry JE-042 was approved"
sync_completedA bank or integration sync finished successfully"Plaid sync completed: 47 new transactions imported"
sync_failedA sync encountered an error"Mercury sync failed: authentication expired"
close_deadlineAn accounting period's close date is approaching"Period 2025-Q2 closes in 3 days"
usage_thresholdYour tenant credit balance is low or exhausted"Your credit balance is $4.50 — add credits to avoid interruption"
team_inviteYou were added to an entity's team"You were added to Acme Corp by matt@example.com"
comment_addedSomeone commented on a record you're involved with"Sarah commented on journal entry JE-042"
mentionSomeone @mentioned you in a comment"@matt mentioned you: 'Can you review this entry?'"
systemSystem-level alerts"Scheduled maintenance window: Sunday 2am-4am UTC"
crm_lead_assignedCRM lead assigned to you"Lead assigned: Acme expansion"
crm_lead_wonCRM lead marked won"Lead won: Acme expansion"
crm_task_dueCRM task due or overdue"CRM task: Follow up with Acme"
invoice_overdueCustomer invoice past due"Invoice INV-1042 is overdue"
invoice_paidCustomer paid an invoice"Payment received for INV-1042"
expense_submittedExpense report submitted"Expense report submitted for review"
expense_approvedExpense report decision"Your expense report was approved"
purchase_order_approvedPO approved"Purchase order PO-88 approved"
sales_quote_approvedSales quote accepted"Quote Q-12 accepted"
helpdesk_ticket_assignedNew helpdesk ticket"New ticket HD-441 opened"
governance_filing_dueCorporate filing deadline"Annual report due in 7 days"
bi_report_readyScheduled report ready"Trial balance report is ready"

Additional module types (inventory, HR leave, routes, maintenance, manufacturing, marketing, documents) are listed in Settings → Notifications.

Viewing Notifications

Click the bell icon in the top navigation bar to open the notification panel. Unread notifications show a badge count. From the panel you can:

  • View all recent notifications
  • Click a notification to navigate to the relevant record
  • Mark individual notifications as read
  • Mark all notifications as read

Notification Preferences

Configure which notification types you receive and through which channels. Navigate to Settings → Notifications to manage your preferences.

Each notification type can be independently enabled or disabled per delivery channel:

ChannelDescription
in_appNotifications appear in the bell icon panel
emailNotifications are sent to your email address

Automated Reminders

Close Deadline Reminders

A background cron job checks for open accounting periods with approaching close dates. When a period's end date is within the configured reminder window, all entity administrators receive a close_deadline notification.

This ensures no one misses a period close — even if they haven't logged in recently.

Usage Threshold Alerts

When a tenant's prepaid credit balance drops to $5 or below (or reaches $0), billing owners receive usage_threshold notifications (in-app and email, if enabled). This replaces the old subscription-tier quota model.

Delivery API (server-side)

Producers should use the unified delivery helpers in @/lib/notifications/deliver:

  • notifyUser(userId, payload) — single recipient; honors in_app and email prefs
  • notifyUsers(userIds, payload) — batch fan-out
  • notifyEntityMembers({ entityId, rbacKeys?, ...payload }) — RBAC-filtered recipients
  • notifyEntityAdminsWithPrefs(entityId, payload) — finance-close admins

Pass an optional email: { send: (to) => ... } callback to send transactional mail when the user has email enabled for that type. Defaults to enabled when no preference row exists.

Real-Time Events (Pusher)

In addition to persisted notifications, the system broadcasts real-time events via Pusher WebSockets for features that require instant UI updates without polling.

Channels

ChannelPatternUsed By
Entity eventsentity-{entityId}Sync status, proposals, transaction imports
Chat updateschat-{chatId}AI assistant streaming
User notificationsuser-{userId}New in-app notification (notification:created)

The notification bell subscribes to user-{userId} for instant badge updates, with a 30-second poll fallback when Pusher is unavailable.

Sync Events

The following events are broadcast on entity-{entityId} during integration syncs:

EventDescriptionPayload
sync:startedA connection sync has begunconnectionId, provider
sync:progressIncremental sync progressconnectionId, transactionsCreated, accountsSynced
sync:completedSync finished successfullyconnectionId, transactionsCreated, duplicatesSkipped, quarantined, errors[]
sync:failedSync encountered an errorconnectionId, error

Other Real-Time Events

EventDescriptionPayload
proposal:createdAI generated a new proposalentityId
proposal:updatedA proposal was approved/rejectedentityId, proposalId, status
transaction:importedTransactions were importedentityId, count

Subscribing in the app (Realtime)

Use the useRealtimeChannel hook to subscribe to entity events:

useRealtimeChannel(`entity-${entityId}`, {
  "sync:completed": (data) => { /* refresh UI */ },
  "sync:failed": (data) => { /* show error */ },
});

The Import & Sync page and dashboard automatically subscribe to these events for live status updates.

API Reference

List Notifications

GET /api/notifications?limit=20&offset=0&unreadOnly=false

Returns a paginated list of notifications for the authenticated user, along with the current unread count.

Response:

{
  "notifications": [
    {
      "id": "notif-uuid",
      "type": "approval_pending",
      "title": "Approval Required",
      "body": "Journal entry JE-042 is awaiting your approval",
      "actionUrl": "/accounting/journal?id=je-042",
      "read": false,
      "createdAt": "2025-06-15T10:30:00Z"
    }
  ],
  "unreadCount": 3
}

Mark Notification as Read

PATCH /api/notifications/:id

Marks a single notification as read and sets the readAt timestamp.

Mark All as Read

POST /api/notifications
{
  "action": "mark_all_read"
}

Marks all unread notifications for the authenticated user as read.

Get Notification Preferences

GET /api/notification-preferences

Returns the user's notification preferences for all types and channels.

Update Notification Preference

PUT /api/notification-preferences
{
  "type": "sync_completed",
  "channel": "email",
  "enabled": false
}

Enable or disable a specific notification type for a given channel.

On this page