Technical Product Requirements
Status: MVP Technical Specifications
Verified: Architecture validated against industry standards
Executive Summary
Build a scalable, secure email marketing platform that delivers enterprise-grade capabilities through an architecture designed for simplicity. This comprehensive technical specification defines RESTful APIs, database schemas, integration frameworks, and performance requirements that enable professional email marketing at an affordable price point.
Key Technical Decisions
| Component | Choice | Rationale |
|---|---|---|
| API Design | RESTful with JWT | Industry standard, easy integration |
| Database | PostgreSQL + JSONB | Flexible schema, proven scale |
| Delivery | Multi-provider | Redundancy & cost optimization |
| Security | OAuth 2.0 + MFA | Enterprise-grade protection |
| Performance | <200ms response | Competitive advantage |
Architecture Overview
Section 1: API Specification (800 words)
RESTful API Design Principles
NudgeCampaign's API follows REST architectural principles with resource-based URLs, standard HTTP methods, and JSON data formats. Our design philosophy emphasizes consistency, predictability, and developer experience, learning from the successes of platforms like Mailchimp's well-documented API while avoiding the complexity of ActiveCampaign's extensive endpoint proliferation.
Simplified API architecture designed for developer success
API Resource Hierarchy
Authentication and Authorization
API authentication uses OAuth 2.0 with JWT tokens for stateless authentication. Each request requires an Authorization header with a Bearer token.
Permission Scopes
| Scope | Description | Use Case |
|---|---|---|
campaigns:read |
View campaign data | Analytics tools |
campaigns:write |
Create/modify campaigns | Content management |
contacts:read |
Access contact info | CRM integration |
contacts:write |
Manage contacts | Import tools |
automations:execute |
Trigger workflows | Event systems |
analytics:read |
Access reports | BI dashboards |
account:admin |
Full access | Account management |
Rate Limiting Strategy
| Plan | Rate Limit | Burst Capacity | Use Case |
|---|---|---|---|
| Starter | 100 req/min | 200 req | Small businesses |
| Professional | 500 req/min | 1000 req | Growing companies |
| Enterprise | 2000 req/min | 4000 req | High-volume users |
Core Resource Endpoints
Campaigns Resource
GET /campaigns # List campaigns with pagination
POST /campaigns # Create new campaign
GET /campaigns/{id} # Get campaign details
PUT /campaigns/{id} # Update campaign
DELETE /campaigns/{id} # Delete campaign
POST /campaigns/{id}/send # Send campaign
POST /campaigns/{id}/test # Send test email
Contacts Resource
GET /contacts # List contacts with filtering
POST /contacts # Create contact
GET /contacts/{id} # Get contact details
PUT /contacts/{id} # Update contact
DELETE /contacts/{id} # Delete contact
POST /contacts/import # Bulk import
GET /contacts/{id}/history # Contact activity
Automations Resource
GET /automations # List automation workflows
POST /automations # Create workflow
GET /automations/{id} # Get workflow details
PUT /automations/{id} # Update workflow
POST /automations/{id}/activate # Activate workflow
POST /automations/{id}/pause # Pause workflow
GET /automations/{id}/metrics # Workflow performance
Request/Response Format
All API requests and responses use JSON format with consistent structure:
Standard Response Format
{
"data": {
// Resource data
},
"meta": {
"total": 150,
"page": 1,
"per_page": 50
},
"links": {
"self": "/api/v1/contacts?page=1",
"next": "/api/v1/contacts?page=2"
}
}
Error Response Format
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid email format",
"details": [
{
"field": "email",
"issue": "Must be valid email address"
}
]
}
}
Common HTTP Status Codes
| Code | Meaning | Use Case |
|---|---|---|
| 200 | OK | Successful GET/PUT |
| 201 | Created | Successful POST |
| 204 | No Content | Successful DELETE |
| 400 | Bad Request | Invalid input |
| 401 | Unauthorized | Missing/invalid auth |
| 403 | Forbidden | Insufficient permissions |
| 404 | Not Found | Resource doesn't exist |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Server Error | Internal error |
Webhook Events API
NudgeCampaign implements event-driven architecture through webhooks:
POST /webhooks # Register webhook endpoint
GET /webhooks # List registered webhooks
PUT /webhooks/{id} # Update webhook
DELETE /webhooks/{id} # Remove webhook
Supported Webhook Events
| Event Type | Trigger | Payload Includes |
|---|---|---|
email.sent |
Email delivered to server | Campaign ID, contact ID |
email.opened |
Tracking pixel loaded | Location, device type |
email.clicked |
Link clicked | URL, click position |
email.bounced |
Delivery failure | Bounce type, reason |
contact.subscribed |
New opt-in | Source, preferences |
contact.unsubscribed |
Opt-out action | Reason, campaign ID |
automation.triggered |
Workflow starts | Trigger type, contact ID |
API Versioning Strategy
The API uses URL path versioning (/api/v1/) with backward compatibility guarantees. Breaking changes trigger new version releases with migration guides and deprecation notices. Non-breaking additions (new fields, endpoints) are added to existing versions with clear documentation updates.
Section 2: Data Model Definition (800 words)
Core Entity Relationships
The database schema follows PostgreSQL best practices with proper normalization, foreign key constraints, and optimized indexes for query performance. The design balances flexibility for future features with simplicity for current MVP requirements.
Simplified yet powerful database architecture optimized for email marketing
Entity Relationship Diagram
Core Table Definitions
Accounts Table
CREATE TABLE accounts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
plan_type VARCHAR(50) DEFAULT 'starter',
monthly_email_limit INTEGER DEFAULT 10000,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
settings JSONB DEFAULT '{}'::jsonb
);
| Column | Type | Purpose |
|---|---|---|
id |
UUID | Unique identifier |
email |
VARCHAR | Account login email |
plan_type |
VARCHAR | Subscription tier |
settings |
JSONB | Flexible preferences |
Contacts Table
CREATE TABLE contacts (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
account_id UUID REFERENCES accounts(id) ON DELETE CASCADE,
email VARCHAR(255) NOT NULL,
first_name VARCHAR(100),
last_name VARCHAR(100),
status VARCHAR(20) DEFAULT 'active',
subscription_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
custom_fields JSONB DEFAULT '{}'::jsonb,
tags TEXT[],
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(account_id, email)
);
-- Performance indexes
CREATE INDEX idx_contacts_account_email ON contacts(account_id, email);
CREATE INDEX idx_contacts_tags ON contacts USING GIN(tags);
Key Design Decisions:
- JSONB for flexible custom fields
- Array type for efficient tag storage
- GIN index for fast tag queries
- Composite unique constraint for data integrity
Campaigns Table
CREATE TABLE campaigns (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
account_id UUID REFERENCES accounts(id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL,
subject VARCHAR(500),
from_name VARCHAR(100),
from_email VARCHAR(255),
reply_to VARCHAR(255),
content_html TEXT,
content_text TEXT,
template_id UUID REFERENCES templates(id),
status VARCHAR(20) DEFAULT 'draft',
scheduled_at TIMESTAMP,
sent_at TIMESTAMP,
stats JSONB DEFAULT '{}'::jsonb,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Segments Table
CREATE TABLE segments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
account_id UUID REFERENCES accounts(id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL,
type VARCHAR(20) DEFAULT 'dynamic',
conditions JSONB NOT NULL,
contact_count INTEGER DEFAULT 0,
last_calculated TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Automation Workflow Schema
Automations Table
CREATE TABLE automations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
account_id UUID REFERENCES accounts(id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL,
trigger_type VARCHAR(50) NOT NULL,
trigger_config JSONB,
status VARCHAR(20) DEFAULT 'draft',
activated_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE automation_steps (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
automation_id UUID REFERENCES automations(id) ON DELETE CASCADE,
step_type VARCHAR(50) NOT NULL,
step_config JSONB NOT NULL,
position INTEGER NOT NULL,
delay_minutes INTEGER DEFAULT 0
);
CREATE TABLE automation_instances (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
automation_id UUID REFERENCES automations(id),
contact_id UUID REFERENCES contacts(id),
current_step INTEGER DEFAULT 0,
status VARCHAR(20) DEFAULT 'active',
started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
completed_at TIMESTAMP
);
Analytics Data Model
Email Events Table
CREATE TABLE email_events (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
account_id UUID REFERENCES accounts(id),
campaign_id UUID REFERENCES campaigns(id),
contact_id UUID REFERENCES contacts(id),
event_type VARCHAR(20) NOT NULL,
event_data JSONB,
ip_address INET,
user_agent TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_email_events_campaign ON email_events(campaign_id, event_type);
CREATE INDEX idx_email_events_contact ON email_events(contact_id, created_at);
Template Storage
Templates use a versioned approach for tracking changes:
CREATE TABLE templates (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
account_id UUID REFERENCES accounts(id),
name VARCHAR(255) NOT NULL,
category VARCHAR(50),
thumbnail_url TEXT,
is_global BOOLEAN DEFAULT false
);
CREATE TABLE template_versions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
template_id UUID REFERENCES templates(id) ON DELETE CASCADE,
version INTEGER NOT NULL,
content_html TEXT NOT NULL,
content_json JSONB,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
created_by UUID REFERENCES accounts(id)
);
Section 3: Integration Architecture (700 words)
Third-Party Service Framework
NudgeCampaign's integration architecture follows a modular, provider-agnostic design that enables seamless connections with essential third-party services while maintaining system flexibility. Our approach prioritizes the most requested integrations from our target market research: Shopify, WordPress, Zapier, and social media platforms.
Integration Service Layer
interface IntegrationProvider {
connect(credentials: Credentials): Promise<Connection>;
disconnect(connectionId: string): Promise<void>;
syncContacts(connectionId: string): Promise<SyncResult>;
handleWebhook(payload: any): Promise<void>;
}
class ShopifyIntegration implements IntegrationProvider {
async connect(credentials) {
// OAuth flow with Shopify
// Store access token securely
// Register webhooks for customer events
}
async syncContacts(connectionId) {
// Fetch customers from Shopify
// Map to NudgeCampaign contact schema
// Handle pagination and rate limits
}
}
Email Delivery Infrastructure
Email delivery leverages multiple providers for redundancy and deliverability optimization:
Primary Provider: SendGrid
- Handles transactional emails and small campaigns
- Real-time event webhooks for tracking
- Template management API integration
Secondary Provider: Amazon SES
- Cost-effective for high-volume sends
- Direct integration with AWS infrastructure
- Automated IP warming procedures
Provider Selection Logic:
def select_email_provider(campaign):
if campaign.size < 1000:
return SendGridProvider()
elif campaign.priority == "transactional":
return SendGridProvider()
else:
return AmazonSESProvider()
Webhook Management System
The webhook infrastructure handles both incoming and outgoing webhooks with reliability and scale:
Incoming Webhooks (from integrations):
- Dedicated endpoint per integration type
- Signature verification for security
- Queue-based processing for reliability
- Automatic retry with exponential backoff
Outgoing Webhooks (to customer endpoints):
class WebhookDispatcher:
def dispatch(self, event, payload):
webhooks = get_active_webhooks(event.account_id, event.type)
for webhook in webhooks:
job = WebhookDeliveryJob(
url=webhook.url,
payload=payload,
headers=self.build_headers(webhook),
max_retries=5
)
queue.enqueue(job)
API Gateway Architecture
All third-party API calls route through a centralized gateway service that provides:
- Rate limiting per integration
- Response caching where appropriate
- Error handling and retry logic
- Monitoring and alerting
- API version management
Data Synchronization Patterns
Contact synchronization follows an event-driven pattern with conflict resolution:
- Initial Import: Bulk import with field mapping UI
- Incremental Sync: Webhook-triggered updates
- Conflict Resolution: Last-write-wins with audit trail
- Bi-directional Sync: Optional for premium integrations
Zapier Integration Specification
Our Zapier app exposes key triggers and actions:
Triggers:
- New Contact Added
- Email Opened
- Link Clicked
- Tag Applied
- Automation Completed
Actions:
- Create/Update Contact
- Add Tag to Contact
- Trigger Automation
- Send Campaign
- Add Contact to Segment
Security Considerations
All integration credentials are encrypted using AES-256 and stored in a dedicated secrets management service. OAuth tokens refresh automatically before expiration. API requests include request signing for webhooks and HMAC validation for incoming webhooks.
Section 4: Performance Requirements (700 words)
Load and Scalability Specifications
NudgeCampaign must handle the demands of growing businesses while maintaining responsive performance. Based on competitor analysis and target market requirements, our performance specifications ensure smooth operation for accounts sending up to 1 million emails monthly.
Core Performance Targets:
- API Response Time: 95th percentile < 200ms
- Dashboard Load Time: < 2 seconds for initial load
- Email Send Throughput: 10,000 emails/minute per account
- Contact Import Speed: 50,000 contacts/minute
- Automation Processing: < 100ms trigger evaluation
Horizontal Scaling Architecture
The system architecture supports horizontal scaling at every layer:
Application Layer:
- Stateless Node.js services behind load balancer
- Auto-scaling based on CPU and request metrics
- Session management via Redis
- Minimum 3 instances for high availability
Database Layer:
- PostgreSQL with read replicas
- Connection pooling (100 connections per instance)
- Query optimization with proper indexing
- Partitioning for large tables (email_events)
Caching Strategy:
const cacheConfig = {
contacts: {
ttl: 3600, // 1 hour
invalidateOn: ['update', 'delete']
},
segments: {
ttl: 300, // 5 minutes
invalidateOn: ['contact_change', 'segment_update']
},
analytics: {
ttl: 60, // 1 minute for real-time feel
aggregationInterval: 60
}
};
Email Delivery Performance
Email delivery requires special attention to maintain sender reputation while achieving speed:
Sending Queue Architecture:
- Multiple priority queues (transactional, marketing, bulk)
- Rate limiting per receiving domain
- Automatic throttling based on bounce rates
- Connection pooling to ESP APIs
Performance Benchmarks:
- Time to first email sent: < 5 seconds
- Bulk campaign completion: 100,000 emails in < 15 minutes
- Bounce processing latency: < 30 seconds
- Click tracking redirect: < 50ms
Real-time Analytics Requirements
Analytics must provide near real-time insights without impacting system performance:
Data Pipeline:
- Events stream to Kafka/Redis Streams
- Stream processing aggregates metrics
- Materialized views for common queries
- Time-series database for trending
Query Performance:
- Campaign overview: < 500ms
- Contact activity timeline: < 200ms
- Segment count calculation: < 1 second
- Custom report generation: < 5 seconds
Resource Utilization Targets
Efficient resource usage keeps costs manageable for our price point:
- CPU Usage: Average < 60%, Peak < 80%
- Memory Usage: < 4GB per application instance
- Database Connections: < 80% of pool capacity
- Network Bandwidth: < 1Gbps sustained
- Storage Growth: < 1GB per 100,000 contacts
Load Testing Scenarios
Regular load testing validates performance under stress:
Scenario 1: Campaign Send Surge
- 50 concurrent campaigns
- 1 million total recipients
- Expected: All sent within 30 minutes
Scenario 2: API Traffic Spike
- 10,000 requests/second
- Mixed read/write operations
- Expected: 99% success rate, <500ms p99
Scenario 3: Analytics Dashboard Load
- 1,000 concurrent dashboard users
- Viewing real-time campaign metrics
- Expected: <3 second load times
Performance Monitoring
Comprehensive monitoring ensures performance targets are met:
monitors:
- name: API Response Time
metric: http_request_duration_ms
threshold: 200
percentile: 95
- name: Email Send Rate
metric: emails_sent_per_minute
threshold: 10000
- name: Database Query Time
metric: pg_query_duration_ms
threshold: 100
percentile: 95
Section 5: Security Specifications (600 words)
Authentication and Encryption
Security forms the foundation of customer trust, especially when handling sensitive marketing data. NudgeCampaign implements defense-in-depth security strategies that exceed industry standards while remaining transparent to end users.
Authentication Framework:
- Multi-factor authentication (MFA) for all accounts
- OAuth 2.0 for API access with JWT tokens
- Session timeout after 30 minutes of inactivity
- Password requirements: 12+ characters, complexity rules
- Account lockout after 5 failed attempts
Encryption Standards:
- Data at rest: AES-256 encryption
- Data in transit: TLS 1.3 minimum
- Database field-level encryption for PII
- Encryption key rotation every 90 days
- Hardware security modules (HSM) for key management
Compliance Framework
Meeting regulatory requirements protects both NudgeCampaign and our customers:
GDPR Compliance:
- Explicit consent management
- Right to erasure (automated deletion workflows)
- Data portability (export in standard formats)
- Privacy by design architecture
- Data Processing Agreements (DPA) available
CAN-SPAM and CASL:
- Mandatory unsubscribe links
- Physical address requirement
- Consent record keeping
- Suppression list management
- Automated compliance checking
Access Control and Auditing
Granular access controls protect customer data:
const rolePermissions = {
owner: ['*'],
admin: ['campaigns', 'contacts', 'automations', 'analytics', 'team'],
marketer: ['campaigns', 'contacts', 'automations', 'analytics'],
viewer: ['campaigns:read', 'contacts:read', 'analytics:read']
};
const auditLog = {
action: 'contact.exported',
user: userId,
ip: request.ip,
timestamp: new Date(),
resources: ['contact:12345'],
metadata: { format: 'csv', count: 5000 }
};
Infrastructure Security
Cloud infrastructure follows security best practices:
- VPC with private subnets for databases
- Web Application Firewall (WAF) rules
- DDoS protection via CloudFlare
- Regular security patching schedule
- Intrusion detection systems
Data Protection Measures
Customer data protection includes:
- Daily automated backups with 30-day retention
- Point-in-time recovery capability
- Geo-redundant backup storage
- Backup encryption and testing
- Disaster recovery plan with 4-hour RTO
Security Monitoring and Response
Proactive security monitoring detects threats:
- Real-time anomaly detection
- Failed login attempt monitoring
- API rate limit abuse detection
- Automated incident response
- 24/7 security operations center (SOC)
Section 6: Technical Constraints (400 words)
Platform Limitations
Understanding technical constraints helps set realistic expectations and guide architectural decisions:
Browser Support:
- Chrome 90+, Firefox 88+, Safari 14+, Edge 90+
- No Internet Explorer support
- Mobile browsers: iOS Safari 14+, Chrome Android
- Progressive enhancement for older browsers
Email Client Compatibility:
- Full support: Gmail, Outlook 2019+, Apple Mail
- Limited support: Outlook 2013-2016 (no background images)
- Basic support: Legacy webmail clients
- AMP email support for Gmail only
API Rate Limits
Rate limiting prevents abuse while ensuring fair access:
- Starter Plan: 100 requests/minute
- Professional: 500 requests/minute
- Enterprise: 2000 requests/minute
- Burst allowance: 2x limit for 10 seconds
- Per-endpoint limits for resource-intensive operations
Data Retention Policies
Storage constraints require data lifecycle management:
- Email events: 2 years retention
- Automation logs: 1 year retention
- Deleted contacts: 30-day recovery period
- Campaign content: Indefinite storage
- Analytics aggregations: 3 years
Technical Debt Boundaries
MVP constraints to revisit post-launch:
- No real-time collaboration (single user editing)
- Limited template customization (drag-drop only)
- Basic segmentation (no computed fields yet)
- English-only interface initially
- Single timezone support per account
Integration Limitations
Third-party integration constraints:
- Webhook delivery: Best effort, no guaranteed delivery
- API versioning: Support latest 2 versions only
- OAuth tokens: 90-day maximum lifetime
- Sync frequency: Minimum 5-minute intervals
- Custom field mapping: 50 fields maximum
These constraints represent conscious trade-offs to deliver a focused, high-quality MVP within budget while maintaining flexibility for future enhancements based on customer feedback and market demands.
Conclusion
This technical architecture positions NudgeCampaign for success by balancing enterprise-grade capabilities with implementation simplicity. Every technical decision supports our core mission: making professional email marketing accessible and affordable for growing businesses.
Next Steps
- Review Feature Implementation Guide for detailed component specifications
- Explore User Story Specifications for acceptance criteria
- Study Testing Specifications for quality assurance requirements
This document defines the technical foundation for NudgeCampaign's MVP, ensuring scalability, security, and performance from day one.