A Notification represents a single message sent through GOV.UK Notify. Each notification has a unique ID, tracks delivery status, and maintains an audit trail.
# From app/models.py - Notification modelclass Notification: id: UUID # Unique notification ID # Recipient to: str # Email address or phone number normalised_to: str # Normalized for searching # Template & Content template_id: UUID template_version: int notification_type: str # "email", "sms", or "letter" # Sending Context service_id: UUID api_key_id: UUID # Which API key was used key_type: str # "normal", "team", or "test" # Status & Timing status: str # Current delivery status created_at: datetime # When notification was created sent_at: datetime # When sent to provider updated_at: datetime # Last status update # Billing billable_units: int # SMS fragments or letter pages international: bool # International SMS/letter? phone_prefix: str # Country code for SMS rate_multiplier: decimal # Cost multiplier postage: str # Letter postage class # Tracking reference: str # Provider reference client_reference: str # Your custom reference # Content personalisation: dict # Encrypted placeholder values # Optional job_id: UUID # If sent via bulk job created_by_id: UUID # If sent via UI reply_to_text: str # Reply-to address used
# From app/constants.pyKEY_TYPE_NORMAL = "normal" # Live API key - sends real notificationsKEY_TYPE_TEAM = "team" # Team key - sends only to team/guest listKEY_TYPE_TEST = "test" # Test key - doesn't actually send
Normal Key
Team Key
Test Key
Sends to anyone
Notifications are billable
Count toward daily limits
Require live (non-restricted) service
Sends only to verified team members and guest list
# International notifications have rate multipliers:international: bool # Is this international?phone_prefix: str # Country code (e.g., "+33", "+1")rate_multiplier: decimal # Cost multiplier vs UK rate# Example: # UK SMS: rate_multiplier = 1.0# France SMS: rate_multiplier = 1.5 (costs 1.5x UK rate)
# When sending:client_reference = "ORDER-12345"# Query notifications by your reference:GET /v2/notifications?reference=ORDER-12345# Stored in notification:notification.client_reference = "ORDER-12345"
Client references are indexed for fast searching. Maximum 255 characters.
Notifications older than 7 days move to notification_history table:
# From app/models.py - Two tables with same structure:Notification # Last 7 days (fast queries)NotificationHistory # Archived (slower queries)# View combines both:NotificationAllTimeView # Queries both tables
Querying notifications_all_time_view is slower than querying recent notifications directly.