Technical Specification Example — Notification Service
Example document for Technical Specification. Use this as a reference when creating your own.
Professional Review Recommended
This document may have legal or financial implications. We recommend having a qualified professional review the final version before use.
Document: Technical Specification
Example Document
Last updated 6/4/2026
Technical Specification: Notification Service
Author: Maya Okonkwo, Platform Team Status: Approved Date: 5 June 2026 Version: 1.0 Related documents: Messaging PRD, Platform System Architecture, Channel-Preferences Feature Spec
1. Overview and goals
The Notification Service is the single component responsible for delivering transactional notifications — account alerts, mentions, and status changes — to a recipient's preferred channel. Other services hand it a message; it decides the channel, dispatches it, records the outcome, and retries transient failures. It exists so that delivery logic, channel adapters, and retry handling live in one place instead of being re-implemented inside every feature that needs to notify someone.
- Purpose: accept a notification request and reliably deliver it to the recipient's preferred channel.
- Goals (priority order): reliability of delivery, then low dispatch latency, then maintainability of the channel adapters.
- Non-goals: it does not compose marketing campaigns, manage recipient consent (the Preferences service owns that), or render in-app UI; it only dispatches a prepared message.
2. Functional requirements
| ID | Requirement |
|---|---|
| FR-1 | The service shall accept a notification request containing a recipient id, a message body, and a notification type, and return an accepted/rejected result synchronously. |
| FR-2 | The service shall look up the recipient's preferred channel from the Preferences service and dispatch the message to that channel. |
| FR-3 | The service shall fall back to email if the preferred channel is unavailable or the recipient has no preference set. |
| FR-4 | The service shall record the delivery status (accepted, sent, failed) for every notification so callers can query the outcome. |
| FR-5 | The service shall retry transient delivery failures with back-off and route permanently failed messages to a dead-letter store for review. |
3. Non-functional requirements
| ID | Category | Target |
|---|---|---|
| NFR-1 | Performance | 95% of accepted notifications are dispatched within 2 seconds; acceptance responds within 200 ms. |
| NFR-2 | Reliability | 99.9% of notifications that are accepted are eventually delivered or dead-lettered, never silently lost. |
| NFR-3 | Scalability | Sustains 500 notifications per second by scaling dispatcher workers horizontally off the queue. |
| NFR-4 | Security | All inbound calls are authenticated; recipient contact details are encrypted in transit and at rest and never written to logs. |
4. Proposed design and approach
The service is split into three parts behind a small HTTP API. The API validates and accepts requests (FR-1), the dispatcher does the work asynchronously (FR-2 to FR-5), and the channel adapters isolate each delivery mechanism so a new channel can be added without touching the rest.
| Part | Responsibility |
|---|---|
| Intake API | Validates the request, persists it as "accepted," enqueues a dispatch job, and returns immediately |
| Dispatcher | Reads jobs from the queue, resolves the channel, calls the right adapter, records the outcome, and retries |
| Channel adapters | One adapter per channel (email, push, SMS); each knows only how to deliver on its channel |
Key flow — a notification is delivered:
- A caller sends an authenticated request to the Intake API with recipient id, body, and type.
- The API validates the payload, writes a notification record with status "accepted," enqueues a dispatch job keyed by the notification id, and returns the id to the caller.
- The dispatcher picks up the job, asks the Preferences service for the recipient's preferred channel, and hands the message to the matching adapter — falling back to the email adapter per FR-3.
- On success the dispatcher marks the record "sent"; on a transient failure it retries with back-off; after the retry limit it marks the record "failed" and writes it to the dead-letter store.
5. Interfaces and APIs
| Operation | Direction | Inputs | Output | Errors |
|---|---|---|---|---|
| sendNotification | Exposed | recipient id, message body, notification type, idempotency key | notification id, status "accepted" | 400 invalid payload; 401 unauthenticated; 409 duplicate idempotency key returns the existing id |
| getNotificationStatus | Exposed | notification id | status (accepted / sent / failed), last updated | 404 unknown id; 401 unauthenticated |
| getPreferredChannel | Consumed | recipient id | preferred channel, or none | timeout or 5xx treated as "no preference," triggering the email fallback |
6. Data
| Entity | Key fields | Notes |
|---|---|---|
| Notification | id, recipient_id, type, body, channel, status, idempotency_key, created_at, updated_at | Stored in the service's own database; idempotency_key is unique to prevent duplicates (FR-1) |
| Delivery attempt | id, notification_id, channel, result, attempted_at | One row per dispatch attempt, used for retries and auditing |
| Dead-letter record | notification_id, last_error, failed_at | Written when retries are exhausted; reviewed each morning |
7. Dependencies and constraints
- External dependencies: the Preferences service (for channel lookup, with a fallback when it is slow or down), a managed email provider, a push provider, and an SMS provider, each reached through its own adapter.
- Platform constraints: the SMS provider allows 100 requests per second per account, so the SMS adapter paces dispatch to stay under that limit; all providers are called over TLS only.
- Assumptions: every recipient has a valid email on file, which is why email is a safe universal fallback; if that ceases to hold, FR-3 must be revisited.
8. Acceptance criteria
- Given a valid request with a new idempotency key, when it is accepted, then a notification id is returned within 200 ms and the record is stored with status "accepted."
- Given a recipient whose preferred channel is push, when a notification is accepted, then it is dispatched via the push adapter and the record is marked "sent" within 2 seconds.
- Given a recipient with no preference set, when a notification is accepted, then it is dispatched via email.
- Given the same idempotency key sent twice, when the second request arrives, then the existing notification id is returned and no second message is dispatched.
- Given a transient provider failure, when the dispatcher retries, then the message is delivered once with no duplicate; given the retry limit is exhausted, then the record is marked "failed" and written to the dead-letter store rather than lost.
9. Open questions
- Should per-recipient quiet hours be honoured by this service or by the Preferences service? Currently assumed to be out of scope for version 1.0.
- The push provider's exact rate limit is unconfirmed; pacing for push is provisional until the vendor replies.
Notes
An illustrative worked example for a fictional notification service; the requirements, design, interfaces, and numbers are made up to show the level of detail, not a recommendation.
About this Example
Part of the Technical Specification document collection
Document Type
Technical Specification
A detailed technical document defining system requirements, architecture, interfaces, and implementation details.