Skip to content

Notification Management

Complete guide to sending, scheduling, and managing notifications across multiple channels in the Reserva platform.


Overview

The notification system provides multi-channel delivery with support for:

  • Immediate Notifications - Send notifications instantly via push, email, or WhatsApp
  • Scheduled Notifications - Schedule future notifications with timezone support
  • Template-Based Content - Jinja2 templates for consistent, personalized messaging
  • Usage Tracking - Monitor notification usage against plan limits
  • Notification History - Audit trail of all sent notifications

Key Concepts:

  • Channels = Delivery methods (push, email, whatsapp)
  • Templates = Predefined message formats per notification type
  • Scheduling Tiers = Cloud Tasks (<=30 days) or MongoDB (>30 days)
  • Usage Quotas = Monthly limits based on subscription plan

Notification System Documentation

The notification system spans multiple documentation pages:

Document Purpose When to Use
This Page API for sending/scheduling notifications Implementing notification sending in your app
Notification Settings Customize templates & reminder timings Configuring tenant-specific notification preferences
Appointment Management Auto-triggered booking notifications Understanding automatic appointment notifications

Subscription Plan Limits

Notification channel access and quotas are based on your subscription plan:

Channel FREE PRO ENTERPRISE
Push (FCM) Unlimited Unlimited Unlimited
Email (SES) 100/month 1,000/month Unlimited
WhatsApp (Fonnte) 50/month 500/month 5,000/month

Notes:

  • Push notifications are always unlimited on all plans
  • Quota resets on the 1st of each month (UTC)
  • Enterprise plan has virtually unlimited email notifications
  • Usage can be monitored via the /usage endpoint

Quota Exceeded Behavior

When a channel's quota is exceeded, that channel will be blocked for the notification but other channels will still be attempted. The response will indicate which channels were blocked due to quota limits.


Available Notification Types

Type Description Common Use Case
booking_confirmation Confirm new appointment booking After successful booking
booking_reminder Remind customer of upcoming appointment 24h/1h before appointment
booking_cancelled Notify of appointment cancellation After cancellation
booking_rescheduled Notify of appointment time change After rescheduling
payment_receipt Confirm payment received After payment completion
welcome Welcome new customer After registration
membership_update Platform subscription update After plan upgrade/renewal

Send Immediate Notification

Send a notification immediately through specified channels.

Endpoint

POST /api/v1/notifications/send

Authentication: Required (JWT token)

Access: Staff with notification permissions (SUPER_ADMIN, TENANT_ADMIN, OUTLET_MANAGER, STAFF)

Request Body

{
  "user_id": "507f1f77bcf86cd799439011",
  "notification_type": "booking_confirmation",
  "channels": ["push", "email", "whatsapp"],
  "template_data": {
    "customer_name": "Budi Santoso",
    "tenant_name": "Salon Cantik",
    "service_names": "Hair Cut, Hair Wash",
    "appointment_date": "20 Januari 2025",
    "appointment_time": "14:00",
    "outlet_name": "Salon Cantik Kemang",
    "outlet_address": "Jl. Kemang Raya No. 10",
    "staff_name": "Sari",
    "total_amount": "Rp 150.000",
    "booking_reference": "BK-2025-001"
  },
  "recipient_email": "budi@example.com",
  "recipient_phone": "+6281234567890",
  "recipient_name": "Budi Santoso",
  "reference_type": "appointment",
  "reference_id": "507f1f77bcf86cd799439012"
}

Parameters:

Parameter Type Required Description
user_id string Yes Target user's ObjectId
notification_type string Yes Type of notification (see types table)
channels array Yes Channels to send through: push, email, whatsapp
template_data object No Variables for template rendering (see template data requirements)
recipient_email string Conditional Required if email is in channels
recipient_phone string Conditional Required if whatsapp is in channels (E.164 format)
recipient_name string No Display name for personalization
user_type string No customer (default) or staff
reference_type string No Entity type for tracking (e.g., appointment, payment)
reference_id string No Entity ID for linking notifications
idempotency_key string No Unique key to prevent duplicates
data object No Additional payload for push notifications
action_url string No Click/action URL for the notification

