Overview
The shared push-notification service for a fiber-optic ISP — the single path every other backend uses to reach customers on their phones. Rather than make each system learn the mechanics of Amazon SNS, this service exposes one authenticated API: register a device, subscribe it to broadcasts, or fire a targeted or broadcast push, with a history of everything sent. It runs as a containerized FastAPI app on AWS Lambda, and I built all of it — API, data model, SNS integration, and the service’s infrastructure as code — connecting into the platform’s existing API Gateway and database cluster (a new database inside the shared one) rather than standing those up myself.
The problem
The ISP needed a single, reusable service to talk to customers through push notifications — both targeted messages to one customer and general announcements to everyone — without every other system having to learn the details of AWS SNS. SNS identifies devices and subscriptions by opaque resource identifiers, and the platform’s clients shouldn’t have to store or manage those. The service had to hide all of that behind a simple API and keep a durable record of what was sent for an admin panel.
What I built
- Containerized FastAPI on Lambda — a FastAPI app shipped as a Docker image on Amazon ECR and run on Lambda via Mangum, so the same code runs locally and in production.
- Device registration — an endpoint that takes a device token + customer + platform (Android/iOS), creates the corresponding SNS platform endpoint, and binds it to the customer so notifications follow the logged-in session even if a different customer signs in on the same phone.
- Subscriptions to broadcasts — subscribe/unsubscribe a device to a general SNS topic, so a single publish reaches every subscribed device.
- Individual push — fan a targeted notification out to all of a customer’s registered devices, building the proper payload and reporting a per-device success/failure summary.
- Broadcast push — publish a single message to the general topic to reach the whole audience at once.
- Notification history — every notification is persisted in a database and exposed through REST endpoints for an admin panel.
Architecture

The deliberate design decision was to keep every SNS resource identifier inside the service’s own database, keyed by the identifiers clients already have — so a client only ever sends a device token, customer, and platform, and never has to know or store anything about AWS. The backend resolves the SNS resources internally, which meant clients needed the minimum possible changes to adopt the service. Operations are also made resilient — e.g. if persisting a token fails after SNS created an endpoint, the service rolls back by deleting the orphaned endpoint.
Impact
The ISP got a push-notification service its app and internal tools can call with a simple authenticated request — no AWS knowledge required on the client side. It became the one delivery path for push across the platform: the mobile app, the admin panel, and other backend services all reach customers through it — including the prepaid-expiration reminder pipeline, which hands its due reminders to this service for the actual send. Targeted and broadcast notifications run through the same service, every message is recorded for the admin panel, and the whole thing deploys itself serverlessly through CI/CD, scaling to zero when idle. The service itself is specific to this platform, but the architecture generalizes — the same pattern could back push delivery for any product without rework.