Notification Service API

Centralized notification delivery service for email, SMS, HubSpot, and Slack channels.

Overview

The Notification Service is a centralized API for all patient and internal notifications. Instead of each service integrating directly with SES, Twilio, HubSpot, and Slack, callers send a single POST /notify/send request and let the service handle template resolution, channel routing, delivery, and logging.

Base URL

https://api.yourera.com/notify

How It Works

  1. Caller sends a POST /notify/send with a notification type and recipient data
  2. Service resolves the template for that notification type
  3. Template engine renders the template with provided variables
  4. Channel config determines which channels are enabled for this type
  5. Service dispatches to all enabled channels (email, SMS, HubSpot, Slack)
  6. Each channel delivery is independent — one failure doesn't block others
  7. All delivery attempts are logged with status, channel, and timestamps

Authentication

The /notify/send endpoint requires HMAC-SHA256 authentication. Admin endpoints (/notify/templates/*, /notify/channels/*) require an Admin JWT token.

HMAC Authentication (Send Endpoint)

HeaderDescription
X-API-Key Your public API key identifier
X-Timestamp Current timestamp in ISO 8601 format. Must be within 5 minutes of server time.
X-Signature HMAC-SHA256 hex digest of timestamp + '.' + jsonBody

Signature Formula

HMAC-SHA256(apiSecret, timestamp + '.' + JSON.stringify(body))

Node.js Example

import crypto from 'node:crypto';

const timestamp = new Date().toISOString();
const body = JSON.stringify({
  type: 'prescription_approved',
  recipient: { email: 'patient@example.com', phone: '5551234567' },
  variables: { patientName: 'Jane Doe', medication: 'Semaglutide' }
});

const signature = crypto
  .createHmac('sha256', API_SECRET)
  .update(timestamp + '.' + body)
  .digest('hex');

await fetch('https://api.yourera.com/notify/send', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': API_KEY,
    'X-Timestamp': timestamp,
    'X-Signature': signature,
  },
  body: body,
});

Send Notification

POST /notify/send

Send a notification to a patient or internal recipient. The service resolves the appropriate template, renders it with the provided variables, and dispatches to all enabled channels.

Request Body

FieldTypeDescription
type string required Notification type. See notification types.
recipient object required Recipient info: { email?: string, phone?: string, name?: string }. At least one of email or phone is required.
variables object required Template variables. Keys match {{variableName}} placeholders in the template.
channels string[] optional Override which channels to use. If omitted, uses the channel config for this type.

Example Request

{
  "type": "prescription_approved",
  "recipient": {
    "email": "jane@example.com",
    "phone": "5041234567",
    "name": "Jane Doe"
  },
  "variables": {
    "patientName": "Jane Doe",
    "medication": "Semaglutide 5mg/mL",
    "pharmacyName": "Galleria Medical Pharmacy"
  }
}

Success Response 200

{
  "success": true,
  "channels": [
    { "channel": "email", "status": "sent" },
    { "channel": "sms", "status": "sent" }
  ],
  "logId": "550e8400-e29b-41d4-a716-446655440000"
}

Error Responses

CodeConditionBody
400 Unknown notification type { "error": "Unknown notification type: foo" }
400 Missing required fields { "error": "Validation failed", "details": [...] }
400 No recipient (email and phone both missing) { "error": "At least one of email or phone is required" }
401 HMAC auth failure { "error": "Missing authentication headers" }

Notification Types

43 notification types organized in 3 categories. Each type is seeded on first deployment with an email template. SMS templates are added as A2P 10DLC registration completes.

General (29 types)

TypeDescriptionRequired Variables
welcome New patient welcome patientName
otp One-time password for verification code
password_reset Password reset link patientName, resetLink
information_changed Profile info was updated patientName, changedFields
prescription_changed Prescription modification patientName, medication, change
what_to_expect Post-intake expectations patientName, intakeType
doctor_message Message from care team patientName, providerName
support_message Support team message patientName, message
first_prescription First-ever prescription approved patientName, medication, providerName, providerSuffix, dosingLine
new_prescription New prescription approved patientName, medication, pharmacyName
new_refill Refill prescription submitted patientName, medication
four_month_checkin 4-month check-in reminder patientName
subscription_renewal Subscription auto-renewal notice patientName, plan, amount, renewalDate
payment_method_updated Card/payment method changed patientName
doctor_reviewed Doctor completed chart review patientName, providerName
magic_link Resume intake magic link magicLinkUrl, intakeType
follow_up_due Follow-up appointment due patientName, dueDate
follow_up_past_due Follow-up is overdue patientName, dueDate
follow_up_two_days Follow-up in 2 days patientName, appointmentDate
checkin_renewal Check-in for subscription renewal patientName
visit_scheduled Appointment confirmed patientName, appointmentDate, providerName
visit_upcoming Appointment reminder patientName, appointmentDate, providerName
visit_complete Visit summary patientName, providerName
three_month_checkin 3-month check-in reminder patientName
billing_plan_change Plan upgrade/downgrade patientName, oldPlan, newPlan, amount
pending_payment Payment is due patientName, amount, dueDate
treatment_change Treatment plan modified patientName, medication, change
balance_expiring Account balance expiring soon patientName, balance, expiryDate
questionnaire_link Health questionnaire to complete patientName, questionnaireUrl

Orders (12 types)

TypeDescriptionRequired Variables
first_order_confirmation First-ever order placed patientName, medication, orderNumber
order_confirmation Order placed patientName, medication, orderNumber
receipt Payment receipt patientName, amount, orderNumber
order_edited Order was modified patientName, orderNumber, change
order_canceled Order canceled patientName, orderNumber, reason
abandoned_checkout Intake started but not finished (30 min) magicLinkUrl, intakeType
abandoned_post_checkout Payment saved but intake not submitted patientName, magicLinkUrl
payment_error Payment charge failed patientName, amount, reason
lab_received Lab sample received patientName
lab_resulted Lab results ready patientName
lab_rejected Lab sample rejected patientName, reason
treatment_active Treatment is now active patientName, medication

Shipping (6 types)

TypeDescriptionRequired Variables
first_shipping_confirmation First-ever shipment created patientName, medication, trackingNumber, carrier
shipping_confirmation Shipment created patientName, medication, trackingNumber, carrier
shipping_update Shipment status change patientName, medication, status, trackingNumber, carrier
delivery_tomorrow Package arriving tomorrow patientName, medication, trackingNumber
out_for_delivery Package out for delivery patientName, medication, trackingNumber
delivered Package delivered patientName, medication, trackingNumber

Channel Matrix

The full channel matrix for all 43 notification types is managed through the Admin Portal. On initial deployment, all types are seeded with Email enabled and all other channels disabled. Channels can be toggled per-type via the admin UI or the PUT /notify/channels/:type API.

Available Channels

ChannelProviderStatus
EmailAWS SESLive
SMSTwilioPending (A2P 10DLC registration)
PushNot implementedPlanned
SlackSlack WebhooksInternal only

Template Engine

Templates use Mustache-style {{variableName}} placeholders. The template engine substitutes variables and handles edge cases gracefully:

Example

// Template
"Hi {{patientName}}, your {{medication}} has been approved!"

// Variables
{ "patientName": "Jane", "medication": "Semaglutide" }

// Result
"Hi Jane, your Semaglutide has been approved!"

Templates CRUD

Admin endpoints for managing notification templates. Requires Admin JWT in Authorization: Bearer <token>.

GET /notify/templates

List all notification templates.

GET /notify/templates/:type

Get template for a specific notification type.

PUT /notify/templates/:type

Update template for a notification type.

Update Request Body

FieldTypeDescription
emailSubject string optional Email subject line template
emailHtml string optional Email HTML body template
emailText string optional Email plain text body template
smsBody string optional SMS message body template

Channels CRUD

Admin endpoints for managing channel configuration per notification type.

GET /notify/channels

List channel configuration for all notification types.

PUT /notify/channels/:type

Update channel configuration for a notification type.

Update Request Body

{
  "email": true,
  "sms": true,
  "hubspot": false,
  "slack": false
}
Note: Setting all channels to false is allowed. This effectively disables notifications for that type. The send endpoint will return success with "channels": [].

Delivery Log

Every notification dispatch is logged with:

FieldDescription
idUUID log entry ID
notificationTypeThe notification type sent
recipientEmailEmail address (if sent)
recipientPhonePhone number (if sent)
channelsArray of channel results
status"sent", "partial", or "failed"
createdAtISO 8601 timestamp

Health Check

GET /health

Health check endpoint. No authentication required.

{
  "status": "ok",
  "service": "notification-service",
  "timestamp": "2026-03-20T12:00:00.000Z"
}

Admin Portal Integration

The admin portal at admin.yourera.com will include a Notifications page for managing the full notification lifecycle. The page provides:

The admin portal calls the notification service Admin JWT-authenticated endpoints:

EndpointDescription
GET /notify/templates Load all templates
PUT /notify/templates/:type Update a template
GET /notify/channels Load channel config
PUT /notify/channels/:type Toggle channels
GET /notify/log Delivery history

Roadmap

Phase 1 — Email Only (Current)

Phase 2 — SMS

Phase 3 — Intake Magic Link + Abandoned Checkout

Phase 4 — Scheduled Notifications

Phase 5 — Push Notifications

What's Missing (Dependency Tracker)

DependencyBlocksStatus
AWS SES production access (us-east-1) All email delivery Pending
Twilio A2P 10DLC SMS delivery Pending registration
Notification service DB created Service startup Pending
Admin portal notifications page Template/channel management Not started
Intake gateway magic link flow abandoned_checkout, magic_link Not started
EventBridge scheduler follow_up_*, checkin_*, delivery_* Not started
Mobile app push integration Push notifications Not started