Skip to main content
Notification System — Backend Documentation

Table of Contents

  • Overview
  • How It Works
    • SMTP Rule
  • Configuration
    • smtp_threshold
    • batch_size
  • Notification Types
  • Request Body Fields
  • Postman Examples
    • 1. Send to a Single User (In-App Only)
    • 2. Send to Multiple Specific Users
    • 3. Send to a Single User + Email (SMTP)
    • 4. Send to an Entire Role (e.g., All Students)
    • 5. Send to Multiple Roles
    • 6. Send to an Entire Company
    • 7. Send to Multiple Companies
    • 8. One Target per Request (No Combining)
    • 9. Scheduled Notification (Future)
    • 10. Scheduled + SMTP to a Single User
    • 11. Each Notification Type — Quick Reference Payloads
  • Other Notification Endpoints
  • Architecture Summary
  • Postman Setup Tips
  • Common Error Responses

Overview

Boot list (19/10/2026): GET /auth/user ships only the 3 newest non-archived notifications (id, student_id, title, message, notification_type_id, notif_read_status, notif_archive_status, created_at) plus notification_count (unread). The bell popup / notifications page load more with GET /notifications/user/{user_id}?per_page=10&page=1 (see “Other Notification Endpoints”). It used to be the 10 newest rows with every column.
All notification sending goes through a single unified endpoint:
This endpoint handles every scenario: sending to individual users, entire roles, full companies, with or without email (SMTP), and with optional scheduling. Authentication: Bearer token required (Laravel Sanctum). Headers (for all requests):

How It Works

  1. The request hits NotificationController@sendUnified
  2. SendUnifiedNotificationRequest validates the payload
  3. NotificationService::resolveRecipients() collects the target user IDs from the one target sent: user_ids, role_ids or company_ids (user_ids and role_ids only match users of the sender’s company)
  4. NotificationService::createDispatch() creates the dispatch record and individual notification rows in chunks of batch_size
  5. If scheduled_at is set and is in the future → a ProcessNotificationDispatch job is queued with a delay
  6. Otherwise → NotificationService::sendNow() fires immediately

SMTP Rule

The original guard blocks SMTP for role/company targets. The smtp_threshold adds a second layer: even when targeting user_ids directly, if the resolved recipient count exceeds the threshold, SMTP is forced off and a warning is logged. This prevents accidental mass email blasts through the “allowed” path. This is enforced in NotificationService::sendNow() — see the Configuration section below.

Configuration

Two runtime-tunable values are extracted into config/notifications_config.php so they can be changed via environment variables without touching application code.

smtp_threshold

Default: 20 After resolveRecipients() produces the final user list, sendNow() checks the count. If it exceeds smtp_threshold, notif_smtp_status is forced to false — regardless of what was passed in the request — and a warning is logged.

batch_size

Default: 1000 When creating Notification rows in bulk, a single Notification::insert() on thousands of rows causes PHP memory exhaustion and can hit DB statement size limits. The full recipient list is split with array_chunk() and inserted in separate queries.
The defaults in notifications_config.php are used when the .env keys are absent — so existing deployments that haven’t set them will automatically behave as if they were set to 20 and 1000 respectively.

Notification Types

These are stored in the notification_types table. Use the id value in notification_type_id:

Request Body Fields

*Exactly one of user_ids, role_ids or company_ids must be a non-empty array; leave the others empty or out. Sending none, or two of them, is a 422 on the target key (see example 8).

Postman Examples

1. Send to a Single User (In-App Only)

The simplest case — one user, no email, no scheduling.
Expected response (201):

2. Send to Multiple Specific Users


3. Send to a Single User + Email (SMTP)

Set notif_smtp_status to true. This only works when targeting user_ids (not roles/companies) and when the recipient count does not exceed smtp_threshold.
Make sure SMTP settings are configured via POST /api/platform/smtp-settings before testing this.

4. Send to an Entire Role (e.g., All Students)

Role IDs are fixed by the seeder and by the Role constants in the backend: The app’s Reminders screen sends the same ids: All students → 1, All instructors → 2, All content creators → 3, All admins → 4. Its Everyone option is not a role: the app sends company_ids: [<your company>] instead (example 6).
notif_smtp_status is forced to false here even if you pass true.

5. Send to Multiple Roles

Notify all instructors and students at once:

6. Send to an Entire Company

Every user in company ID 1:
SMTP is also forced off for company-wide broadcasts.

7. Send to Multiple Companies

If you have a multi-tenant setup:

8. One Target per Request (No Combining)

You can’t mix targets in one request. This body, sending to two users and the student role, is refused:
Response (422):
Send two requests instead: one with "role_ids": [1], one with "user_ids": [7, 9] (the second one may also use notif_smtp_status).

9. Scheduled Notification (Future)

Send a reminder that gets delivered at a specific time:
Expected response (201):
The scheduled_at datetime is parsed in Africa/Tunis timezone. If the datetime is in the past, it sends immediately instead of scheduling.

10. Scheduled + SMTP to a Single User


11. Each Notification Type — Quick Reference Payloads

Danger (2):
Warning (3):
Assignment (5):
Grade (6):
Quiz (7):

Other Notification Endpoints

These manage notifications after they’ve been sent.

Mark as Read

Mark as Unread

Mark All as Read (per user)

Archive

Unarchive

Get Notifications by User

Returns paginated notifications + unread_count.

Get Notifications by Company

Get Notifications by Role

Get Single Notification

Delete Notification


Architecture Summary

Key Models

Key Files


Postman Setup Tips

  1. Environment variables — set {{base_url}} (e.g., http://localhost:8000/api) and {{token}}
  2. Get a token — call POST {{base_url}}/auth/login first and grab the token from the response
  3. Role IDs — 1 Student, 2 Instructor, 3 Content Manager, 4 Admin, 5 Super Admin (SELECT * FROM roles; shows the same rows)
  4. Check your users table — run SELECT id, first_name, email, role_id FROM users; to get valid user IDs
  5. SMTP testing — configure SMTP first via POST /api/platform/smtp-settings, then test with POST /api/platform/test-smtp before trying notif_smtp_status: true

Common Error Responses