High-level Architecture
Relevant source files
The following files were used as context for generating this wiki page:
Send Again is an open-source email campaign platform designed for high deliverability via Amazon SES. The system provides a multi-tenant environment where users manage "Workspaces" tied to specific domains. The architecture is built on Next.js, utilizing Supabase for authentication and database management, and AWS SES for the core mail transfer and delivery tracking capabilities.
The platform is divided into three primary functional layers: the User Interface (Dashboard), the REST API (for programmatic automation), and the Background Processing system (handling high-volume send jobs). These layers interact through a shared PostgreSQL schema hosted on Supabase, ensuring consistency across campaign management, contact suppression, and real-time event tracking.
Sources: README.md:3-15, src/lib/db.ts:16-35, src/app/app/page.tsx:750-780
Core System Components
1. Workspace and Multi-tenancy
The system architecture centers around the Workspace, which acts as the primary container for domains, sending identities, and billing. Each workspace maintains its own set of verified domains and configuration sets within Amazon SES.
- Authentication: Handled via Supabase JWT or scoped API Keys.
- Permissions: Managed through
workspace_memberships, where users are assigned roles likeownerormember.
Sources: src/lib/db.ts:285-330, src/lib/openapi.ts:14-30
2. Email Delivery Pipeline
Email delivery is handled asynchronously. When a user or API agent initiates a send, a SendJob is created. A worker process then iterates through the job's recipients, applying rate limits and credit checks.
The diagram shows the end-to-end flow from job creation to event tracking via SNS webhooks.
Sources: src/lib/db.ts:1080-1120, README.md:144-150
3. Contact Management and Suppression
Contacts are stored per workspace with arbitrary metadata fields. The system enforces an automatic suppression list through contact_unsubscribes. Before any send, the system filters the recipient list against these suppression records.
Sources: src/lib/db.ts:460-500, src/lib/db.ts:600-640
Data Models
The system relies on several critical tables in the Supabase PostgreSQL database to manage the state of campaigns and delivery.
| Entity | Description | Key Fields |
|---|---|---|
| Workspace Settings | Global config for a domain. | id, from_address, rate_limit, footer_html |
| Contacts | Recipient data and metadata. | email, workspace_id, fields (JSONB) |
| Send Jobs | State of a bulk email task. | status, total, sent, failed, payload |
| Email Events | Tracking logs from SES. | message_id, event_type, timestamp, detail |
| API Keys | Programmatic access tokens. | key_hash, scopes, workspace_id |
Sources: src/lib/openapi.ts:45-120, src/lib/db.ts:700-750
API and Integration Layer
Send Again exposes a comprehensive REST API for developers and AI agents. Authentication is performed using Bearer tokens, which can either be Supabase user JWTs or scoped API keys (e.g., sk_...).
Scoped API Keys
The architecture implements fine-grained access control for programmatic keys.
The diagram represents the relationship between API keys and their assigned permissions.
Sources: src/lib/openapi.ts:20-40, src/lib/db.ts:150-180
Campaign and Workflow Logic
The platform supports complex email workflows, including delays and conditional logic based on recipient behavior (e.g., whether they opened a previous email).
Workflow Node Types
- Send Node: Dispatches an email to a manual list or a rule-based audience.
- Delay Node: Pauses the workflow for a specified duration in days or hours.
- Rule Node: Evaluates conditions against contact fields or send history.
The flowchart illustrates a typical campaign sequence involving conditional logic and delays.
Sources: src/app/campaigns/page.tsx:60-100, src/app/campaigns/page.tsx:550-600
AI Compose System (Vibe)
A specialized module, "Vibe," integrates with OpenAI to generate raw HTML email fragments. It accepts natural language instructions and optionally takes existing HTML to perform revisions.
This sequence shows how the system translates user instructions into email code.
Sources: src/app/api/vibe/route.ts:80-140
Summary
The high-level architecture of Send Again is designed for scalability and reliability by offloading the heavy lifting of mail delivery to Amazon SES while maintaining strict control over contact data and campaign logic within a self-hosted or cloud-managed Next.js environment. By utilizing a job-based processing model, the system can handle large recipient lists while respecting SES rate limits and providing real-time performance analytics to the user.