Response

{
  "notification_id": "507f1f77bcf86cd799439020",
  "overall_success": true,
  "channels_succeeded": ["push", "email", "whatsapp"],
  "channels_failed": [],
  "channels_blocked": {},
  "channels_quota_exceeded": []
}

Response Fields:

Field Description
notification_id Created notification record ID
overall_success True if at least one channel succeeded
channels_succeeded List of channels that delivered successfully
channels_failed List of channels that failed delivery
channels_blocked Map of blocked channels with reasons
channels_quota_exceeded List of channels blocked due to quota

Partial Success Example

When some channels fail but others succeed:

{
  "notification_id": "507f1f77bcf86cd799439020",
  "overall_success": true,
  "channels_succeeded": ["push"],
  "channels_failed": ["email"],
  "channels_blocked": {
    "whatsapp": "Channel not enabled for FREE plan"
  },
  "channels_quota_exceeded": []
}

Template Data Requirements

Each notification type requires specific variables for template rendering:

booking_confirmation

{
  "customer_name": "Budi Santoso",
  "tenant_name": "Salon Cantik",
  "service_names": "Hair Cut, Hair Wash",
  "appointment_date": "20 Januari 2025",
  "appointment_time": "14:00",
  "outlet_name": "Salon Cantik Kemang",
  "outlet_address": "Jl. Kemang Raya No. 10",
  "staff_name": "Sari",
  "total_amount": "Rp 150.000",
  "booking_reference": "BK-2025-001"
}

booking_reminder

{
  "customer_name": "Budi Santoso",
  "tenant_name": "Salon Cantik",
  "service_names": "Hair Cut, Hair Wash",
  "appointment_date": "20 Januari 2025",
  "appointment_time": "14:00",
  "outlet_name": "Salon Cantik Kemang",
  "outlet_address": "Jl. Kemang Raya No. 10",
  "staff_name": "Sari"
}

booking_cancelled

{
  "customer_name": "Budi Santoso",
  "tenant_name": "Salon Cantik",
  "service_names": "Hair Cut",
  "appointment_date": "20 Januari 2025",
  "appointment_time": "14:00",
  "cancellation_reason": "Customer request",
  "refund_amount": "Rp 50.000"
}

Note: refund_amount is optional.

booking_rescheduled

{
  "customer_name": "Budi Santoso",
  "tenant_name": "Salon Cantik",
  "old_date": "20 Januari 2025",
  "old_time": "14:00",
  "new_date": "21 Januari 2025",
  "new_time": "15:00",
  "outlet_name": "Salon Cantik Kemang",
  "staff_name": "Sari"
}

payment_receipt

{
  "customer_name": "Budi Santoso",
  "tenant_name": "Salon Cantik",
  "invoice_number": "INV-2025-001",
  "amount": "Rp 150.000",
  "payment_method": "Bank Transfer",
  "service_names": "Hair Cut, Hair Wash",
  "payment_date": "20 Januari 2025"
}

welcome

{
  "customer_name": "Budi Santoso",
  "tenant_name": "Salon Cantik"
}

membership_update

{
  "customer_name": "Ahmad (Tenant Admin)",
  "tenant_name": "Reserva Platform",
  "plan_name": "PRO",
  "effective_date": "1 Januari 2025",
  "expiry_date": "31 Januari 2025"
}

Note: membership_update is typically triggered automatically by webhooks when a tenant's platform subscription is upgraded or renewed.


Schedule Future Notification

Schedule a notification for future delivery with timezone support.

Endpoint

POST /api/v1/notifications/schedule

Authentication: Required (JWT token)

Access: Staff with notification permissions

Request Body

