Notix is an event driven notification delivery service built with FastAPI, Celery, and RabbitMQ. It is designed to help applications send reliable email and webhook notifications with authentication, API key management, idempotency, retries, queue-based processing, and delivery tracking.
- Email/password sign-up and login
- Email verification via OTP
- Google and GitHub OAuth login
- JWT-based access token flow with refresh tokens
- Account deletion and logout support
- Rate limiting on sensitive auth endpoints
- Create email notifications for registered users
- Create webhook notifications for configured endpoints
- Notification idempotency using unique idempotency keys
- Priority-based queue routing for high, medium, and critical traffic
- Delivery status tracking through the database
- Automatic retries for transient failures and dead-letter handling for non-transient failures
- Register webhook endpoints per user
- Store webhook secrets securely
- Deliver signed webhook payloads with custom headers
- Track webhook notifications with the same persistence model as email
- Async SQLAlchemy with PostgreSQL
- Redis-backed state and idempotency checks
- RabbitMQ + Celery for asynchronous processing
- Docker Compose-based local development environment
- Sentry integration for observability and error tracking
Notix follows a layered architecture:
- API layer: FastAPI routers and request handlers
- Service layer: business logic for auth, notifications, webhooks, and API keys
- Repository layer: persistence abstractions for PostgreSQL models
- Worker layer: Celery tasks that process email and webhook delivery asynchronously
- Infrastructure layer: PostgreSQL, Redis, RabbitMQ, and Resend
- Idempotency: Prevents duplicate processing by ensuring the same notification can be safely handled more than once.
- At-least-once delivery: Retries transient failures so notifications are not lost even if a delivery attempt fails temporarily.
- Dead-lettering: Failed messages are moved to a dead-letter queue for inspection and recovery instead of being silently dropped.
- Backpressure: Queue depth is checked before accepting new notifications to avoid overwhelming the system and causing backlog buildup.
- Priority queues: Notifications are routed through priority-aware queues so critical messages are processed faster.
- Queue durability: Durable queues and messages help preserve delivery work across restarts, crashes, or temporary outages.
- A client calls one of the API routes.
- The FastAPI service validates the request and creates or updates a domain entity.
- For notification requests, the service writes the notification record and publishes work to the broker.
- Celery workers consume tasks from RabbitMQ and execute delivery logic.
- Delivery status is updated in PostgreSQL and tracked by the API.
app/
api/
models/ # SQLAlchemy models
repo/ # repositories layer
routers/ # FastAPI endpoints
schemas/ # request/response schemas
services/ # core service logic
core/ # settings, security, exception handling
database/ # session and DB utilities
worker/ # Celery app, tasks, and queue config
deps.py # Dependencies
limiter.py # Rate limiting
main.py # FastAPI entrypoint
alembic/ # database migrations
Dockerfile
docker-compose.yml
test/ # pytest test suite
Before running Notix locally, make sure you have:
- Python 3.12 or newer
- Docker and Docker Compose
- uv (recommended for dependency management)
- access to a PostgreSQL instance, Redis, RabbitMQ, and Resend credentials
cp .env.example .envThe repository includes a full local stack for the API, workers, PostgreSQL, Redis, and RabbitMQ.
docker compose up --buildThis will launch:
- PostgreSQL for app data
- PostgreSQL for test data
- Redis
- RabbitMQ management UI at http://localhost:15672
- API server at http://localhost:8000
- Celery worker pools for high, standard, webhook, and batch processing
- Celery beat scheduler
docker compose downuv syncuv run alembic upgrade headuv run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000uv run celery -A app.worker.celery_app worker -Q notix.high -P gevent -l infouv run celery -A app.worker.celery_app worker -Q notix.standard,notix.webhook -P gevent -l infouv run celery -A app.worker.celery_app worker -Q notix.batch -P gevent -l infouv run celery -A app.worker.celery_app beat -l infoOpen your browser and navigate to http://localhost:8000/docs.
Run the test suite with:
uv run pytestRun in verbose mode:
uv run pytest -vThe repository includes tests covering authentication, notifications, webhooks, and worker flows depending on the environment setup.
- Database migrations are managed with Alembic.
- Notification processing is intentionally asynchronous to keep the API responsive.
- The service uses idempotency keys to prevent duplicate processing for repeated requests.
- Worker failures are routed through retry and dead-letter logic for resilience.