Skip to main content

Notifications API

The notifications module provides in-app notifications for users, supporting categories, persistence levels, deduplication, and automatic cleanup. The API layer (apps/api/src/notifications/) exposes REST endpoints, while the agent package (packages/agent/src/notifications/) contains the core NotificationService.

Architecture

apps/api/src/notifications/
notifications.controller.ts # REST endpoints
notification-cleanup.service.ts # Cron-based cleanup
notifications.module.ts # NestJS module

packages/agent/src/notifications/
notification.service.ts # Core notification logic
notifications.module.ts # Agent module

Notification Types and Categories

Types: ERROR, WARNING, INFO, SUCCESS

Categories:

CategoryUse Case
ai_creditsAI provider credit depletion and errors
subscriptionSubscription and billing notifications
generationWork generation successes and failures
systemPlatform-level system notifications
securityAuthentication and access-related alerts

REST Endpoints

All endpoints require JWT authentication.

GET /api/notifications

Retrieve notifications for the current user with optional filters.

Query ParameterTypeDefaultDescription
unreadOnlybooleanfalseReturn only unread notifications
limitnumber50Maximum results (capped at 100)
offsetnumber0Pagination offset
categorystring--Filter by category: ai_credits, subscription, generation, system, security

GET /api/notifications/unread-count

Returns the count of unread notifications.

{ "count": 5 }

GET /api/notifications/persistent

Returns persistent (critical) notifications displayed as global banners. Persistent notifications cannot be dismissed until the underlying issue is resolved.

POST /api/notifications/:id/read

Mark a single notification as read.

POST /api/notifications/read-all

Mark all notifications as read for the current user.

POST /api/notifications/:id/dismiss

Dismiss a notification (hides it from view). Returns 400 Bad Request if the notification is persistent.

NotificationService

The core service provides both CRUD operations and domain-specific notification helpers.

Creating Notifications

await notificationService.create({
userId: 'user-123',
type: NotificationType.ERROR,
category: NotificationCategory.AI_CREDITS,
title: 'AI Credits Depleted',
message: 'Your OpenAI credits have been exhausted.',
actionUrl: '/settings',
actionLabel: 'Add Credits',
isPersistent: true,
deduplicationKey: 'ai_credits_depleted_openai'
});

Deduplication

Notifications support a deduplicationKey field. When set, the service checks for an existing non-dismissed notification with the same key before creating a new one. This prevents duplicate alerts (e.g., repeated credit depletion warnings). Race conditions are handled via unique constraint error detection across PostgreSQL, MySQL, and SQLite.

Built-in Notification Helpers

MethodCategoryPersistentDescription
notifyAiCreditsDepleted()ai_creditsYesAI provider credits exhausted
notifyAiProviderError()ai_creditsNoAI provider returned an error
notifyGenerationAccountError()generationNoWork generation failed
notifySchedulePaused()generationNoScheduled updates paused
notifyGitAuthExpired()securityYesGit provider token expired
clearByDeduplicationKey()----Remove notification when issue resolves

Cleanup Service

NotificationCleanupService runs daily at 3:00 AM via @Cron(CronExpression.EVERY_DAY_AT_3AM) and removes:

RuleRetention
Expired notifications (past expiresAt)Immediate
Dismissed notifications7 days
All notifications30 days

The cleanup returns counts: { expired: number, dismissed: number, old: number }.

Module Registration

@Module({
imports: [AgentNotificationsModule, DatabaseModule],
controllers: [NotificationsController],
providers: [NotificationCleanupService],
exports: [AgentNotificationsModule]
})
export class NotificationsModule {}