{
  "user_id": "507f1f77bcf86cd799439011",
  "notification_type": "booking_reminder",
  "title": "Appointment Reminder",
  "body": "Your appointment is coming up in 24 hours",
  "scheduled_at": "2025-01-19T06:00:00Z",
  "channels": ["push", "whatsapp"],
  "template_data": {
    "customer_name": "Budi Santoso",
    "tenant_name": "Salon Cantik",
    "service_names": "Hair Cut, Hair Wash",
    "appointment_date": "20 Januari 2025",
    "appointment_time": "14:00",
    "outlet_name": "Salon Cantik Kemang",
    "outlet_address": "Jl. Kemang Raya No. 10",
    "staff_name": "Sari"
  },
  "recipient_phone": "+6281234567890",
  "recipient_name": "Budi Santoso",
  "reference_type": "appointment",
  "reference_id": "507f1f77bcf86cd799439012",
  "timezone": "Asia/Jakarta",
  "metadata": {
    "reminder_timing": "24 hours before"
  }
}

Additional Parameters:

Parameter Type Required Description
title string Yes Notification title (push title, email subject)
body string Yes Fallback message if template rendering fails
scheduled_at datetime Yes When to send (UTC, ISO 8601 with 'Z' suffix)
timezone string No IANA timezone (e.g., Asia/Jakarta)
metadata object No Additional tracking metadata

Timezone Handling

Important: UTC Timestamps

The scheduled_at field must be provided in UTC timezone (ISO 8601 format with 'Z' suffix).

Conversion Example:

  • To send at 14:00 WIB (Jakarta time, UTC+7)
  • Convert: 14:00 - 7 hours = 07:00 UTC
  • Use: 2025-01-20T07:00:00Z

Response

{
  "success": true,
  "scheduled_notification_id": "507f1f77bcf86cd799439021",
  "scheduling_tier": "cloud_tasks",
  "scheduled_at_utc": "2025-01-19T06:00:00Z",
  "cloud_task_id": "projects/myproject/locations/asia-southeast2/queues/notifications/tasks/abc123"
}

Response Fields:

Field Description
success Whether scheduling succeeded
scheduled_notification_id ID of the scheduled notification record
scheduling_tier Tier used: cloud_tasks or mongodb
scheduled_at_utc Confirmed scheduled time in UTC
cloud_task_id Cloud Task ID (if using cloud_tasks tier)
error Error message if scheduling failed

Scheduling Strategy

The system automatically selects the optimal scheduling tier:

flowchart TD
    A[Schedule Request] --> B{Days Until Send?}
    B -->|≤30 days| C[Cloud Tasks]
    B -->|>30 days| D[MongoDB + Promoter]

    C --> E[Scheduled]
    D --> F[Promoted at T-25 days]
    F --> C

Note: All channels (including WhatsApp) follow the same scheduling path. When a Cloud Task fires, it triggers notification_service.send() which delivers to each channel (email, WhatsApp, push) via their respective handlers.

Scheduling Tiers:

Tier When Used How It Works
cloud_tasks ≤30 days from now Immediate promotion to Cloud Tasks
mongodb >30 days from now Stored in MongoDB, promoted at T-25 days

List Scheduled Notifications

Retrieve scheduled notifications with optional filters.

Endpoint

GET /api/v1/notifications/scheduled

Authentication: Required (JWT token)

Query Parameters

Parameter Type Description
status string Filter by status: pending, promoted, completed, cancelled, failed
reference_type string Filter by reference type (e.g., appointment)
reference_id string Filter by reference ID
user_id string Filter by target user ID
from_date datetime Filter scheduled_at >= from_date
to_date datetime Filter scheduled_at <= to_date
skip integer Pagination offset (default: 0)
limit integer Results per page (default: 50, max: 100)

Response

