core-notification-service
Sends transactional emails via Resend and manages notification queues. Used by other services (auth, billing) to deliver team invitations, payment confirmations, and system notifications.
Worker name: crow-core-notification-service
Domain (prod): internal.notifications.crowai.dev
Domain (dev): dev.internal.notifications.crowai.dev
Schema
No D1 database -- the notification service is stateless. It processes email requests from queues and sends them via the Resend API.
Routes
| Method | Path | Description |
|---|---|---|
| POST | /api/v1/notifications/send | Send an email notification |
| GET | /health | Health check |
Environment Variables
| Variable | Example |
|---|---|
| ENVIRONMENT | dev |
| FROM_EMAIL | noreply@crowai.dev |
| FROM_NAME | CROW Team (Dev) |
| AUTH_SERVICE_URL | https://dev.api.crowai.dev |
Secrets
| Secret | Purpose |
|---|---|
| BETTER_AUTH_SECRET | JWT verification |
| INTERNAL_GATEWAY_KEY | Gateway trust validation |
| RESEND_API_KEY | Resend email API authentication |
Bindings
| Binding | Type | Name |
|---|---|---|
| EMAIL_QUEUE | Queue (producer + consumer) | email-queue |
| (consumer) | Queue (consumer) | crow-notification-queue |
Queue Configuration
| Queue | Role | Batch Size | Retries | DLQ |
|---|---|---|---|---|
email-queue | Producer + Consumer | 10 | 3 | email-dlq |
crow-notification-queue | Consumer | 10 | - | - |
Message Type
EmailQueueMessage
{
id: string
to: string
template: string
data: Record<string, unknown>
timestamp: number
}
Templates
The service uses HTML email templates located in src/templates/. Templates are rendered with dynamic data from the queue message.
Dependencies
- Inbound: auth service (team invitations, welcome emails), billing service (payment confirmations)
- Outbound: Resend API
Key Behaviors
- INTERNAL_GATEWAY_KEY guard: All API routes require the shared internal key
- Queue-based: Most notifications arrive via queue messages rather than HTTP requests, making the processing asynchronous and reliable
- Trusted queue messages: Queue messages are trusted (no additional auth) since only internal services can produce to the queue