{
  "items": [
    {
      "id": "507f1f77bcf86cd799439021",
      "notification_type": "booking_reminder",
      "title": "Appointment Reminder",
      "status": "pending",
      "scheduled_at": "2025-01-19T06:00:00Z",
      "scheduling_tier": "cloud_tasks",
      "channels": ["push", "whatsapp"],
      "reference_type": "appointment",
      "reference_id": "507f1f77bcf86cd799439012",
      "created_at": "2025-01-15T10:00:00Z"
    }
  ],
  "total": 15,
  "skip": 0,
  "limit": 50
}

Scheduled Notification Statuses:

Status Description
pending Waiting in MongoDB (>30 days out)
promoted Moved to Cloud Tasks (≤30 days)
processing Currently being sent
completed Successfully sent
failed Failed to send
cancelled Cancelled before sending
expired Passed scheduled time without being sent

Get Scheduled Notification Details

Retrieve full details of a specific scheduled notification.

Endpoint

GET /api/v1/notifications/scheduled/{notification_id}

Authentication: Required (JWT token)

Response

{
  "id": "507f1f77bcf86cd799439021",
  "tenant_id": "507f1f77bcf86cd799439010",
  "user_id": "507f1f77bcf86cd799439011",
  "user_type": "customer",
  "notification_type": "booking_reminder",
  "title": "Appointment Reminder",
  "body": "Your appointment is coming up in 24 hours",
  "priority": "normal",
  "channels": ["push", "whatsapp"],
  "scheduled_at": "2025-01-19T06:00:00Z",
  "template_data": {
    "customer_name": "Budi Santoso",
    "tenant_name": "Salon Cantik"
  },
  "status": "promoted",
  "scheduling_tier": "cloud_tasks",
  "version": 1,
  "recipient_phone": "+6281234567890",
  "recipient_name": "Budi Santoso",
  "reference_type": "appointment",
  "reference_id": "507f1f77bcf86cd799439012",
  "original_timezone": "Asia/Jakarta",
  "scheduled_at_local": "2025-01-19T13:00:00+07:00",
  "cloud_task_id": "projects/myproject/locations/asia-southeast2/queues/notifications/tasks/abc123",
  "promoted_at": "2025-01-15T10:00:00Z",
  "created_at": "2025-01-15T10:00:00Z",
  "updated_at": "2025-01-15T10:00:00Z"
}

Cancel Scheduled Notification

Cancel a pending or promoted scheduled notification.

Endpoint

DELETE /api/v1/notifications/scheduled/{notification_id}

Authentication: Required (JWT token)

Request Body

{
  "reason": "Appointment cancelled by customer"
}

Response

{
  "success": true,
  "message": "Scheduled notification cancelled successfully"
}

Business Rules:

  • Can only cancel pending or promoted notifications
  • completed or already cancelled notifications return error
  • Cloud Task is deleted if exists
  • Cancellation reason is stored for audit

Reschedule Notification

Change the scheduled time of a pending notification.

Endpoint

PUT /api/v1/notifications/scheduled/{notification_id}

Authentication: Required (JWT token)

Request Body

{
  "new_scheduled_at": "2025-01-20T07:00:00Z",
  "timezone": "Asia/Jakarta"
}

Response

{
  "success": true,
  "scheduled_notification_id": "507f1f77bcf86cd799439021",
  "scheduling_tier": "cloud_tasks",
  "scheduled_at_utc": "2025-01-20T07:00:00Z",
  "cloud_task_id": "projects/myproject/locations/asia-southeast2/queues/notifications/tasks/xyz789"
}

Business Rules:

  • Can only reschedule pending or promoted notifications
  • Increments version to prevent stale task execution
  • Old Cloud Task is deleted
  • New Cloud Task is created if within 30-day window
  • Re-evaluates scheduling tier based on new time

Get Usage Statistics

Monitor notification usage against plan limits.

Endpoint

GET /api/v1/notifications/usage

Authentication: Required (JWT token)

Query Parameters

Parameter Type Description
year_month string Period to query (YYYY-MM). Uses current if not provided.

Response

{
  "tenant_id": "507f1f77bcf86cd799439010",
  "year_month": "2025-01",
  "subscription_tier": "PRO",
  "push": {
    "sent": 150,
    "success": 145,
    "failed": 5,
    "limit": 0,
    "remaining": -1,
    "success_rate": 96.67
  },
  "email": {
    "sent": 234,
    "success": 230,
    "failed": 4,
    "limit": 1000,
    "remaining": 766,
    "success_rate": 98.29
  },
  "whatsapp": {
    "sent": 89,
    "success": 87,
    "failed": 2,
    "limit": 500,
    "remaining": 411,
    "success_rate": 97.75
  },
  "total_sent": 473,
  "total_success": 462,
  "total_failed": 11,
  "overall_success_rate": 97.67,
  "period_start": "2025-01-01T00:00:00Z",
  "period_end": "2025-01-31T23:59:59Z",
  "last_updated": "2025-01-15T10:30:00Z"
}

Usage Fields:

Field Description
sent Total notifications sent this period
success Successfully delivered
failed Failed to deliver
limit Monthly limit (0 = unlimited)
remaining Remaining quota (-1 = unlimited)
success_rate Delivery success percentage

List Available Templates

Get all available notification templates and their configurations.

Endpoint

GET /api/v1/notifications/templates

Authentication: Required (JWT token)

Response

{
  "notification_types": [
    "booking_confirmation",
    "booking_reminder",
    "booking_cancelled",
    "booking_rescheduled",
    "payment_receipt",
    "welcome",
    "membership_update"
  ],
  "templates": {
    "booking_confirmation": {
      "channels": {
        "push": {
          "enabled": true,
          "has_title": true,
          "has_body": true,
          "has_html": false
        },
        "email": {
          "enabled": true,
          "has_title": true,
          "has_body": true,
          "has_html": true
        },
        "whatsapp": {
          "enabled": true,
          "has_title": false,
          "has_body": true,
          "has_html": false
        }
      },
      "variables": [
        "customer_name",
        "tenant_name",
        "service_names",
        "appointment_date",
        "appointment_time",
        "outlet_name",
        "outlet_address",
        "staff_name",
        "total_amount",
        "booking_reference"
      ],
      "sample_data": {
        "customer_name": "Budi Santoso",
        "tenant_name": "Salon Cantik",
        "service_names": "Hair Cut, Hair Wash",
        "appointment_date": "20 Januari 2025",
        "appointment_time": "14:00",
        "outlet_name": "Salon Cantik Kemang",
        "outlet_address": "Jl. Kemang Raya No. 10",
        "staff_name": "Sari",
        "total_amount": "Rp 150.000",
        "booking_reference": "BK-2025-001"
      }
    }
  }
}

Preview Template

Preview a template with sample or custom data.

Endpoint

POST /api/v1/notifications/templates/preview

Authentication: Required (JWT token)

Request Body

{
  "notification_type": "booking_confirmation",
  "channel": "email",
  "custom_data": {
    "customer_name": "Custom Name"
  }
}

Response

{
  "template_id": "booking_confirmation_email",
  "channel": "email",
  "rendered_title": "Booking Confirmed - Salon Cantik",
  "rendered_body": "Hi Custom Name, your booking has been confirmed...",
  "rendered_html": "<html>...</html>",
  "sample_data_used": {
    "customer_name": "Custom Name",
    "tenant_name": "Salon Cantik",
    "service_names": "Hair Cut, Hair Wash"
  }
}

Notification History (Audit)

List sent notifications for audit purposes.

Endpoint

GET /api/v1/notifications/history

Authentication: Required (JWT token)

Query Parameters

Parameter Type Description
user_id string Filter by target user ID
status string Filter by status: pending, sent, delivered, failed
notification_type string Filter by notification type
skip integer Pagination offset (default: 0)
limit integer Results per page (default: 50, max: 100)

Response

{
  "items": [
    {
      "id": "507f1f77bcf86cd799439020",
      "tenant_id": "507f1f77bcf86cd799439010",
      "user_id": "507f1f77bcf86cd799439011",
      "user_type": "customer",
      "notification_type": "booking_confirmation",
      "title": "Booking Confirmed!",
      "body": "Your appointment has been confirmed",
      "priority": "normal",
      "channels": ["push", "email", "whatsapp"],
      "status": "delivered",
      "delivery_status": {
        "push": {
          "channel": "push",
          "status": "delivered",
          "sent_at": "2025-01-15T10:00:00Z",
          "delivered_at": "2025-01-15T10:00:01Z"
        },
        "email": {
          "channel": "email",
          "status": "delivered",
          "sent_at": "2025-01-15T10:00:00Z",
          "delivered_at": "2025-01-15T10:00:05Z"
        },
        "whatsapp": {
          "channel": "whatsapp",
          "status": "delivered",
          "sent_at": "2025-01-15T10:00:00Z",
          "delivered_at": "2025-01-15T10:00:02Z"
        }
      },
      "recipient_email": "budi@example.com",
      "recipient_phone": "+6281234567890",
      "recipient_name": "Budi Santoso",
      "reference_type": "appointment",
      "reference_id": "507f1f77bcf86cd799439012",
      "sent_at": "2025-01-15T10:00:00Z",
      "delivered_at": "2025-01-15T10:00:05Z",
      "created_at": "2025-01-15T10:00:00Z",
      "updated_at": "2025-01-15T10:00:05Z"
    }
  ],
  "total": 234,
  "skip": 0,
  "limit": 50
}

Notification Statuses:

Status Description
pending Created, waiting to send
queued Added to send queue
sending Currently being sent
sent Successfully sent to provider
delivered Confirmed delivered to recipient
failed Delivery failed
cancelled Cancelled before sending
partially_delivered Some channels succeeded, some failed

Best Practices

For Immediate Notifications

DO:

  • Include all required template variables for the notification type
  • Provide recipient contact info for requested channels
  • Use idempotency keys for critical notifications (prevent duplicates)
  • Check response for partial failures and handle accordingly

DON'T:

  • Send without verifying recipient contact information
  • Ignore channel failures in response
  • Skip idempotency for duplicate-sensitive notifications

For Scheduled Notifications

DO:

  • Always provide scheduled_at in UTC
  • Use timezone parameter for display purposes
  • Use reference_type and reference_id for linking to related entities
  • Include metadata for tracking (e.g., reminder_timing)
  • Cancel scheduled notifications when the underlying event is cancelled

DON'T:

  • Schedule notifications for past times
  • Forget to cancel reminders when appointments are cancelled
  • Ignore timezone conversion requirements

For Template Usage

DO:

  • Preview templates before sending to verify rendering
  • Provide all required variables for the notification type
  • Use sample_data from templates endpoint as reference

DON'T:

  • Send notifications with missing required variables
  • Assume template variables without checking documentation

Frontend UI Suggestions

Notification Center Dashboard

+------------------------------------------------------------------+
|  NOTIFICATION CENTER                                    [+ New]   |
+------------------------------------------------------------------+
|                                                                   |
|  QUICK STATS                              USAGE THIS MONTH        |
|  +------------+  +------------+           +--------------------+  |
|  |    145     |  |     12     |           | Push:  145/∞      |  |
|  |   Sent     |  |  Scheduled |           | Email: 234/1000   |  |
|  | This Week  |  |  Pending   |           | WA:     89/500    |  |
|  +------------+  +------------+           +--------------------+  |
|                                                                   |
|  RECENT NOTIFICATIONS                          [View All →]       |
|  +---------------------------------------------------------------+|
|  | booking_confirmation  | Budi S.  | Delivered  | 2 min ago     ||
|  | booking_reminder      | Siti A.  | Scheduled  | in 24 hours   ||
|  | payment_receipt       | Ahmad R. | Delivered  | 15 min ago    ||
|  +---------------------------------------------------------------+|
|                                                                   |
+------------------------------------------------------------------+

Send Notification Form

+------------------------------------------------------------------+
|  SEND NOTIFICATION                                                |
+------------------------------------------------------------------+
|                                                                   |
|  Notification Type: [  Booking Confirmation  ▼ ]                  |
|                                                                   |
|  Recipient                                                        |
|  +---------------------------------------------------------------+|
|  | Search customer... [                              ] [Search]  ||
|  | Selected: Budi Santoso                                        ||
|  | Email: budi@example.com  |  Phone: +6281234567890             ||
|  +---------------------------------------------------------------+|
|                                                                   |
|  Channels                                                         |
|  [✓] Push    [✓] Email    [✓] WhatsApp                           |
|                                                                   |
|  Template Data                                                    |
|  +---------------------------------------------------------------+|
|  | Customer Name:    [Budi Santoso            ]                  ||
|  | Service Names:    [Hair Cut, Hair Wash     ]                  ||
|  | Appointment Date: [20 Januari 2025         ]                  ||
|  | Appointment Time: [14:00                   ]                  ||
|  | ... (auto-populated based on notification type)               ||
|  +---------------------------------------------------------------+|
|                                                                   |
|  [Preview Template]                    [Send Now] [Schedule →]    |
|                                                                   |
+------------------------------------------------------------------+

Schedule Notification Modal

+------------------------------------------------------------------+
|  SCHEDULE NOTIFICATION                                      [X]   |
+------------------------------------------------------------------+
|                                                                   |
|  When to Send                                                     |
|  +---------------------------------------------------------------+|
|  | Date: [ 2025-01-19 📅 ]   Time: [ 13:00 ⏰ ]                   ||
|  | Timezone: [ Asia/Jakarta (WIB) ▼ ]                            ||
|  |                                                                ||
|  | Will send at: 2025-01-19 06:00:00 UTC                         ||
|  +---------------------------------------------------------------+|
|                                                                   |
|  Quick Schedule Options                                           |
|  [ 1 hour before ] [ 24 hours before ] [ Custom ]                 |
|                                                                   |
|  Metadata (Optional)                                              |
|  +---------------------------------------------------------------+|
|  | Reminder Timing: [24 hours before    ]                        ||
|  +---------------------------------------------------------------+|
|                                                                   |
|                               [Cancel] [Schedule Notification]    |
|                                                                   |
+------------------------------------------------------------------+

Scheduled Notifications List

+------------------------------------------------------------------+
|  SCHEDULED NOTIFICATIONS                                          |
+------------------------------------------------------------------+
|  Filters: [Status ▼] [Type ▼] [Date Range 📅]        [Search 🔍] |
+------------------------------------------------------------------+
|                                                                   |
|  | Type              | Recipient  | Scheduled For    | Status    |
|  |-------------------|------------|------------------|-----------|
|  | booking_reminder  | Budi S.    | Jan 19, 13:00   | ● Pending |
|  | booking_reminder  | Siti A.    | Jan 20, 09:00   | ● Promoted|
|  | payment_receipt   | Ahmad R.   | Jan 18, 10:00   | ✓ Sent    |
|  |-------------------|------------|------------------|-----------|
|                                                                   |
|  Actions per row: [View] [Reschedule] [Cancel]                    |
|                                                                   |
|  Pagination: [< Prev] Page 1 of 3 [Next >]                        |
|                                                                   |
+------------------------------------------------------------------+

Usage Statistics Dashboard

+------------------------------------------------------------------+
|  NOTIFICATION USAGE                           Period: [Jan 2025▼] |
+------------------------------------------------------------------+
|                                                                   |
|  CHANNEL USAGE                                                    |
|  +-------------------+  +-------------------+  +-------------------+
|  |      PUSH         |  |      EMAIL        |  |     WHATSAPP     |
|  |  ∞ Unlimited      |  |  ████████░░ 76%   |  |  █████░░░░░ 18%  |
|  |  145 sent         |  |  234/1000 used    |  |  89/500 used     |
|  |  96.7% success    |  |  766 remaining    |  |  411 remaining   |
|  +-------------------+  +-------------------+  +-------------------+
|                                                                   |
|  DELIVERY STATS                                                   |
|  +---------------------------------------------------------------+|
|  |  Total Sent: 473  |  Success: 462 (97.7%)  |  Failed: 11      ||
|  +---------------------------------------------------------------+|
|                                                                   |
|  [!] Tip: Upgrade to PRO for 1000 emails/month                   |
|                                                                   |
+------------------------------------------------------------------+

Template Preview Modal

+------------------------------------------------------------------+
|  TEMPLATE PREVIEW                                            [X]  |
+------------------------------------------------------------------+
|  Type: booking_confirmation    Channel: [Push ▼]                  |
+------------------------------------------------------------------+
|                                                                   |
|  PREVIEW                                                          |
|  +---------------------------------------------------------------+|
|  |  📱 PUSH NOTIFICATION                                         ||
|  |  +---------------------------------------------------+        ||
|  |  | Booking Confirmed!                                |        ||
|  |  | Hi Budi Santoso, your booking at Salon Cantik     |        ||
|  |  | for Hair Cut, Hair Wash on 20 Januari 2025 at     |        ||
|  |  | 14:00 has been confirmed.                         |        ||
|  |  +---------------------------------------------------+        ||
|  +---------------------------------------------------------------+|
|                                                                   |
|  SAMPLE DATA USED                                                 |
|  +---------------------------------------------------------------+|
|  | { "customer_name": "Budi Santoso",                            ||
|  |   "tenant_name": "Salon Cantik", ... }                        ||
|  +---------------------------------------------------------------+|
|                                                                   |
|  [Edit Sample Data]                         [Close] [Use Template]|
|                                                                   |
+------------------------------------------------------------------+

Notification Status Colors

Status Color Icon
pending Yellow
promoted Blue
processing Orange
completed / delivered Green
failed Red
cancelled Gray

Error Handling

Common Errors

Error Status Code Cause Solution
Invalid ObjectId format 422 Malformed ID Use valid MongoDB ObjectId
Insufficient permissions 403 Wrong user role Requires STAFF or higher
scheduled_at must be in the future 422 Past datetime Use future datetime
Template not found 404 Invalid notification type Check available types
Channel not enabled for plan 200 (partial) Subscription limit Upgrade plan or use different channel
Quota exceeded 200 (partial) Monthly limit reached Wait for reset or upgrade

Error Response Format

{
  "detail": "Error message describing the issue"
}

API Reference Summary

Endpoint Method Purpose Key Response
/notifications/send POST Send immediate notification Channel success/failure status
/notifications/schedule POST Schedule future notification Scheduling tier and task ID
/notifications/scheduled GET List scheduled notifications Paginated list with filters
/notifications/scheduled/{id} GET Get scheduled notification details Full notification details
/notifications/scheduled/{id} PUT Reschedule notification Updated scheduling info
/notifications/scheduled/{id} DELETE Cancel scheduled notification Cancellation confirmation
/notifications/usage GET Get usage statistics Per-channel usage and limits
/notifications/templates GET List available templates Template configurations
/notifications/templates/preview POST Preview template rendering Rendered content
/notifications/history GET List sent notifications (audit) Notification delivery history

Notification System

Document Description
Notification Settings Customize reminder timings and message templates
Device Management FCM token registration and device management APIs
Push Notification Integration Frontend Firebase setup and implementation guide
Appointment Management - Auto Notifications Booking-triggered notifications flow

Integration


Next Steps:

  1. Check current usage: GET /notifications/usage
  2. List available templates: GET /notifications/templates
  3. Preview a template: POST /notifications/templates/preview
  4. Send your first notification: POST /notifications/send
  5. Monitor delivery: GET /notifications/history

For webhook-triggered notifications (booking confirmations, payment receipts), refer to the Webhook Integration documentation.