Last updated: Aug 4, 2025, 11:26 AM UTC

API Integration Implementation: Building the Email Marketing Backend

Phase: 14 - MVP Implementation with Claude Code
Status: Executable API Development Guide
Research Foundation: Next.js API routes, Supabase integration, and email service patterns


Executive Summary

Connect frontend to backend with production-ready APIs. This guide provides executable Claude Code prompts to build comprehensive API endpoints, database integrations, and third-party service connections. Transform the UI components into a fully functional email marketing platform.

API-First Implementation Strategy

This guide contains 6 major Claude Code execution prompts that will create:

  • RESTful API Routes for campaigns, contacts, templates, and automation management
  • AI Workflow Generation APIs for natural language to n8n workflow conversion
  • n8n Integration APIs for workflow deployment, monitoring, and execution
  • Conversational AI APIs for Maya assistant and voice processing
  • Supabase Database Integration with real-time subscriptions and complex queries
  • Email Service Integration with SendGrid/Postmark for reliable email delivery
  • Real-Time Features with websockets, notifications, and collaborative editing

Key Innovation: Production-Ready API Architecture

Traditional Backend Claude Code Implementation Advantage
Weeks of API development 4 prompts = complete backend 15x faster API development
Manual database queries Type-safe Supabase integration 95% fewer SQL errors
Basic email sending Professional delivery infrastructure Enterprise-grade reliability
No real-time features Built-in real-time subscriptions Modern user experience

RESTful API Routes Implementation

Campaign Management API

Comprehensive API endpoints for managing email campaigns with full CRUD operations, status management, and analytics integration.

Claude Code Prompt #1: Campaign API Endpoints

Execution Priority: FIRST - Core campaign management functionality

Prompt for Claude Code:

Create comprehensive Next.js API routes for email marketing campaign management with the following specifications:

CAMPAIGN API ENDPOINTS:
Create src/app/api/campaigns/ with:

1. route.ts (GET /api/campaigns, POST /api/campaigns):
```typescript
import { NextRequest, NextResponse } from 'next/server';
import { createServerSupabaseClient } from '@/lib/supabase/server';
import { campaignSchema, CampaignCreateData } from '@/lib/validation/campaign';

export async function GET(request: NextRequest) {
  try {
    const supabase = createServerSupabaseClient();
    const { data: { user }, error: authError } = await supabase.auth.getUser();
    
    if (authError || !user) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const url = new URL(request.url);
    const page = parseInt(url.searchParams.get('page') || '1');
    const limit = parseInt(url.searchParams.get('limit') || '10');
    const status = url.searchParams.get('status');
    const search = url.searchParams.get('search');
    
    let query = supabase
      .from('campaigns')
      .select(`
        id, name, subject, status, recipient_count, sent_count, 
        open_count, click_count, created_at, updated_at, scheduled_at,
        open_rate, click_rate
      `)
      .eq('user_id', user.id)
      .order('created_at', { ascending: false });

    if (status) {
      query = query.eq('status', status);
    }

    if (search) {
      query = query.or(`name.ilike.%${search}%,subject.ilike.%${search}%`);
    }

    const offset = (page - 1) * limit;
    query = query.range(offset, offset + limit - 1);

    const { data: campaigns, error, count } = await query;

    if (error) {
      throw error;
    }

    return NextResponse.json({
      campaigns,
      pagination: {
        page,
        limit,
        total: count || 0,
        pages: Math.ceil((count || 0) / limit)
      }
    });
  } catch (error) {
    console.error('Campaign fetch error:', error);
    return NextResponse.json(
      { error: 'Failed to fetch campaigns' },
      { status: 500 }
    );
  }
}

export async function POST(request: NextRequest) {
  try {
    const supabase = createServerSupabaseClient();
    const { data: { user }, error: authError } = await supabase.auth.getUser();
    
    if (authError || !user) {
      return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    }

    const body = await request.json();
    const validatedData = campaignSchema.parse(body);

    const { data: campaign, error } = await supabase
      .from('campaigns')
      .insert({
        user_id: user.id,
        name: validatedData.name,
        subject: validatedData.subject,
        content: validatedData.content,
        status: 'draft'
      })
      .select()
      .single();

    if (error) {
      throw error;
    }

    return NextResponse.json({ campaign }, { status: 201 });
  } catch (error) {
    console.error('Campaign creation error:', error);
    return NextResponse.json(
      { error: 'Failed to create campaign' },
      { status: 500 }
    );
  }
}
  1. [id]/route.ts (GET, PUT, DELETE /api/campaigns/[id]):
  • Individual campaign operations
  • Status updates (draft, scheduled, sending, sent, paused)
  • Analytics calculation and caching
  • Campaign duplication functionality
  1. [id]/send/route.ts (POST /api/campaigns/[id]/send):
  • Campaign sending logic with queue integration
  • Recipient validation and segmentation
  • Send scheduling and rate limiting
  • Delivery tracking setup
  1. [id]/analytics/route.ts (GET /api/campaigns/[id]/analytics):
  • Detailed campaign performance metrics
  • Open/click tracking data
  • Geographic and device analytics
  • Time-based performance trends

CONTACT API ENDPOINTS:
Create src/app/api/contacts/ with:

  1. route.ts (GET /api/contacts, POST /api/contacts):
  • Contact listing with advanced filtering
  • Bulk contact creation
  • Duplicate detection and handling
  • Tag-based querying
  1. [id]/route.ts (GET, PUT, DELETE /api/contacts/[id]):
  • Individual contact management
  • Custom field updates
  • Engagement history retrieval
  • Contact merge functionality
  1. import/route.ts (POST /api/contacts/import):
  • CSV file processing
  • Field mapping and validation
  • Batch import with progress tracking
  • Error reporting and resolution
  1. segments/route.ts (GET, POST /api/contacts/segments):
  • Dynamic segmentation logic
  • Segment creation and management
  • Real-time segment statistics
  • Export segment functionality

TEMPLATE API ENDPOINTS:
Create src/app/api/templates/ with:

  1. route.ts (GET /api/templates, POST /api/templates):
  • Template library management
  • Category-based organization
  • Template sharing and permissions
  • Usage analytics tracking
  1. [id]/route.ts (GET, PUT, DELETE /api/templates/[id]):
  • Individual template operations
  • Version history management
  • Template preview generation
  • Collaborative editing support

AUTOMATION API ENDPOINTS:
Create src/app/api/automations/ with:

  1. route.ts (GET /api/automations, POST /api/automations):
  • Automation workflow management
  • Trigger configuration validation
  • Workflow status management
  • Performance analytics
  1. [id]/route.ts (GET, PUT, DELETE /api/automations/[id]):
  • Individual workflow operations
  • Node configuration updates
  • Execution history retrieval
  • Workflow testing functionality
  1. [id]/execute/route.ts (POST /api/automations/[id]/execute):
  • Manual workflow execution
  • Test mode execution
  • Execution logging and monitoring
  • Error handling and recovery

DATA VALIDATION:
Create src/lib/validation/ with Zod schemas:

  • campaignSchema for campaign creation/updates
  • contactSchema for contact operations
  • templateSchema for template management
  • automationSchema for workflow validation

ERROR HANDLING:
Implement comprehensive error handling:

  • Request validation with detailed error messages
  • Database error handling with user-friendly responses
  • Rate limiting and quota management
  • Logging and monitoring integration

SECURITY FEATURES:

  • Row Level Security (RLS) enforcement
  • Input sanitization and validation
  • Rate limiting per user/endpoint
  • API key authentication for webhooks
  • CORS configuration for frontend access

Include comprehensive request/response typing, error handling, and performance optimization.


**Expected Output**: Complete RESTful API with all email marketing operations

---

## πŸ€– AI Workflow Generation API

### 🎯 Revolutionary Natural Language to Automation Conversion

**Critical Innovation**: Transform natural language conversations into complete n8n workflows using AI, eliminating the need for traditional drag-and-drop builders.

### πŸ€– Claude Code Prompt #2: AI Workflow Generation API

**Execution Priority**: SECOND - Core AI functionality

**Prompt for Claude Code**:

Create comprehensive AI workflow generation API endpoints that convert natural language to n8n workflows:

API ENDPOINTS:
Create src/app/api/ai/ with:

  1. workflow-generate/route.ts (POST /api/ai/workflow-generate):
import { NextRequest, NextResponse } from 'next/server';
import { OpenAI } from 'openai';
import { createServerSupabaseClient } from '@/lib/supabase/server';
import { generateN8nWorkflow } from '@/lib/ai/workflow-generator';
import { deployWorkflowToN8n } from '@/lib/n8n/client';

export async function POST(request: NextRequest) {
  try {
    const { userMessage, businessContext, existingWorkflows } = await request.json();
    
    // Authenticate user
    const supabase = createServerSupabaseClient();
    const { data: { user }, error: authError } = await supabase.auth.getUser();
    if (!user) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
    
    // Generate workflow using AI
    const workflowSpec = await generateN8nWorkflow({
      userIntent: userMessage,
      businessContext,
      userHistory: existingWorkflows,
      userId: user.id
    });
    
    // Convert to n8n JSON format
    const n8nWorkflow = await convertToN8nFormat(workflowSpec);
    
    // Store in database
    const { data: automation } = await supabase
      .from('automations')
      .insert({
        user_id: user.id,
        name: workflowSpec.name,
        description: workflowSpec.description,
        n8n_workflow_json: n8nWorkflow,
        ai_generated: true,
        ai_conversation_context: { userMessage, businessContext },
        status: 'draft'
      })
      .select()
      .single();
    
    return NextResponse.json({
      automation,
      workflowPreview: workflowSpec,
      estimatedSavings: calculateTimeSavings(workflowSpec)
    });
  } catch (error) {
    return NextResponse.json({ error: error.message }, { status: 500 });
  }
}
  1. conversation/route.ts (POST /api/ai/conversation):
  • Maya AI assistant conversation handling
  • Context-aware responses about email marketing
  • Intent recognition and workflow suggestions
  • Voice input processing and natural responses
  1. voice-process/route.ts (POST /api/ai/voice-process):
  • Google Cloud Speech-to-Text integration
  • Text-to-Speech for Maya responses
  • Real-time voice streaming support
  • Voice command recognition for automation
  1. workflow-optimize/route.ts (POST /api/ai/workflow-optimize):
  • AI-powered workflow performance analysis
  • Optimization suggestions based on execution data
  • A/B testing recommendations
  • Continuous improvement suggestions

Include complete TypeScript types, error handling, and performance monitoring.


**Expected Output**: Complete AI workflow generation infrastructure

---

## πŸ”§ n8n Integration API

### 🎯 Seamless n8n Cloud Run Integration

**Integration Foundation**: Connect Next.js application to self-hosted n8n instance for workflow deployment and execution monitoring.

### πŸ€– Claude Code Prompt #3: n8n API Integration

**Execution Priority**: THIRD - After AI workflow generation

**Prompt for Claude Code**:

Create comprehensive n8n API integration for workflow management and execution:

N8N CLIENT LIBRARY:
Create src/lib/n8n/client.ts:

import axios from 'axios';
import { N8nWorkflow, WorkflowExecution, N8nNode } from '@/types/n8n';

export class N8nClient {
  private baseUrl: string;
  private apiKey: string;
  
  constructor() {
    this.baseUrl = process.env.N8N_API_URL!;
    this.apiKey = process.env.N8N_API_KEY!;
  }
  
  // Workflow management
  async createWorkflow(workflow: N8nWorkflow): Promise<string> {
    const response = await axios.post(`${this.baseUrl}/api/v1/workflows`, workflow, {
      headers: { 'X-N8N-API-KEY': this.apiKey }
    });
    return response.data.id;
  }
  
  async updateWorkflow(id: string, workflow: N8nWorkflow): Promise<void> {
    await axios.put(`${this.baseUrl}/api/v1/workflows/${id}`, workflow, {
      headers: { 'X-N8N-API-KEY': this.apiKey }
    });
  }
  
  async deleteWorkflow(id: string): Promise<void> {
    await axios.delete(`${this.baseUrl}/api/v1/workflows/${id}`, {
      headers: { 'X-N8N-API-KEY': this.apiKey }
    });
  }
  
  // Workflow execution
  async executeWorkflow(id: string, data?: any): Promise<WorkflowExecution> {
    const response = await axios.post(`${this.baseUrl}/api/v1/workflows/${id}/execute`, 
      { data }, 
      { headers: { 'X-N8N-API-KEY': this.apiKey } }
    );
    return response.data;
  }
  
  async getExecutionStatus(executionId: string): Promise<WorkflowExecution> {
    const response = await axios.get(`${this.baseUrl}/api/v1/executions/${executionId}`, {
      headers: { 'X-N8N-API-KEY': this.apiKey }
    });
    return response.data;
  }
  
  // Real-time monitoring
  async getActiveExecutions(): Promise<WorkflowExecution[]> {
    const response = await axios.get(`${this.baseUrl}/api/v1/executions/active`, {
      headers: { 'X-N8N-API-KEY': this.apiKey }
    });
    return response.data;
  }
}

API ENDPOINTS:
Create src/app/api/n8n/ with:

  1. workflows/route.ts (GET, POST /api/n8n/workflows):
  • Deploy AI-generated workflows to n8n
  • Retrieve workflow status and configuration
  • Update workflow settings and activation
  1. execute/route.ts (POST /api/n8n/execute):
  • Trigger workflow executions
  • Pass dynamic data to workflows
  • Handle webhook-based executions
  1. monitor/route.ts (GET /api/n8n/monitor):
  • Real-time execution monitoring
  • Performance metrics collection
  • Error tracking and alerting
  1. webhooks/route.ts (POST /api/n8n/webhooks):
  • Handle n8n webhook callbacks
  • Process execution results
  • Update database with execution status

Include comprehensive error handling, retry logic, and monitoring.


**Expected Output**: Complete n8n integration with monitoring and execution

---

## πŸ—„οΈ Supabase Database Integration

### 🎯 Real-Time Database Operations

Advanced Supabase integration with real-time subscriptions, complex queries, and optimized data relationships for the email marketing platform.

### πŸ€– Claude Code Prompt #4: Database Integration Implementation

**Execution Priority**: SECOND - After API routes are established

**Prompt for Claude Code**:

Implement comprehensive Supabase database integration with the following specifications:

DATABASE CLIENT SETUP:
Create src/lib/supabase/ with:

  1. client.ts (Browser client):
import { createBrowserSupabaseClient } from '@supabase/auth-helpers-nextjs';
import { Database } from '@/types/database';

export const createClient = () => createBrowserSupabaseClient<Database>();
  1. server.ts (Server client):
import { createServerSupabaseClient } from '@supabase/auth-helpers-nextjs';
import { cookies } from 'next/headers';
import { Database } from '@/types/database';

export const createServerSupabaseClient = () => 
  createServerSupabaseClient<Database>({ cookies });
  1. middleware.ts (Middleware client):
import { createMiddlewareSupabaseClient } from '@supabase/auth-helpers-nextjs';
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export async function middleware(req: NextRequest) {
  const res = NextResponse.next();
  const supabase = createMiddlewareSupabaseClient({ req, res });
  await supabase.auth.getSession();
  return res;
}

DATABASE OPERATIONS:
Create src/lib/database/ with:

  1. campaigns.ts:
import { createClient } from '@/lib/supabase/client';
import { Campaign, CampaignAnalytics, CampaignFilters } from '@/types/campaign';

export class CampaignDatabase {
  private supabase = createClient();

  async getCampaigns(filters: CampaignFilters = {}) {
    let query = this.supabase
      .from('campaigns')
      .select(`
        id, name, subject, status, recipient_count, sent_count,
        open_count, click_count, created_at, updated_at, scheduled_at,
        open_rate, click_rate
      `);

    if (filters.status) {
      query = query.eq('status', filters.status);
    }

    if (filters.search) {
      query = query.or(`name.ilike.%${filters.search}%,subject.ilike.%${filters.search}%`);
    }

    if (filters.dateFrom) {
      query = query.gte('created_at', filters.dateFrom);
    }

    if (filters.dateTo) {
      query = query.lte('created_at', filters.dateTo);
    }

    const { data, error } = await query
      .order('created_at', { ascending: false })
      .range(filters.offset || 0, (filters.offset || 0) + (filters.limit || 10) - 1);

    if (error) throw error;
    return data as Campaign[];
  }

  async getCampaignAnalytics(campaignId: string): Promise<CampaignAnalytics> {
    const { data, error } = await this.supabase
      .rpc('get_campaign_analytics', { campaign_id: campaignId });

    if (error) throw error;
    return data;
  }

  async updateCampaignStatus(campaignId: string, status: Campaign['status']) {
    const { data, error } = await this.supabase
      .from('campaigns')
      .update({ 
        status,
        updated_at: new Date().toISOString()
      })
      .eq('id', campaignId)
      .select()
      .single();

    if (error) throw error;
    return data;
  }

  subscribeToCampaignUpdates(callback: (payload: any) => void) {
    return this.supabase
      .channel('campaign-updates')
      .on('postgres_changes',
        {
          event: '*',
          schema: 'public',
          table: 'campaigns'
        },
        callback
      )
      .subscribe();
  }
}
  1. contacts.ts:
import { createClient } from '@/lib/supabase/client';
import { Contact, ContactFilters, ImportJob } from '@/types/contact';

export class ContactDatabase {
  private supabase = createClient();

  async getContacts(filters: ContactFilters = {}) {
    let query = this.supabase
      .from('contacts')
      .select('*');

    if (filters.tags && filters.tags.length > 0) {
      query = query.overlaps('tags', filters.tags);
    }

    if (filters.status) {
      query = query.eq('status', filters.status);
    }

    if (filters.search) {
      query = query.or(`
        email.ilike.%${filters.search}%,
        first_name.ilike.%${filters.search}%,
        last_name.ilike.%${filters.search}%
      `);
    }

    const { data, error } = await query
      .order('created_at', { ascending: false })
      .range(filters.offset || 0, (filters.offset || 0) + (filters.limit || 50) - 1);

    if (error) throw error;
    return data as Contact[];
  }

  async bulkCreateContacts(contacts: Partial<Contact>[]) {
    const { data, error } = await this.supabase
      .from('contacts')
      .insert(contacts)
      .select();

    if (error) throw error;
    return data;
  }

  async createSegment(name: string, rules: any[]) {
    const { data, error } = await this.supabase
      .rpc('create_dynamic_segment', {
        segment_name: name,
        segment_rules: rules
      });

    if (error) throw error;
    return data;
  }

  async getSegmentContacts(segmentId: string) {
    const { data, error } = await this.supabase
      .rpc('get_segment_contacts', { segment_id: segmentId });

    if (error) throw error;
    return data;
  }
}
  1. real-time.ts:
import { createClient } from '@/lib/supabase/client';
import { RealtimeChannel } from '@supabase/supabase-js';

export class RealTimeManager {
  private supabase = createClient();
  private channels: Map<string, RealtimeChannel> = new Map();

  subscribeToTable(
    table: string,
    event: 'INSERT' | 'UPDATE' | 'DELETE' | '*',
    callback: (payload: any) => void,
    filter?: string
  ) {
    const channelName = `${table}-${event}-${Date.now()}`;
    
    let channel = this.supabase.channel(channelName);

    const config: any = {
      event,
      schema: 'public',
      table
    };

    if (filter) {
      config.filter = filter;
    }

    channel = channel.on('postgres_changes', config, callback);

    channel.subscribe((status) => {
      console.log(`Subscription to ${table} ${event}: ${status}`);
    });

    this.channels.set(channelName, channel);
    return channelName;
  }

  unsubscribe(channelName: string) {
    const channel = this.channels.get(channelName);
    if (channel) {
      this.supabase.removeChannel(channel);
      this.channels.delete(channelName);
    }
  }

  unsubscribeAll() {
    this.channels.forEach((channel) => {
      this.supabase.removeChannel(channel);
    });
    this.channels.clear();
  }
}

DATABASE FUNCTIONS:
Create PostgreSQL functions for complex operations:

  1. Campaign Analytics Function:
CREATE OR REPLACE FUNCTION get_campaign_analytics(campaign_id UUID)
RETURNS JSON AS $
DECLARE
    result JSON;
BEGIN
    SELECT json_build_object(
        'total_sent', COALESCE(c.sent_count, 0),
        'total_opens', COALESCE(c.open_count, 0),
        'total_clicks', COALESCE(c.click_count, 0),
        'open_rate', CASE 
            WHEN c.sent_count > 0 THEN (c.open_count::float / c.sent_count) * 100 
            ELSE 0 
        END,
        'click_rate', CASE 
            WHEN c.sent_count > 0 THEN (c.click_count::float / c.sent_count) * 100 
            ELSE 0 
        END,
        'bounce_rate', (
            SELECT COUNT(*)::float / GREATEST(c.sent_count, 1) * 100
            FROM email_events e
            WHERE e.campaign_id = c.id AND e.event_type = 'bounced'
        ),
        'unsubscribe_rate', (
            SELECT COUNT(*)::float / GREATEST(c.sent_count, 1) * 100
            FROM email_events e
            WHERE e.campaign_id = c.id AND e.event_type = 'unsubscribed'
        ),
        'engagement_timeline', (
            SELECT json_agg(
                json_build_object(
                    'date', DATE(created_at),
                    'opens', SUM(CASE WHEN event_type = 'opened' THEN 1 ELSE 0 END),
                    'clicks', SUM(CASE WHEN event_type = 'clicked' THEN 1 ELSE 0 END)
                )
            )
            FROM email_events
            WHERE campaign_id = c.id
            GROUP BY DATE(created_at)
            ORDER BY DATE(created_at)
        )
    ) INTO result
    FROM campaigns c
    WHERE c.id = campaign_id;
    
    RETURN result;
END;
$ LANGUAGE plpgsql;
  1. Dynamic Segmentation Function:
CREATE OR REPLACE FUNCTION create_dynamic_segment(
    segment_name TEXT,
    segment_rules JSON
)
RETURNS UUID AS $
DECLARE
    segment_id UUID;
    contact_count INTEGER;
BEGIN
    -- Insert segment
    INSERT INTO contact_segments (name, rules)
    VALUES (segment_name, segment_rules)
    RETURNING id INTO segment_id;
    
    -- Calculate contact count
    SELECT COUNT(*) INTO contact_count
    FROM contacts
    WHERE evaluate_segment_rules(id, segment_rules);
    
    -- Update segment with contact count
    UPDATE contact_segments
    SET contact_count = contact_count
    WHERE id = segment_id;
    
    RETURN segment_id;
END;
$ LANGUAGE plpgsql;

PERFORMANCE OPTIMIZATION:

  • Database indexes for frequently queried columns
  • Query optimization with EXPLAIN ANALYZE
  • Connection pooling configuration
  • Prepared statement usage
  • Result caching for expensive operations

REAL-TIME SUBSCRIPTIONS:

  • Campaign status updates
  • Contact list changes
  • Email event tracking
  • Automation execution monitoring
  • Collaborative editing synchronization

Include comprehensive error handling, connection management, and performance monitoring.


**Expected Output**: Complete database integration with real-time capabilities and optimized queries

---

## πŸ“§ Email Service Integration

### 🎯 Professional Email Delivery Infrastructure

Integration with SendGrid and Postmark for reliable email delivery, template rendering, tracking, and delivery optimization.

### πŸ€– Claude Code Prompt #5: Email Service Implementation

**Execution Priority**: THIRD - After database integration is complete

**Prompt for Claude Code**:

Implement comprehensive email service integration with the following specifications:

EMAIL SERVICE SETUP:
Create src/lib/email/ with:

  1. sendgrid.ts:
import sgMail from '@sendgrid/mail';
import { EmailTemplate, EmailRecipient, EmailResult } from '@/types/email';

sgMail.setApiKey(process.env.SENDGRID_API_KEY!);

export class SendGridService {
  async sendEmail(
    template: EmailTemplate,
    recipient: EmailRecipient,
    trackingData?: Record<string, any>
  ): Promise<EmailResult> {
    try {
      const personalizedContent = this.personalizeContent(template.content, recipient);
      
      const msg = {
        to: recipient.email,
        from: {
          email: process.env.FROM_EMAIL!,
          name: process.env.FROM_NAME || 'NudgeCampaign'
        },
        subject: this.personalizeContent(template.subject, recipient),
        html: this.addTrackingPixels(personalizedContent, {
          campaignId: template.campaignId,
          contactId: recipient.id,
          ...trackingData
        }),
        customArgs: {
          campaign_id: template.campaignId,
          contact_id: recipient.id,
          user_id: recipient.userId
        },
        trackingSettings: {
          clickTracking: { enable: true },
          openTracking: { enable: true },
          subscriptionTracking: { enable: false }
        }
      };

      const [response] = await sgMail.send(msg);
      
      return {
        success: true,
        messageId: response.headers['x-message-id'] as string,
        recipient: recipient.email,
        timestamp: new Date().toISOString()
      };
    } catch (error) {
      console.error('SendGrid error:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Unknown error',
        recipient: recipient.email,
        timestamp: new Date().toISOString()
      };
    }
  }

  async sendBulkEmails(
    template: EmailTemplate,
    recipients: EmailRecipient[]
  ): Promise<EmailResult[]> {
    const results: EmailResult[] = [];
    const batchSize = 100; // SendGrid recommendation
    
    for (let i = 0; i < recipients.length; i += batchSize) {
      const batch = recipients.slice(i, i + batchSize);
      const batchPromises = batch.map(recipient => 
        this.sendEmail(template, recipient)
      );
      
      const batchResults = await Promise.allSettled(batchPromises);
      
      batchResults.forEach((result, index) => {
        if (result.status === 'fulfilled') {
          results.push(result.value);
        } else {
          results.push({
            success: false,
            error: result.reason?.message || 'Unknown error',
            recipient: batch[index].email,
            timestamp: new Date().toISOString()
          });
        }
      });
      
      // Rate limiting: wait 1 second between batches
      if (i + batchSize < recipients.length) {
        await new Promise(resolve => setTimeout(resolve, 1000));
      }
    }
    
    return results;
  }

  private personalizeContent(content: string, recipient: EmailRecipient): string {
    let personalized = content;
    
    // Replace common personalization tokens
    personalized = personalized.replace(/{{first_name}}/g, recipient.firstName || '');
    personalized = personalized.replace(/{{last_name}}/g, recipient.lastName || '');
    personalized = personalized.replace(/{{email}}/g, recipient.email);
    
    // Replace custom field tokens
    if (recipient.customFields) {
      Object.entries(recipient.customFields).forEach(([key, value]) => {
        const regex = new RegExp(`{{${key}}}`, 'g');
        personalized = personalized.replace(regex, String(value));
      });
    }
    
    return personalized;
  }

  private addTrackingPixels(html: string, trackingData: Record<string, any>): string {
    const trackingPixel = `<img src="${process.env.NEXT_PUBLIC_BASE_URL}/api/email/track/open?${
      new URLSearchParams(trackingData).toString()
    }" width="1" height="1" style="display:none;" alt="" />`;
    
    // Add tracking pixel before closing body tag
    return html.replace('</body>', `${trackingPixel}</body>`);
  }
}
  1. postmark.ts:
import { ServerClient } from 'postmark';
import { EmailTemplate, EmailRecipient, EmailResult } from '@/types/email';

export class PostmarkService {
  private client: ServerClient;

  constructor() {
    this.client = new ServerClient(process.env.POSTMARK_API_KEY!);
  }

  async sendEmail(
    template: EmailTemplate,
    recipient: EmailRecipient,
    trackingData?: Record<string, any>
  ): Promise<EmailResult> {
    try {
      const personalizedContent = this.personalizeContent(template.content, recipient);
      
      const result = await this.client.sendEmail({
        From: `${process.env.FROM_NAME} <${process.env.FROM_EMAIL}>`,
        To: recipient.email,
        Subject: this.personalizeContent(template.subject, recipient),
        HtmlBody: this.addTrackingPixels(personalizedContent, {
          campaignId: template.campaignId,
          contactId: recipient.id,
          ...trackingData
        }),
        MessageStream: 'outbound',
        Metadata: {
          campaign_id: template.campaignId,
          contact_id: recipient.id,
          user_id: recipient.userId
        },
        TrackOpens: true,
        TrackLinks: 'HtmlOnly'
      });

      return {
        success: true,
        messageId: result.MessageID,
        recipient: recipient.email,
        timestamp: new Date().toISOString()
      };
    } catch (error) {
      console.error('Postmark error:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Unknown error',
        recipient: recipient.email,
        timestamp: new Date().toISOString()
      };
    }
  }

  async sendBulkEmails(
    template: EmailTemplate,
    recipients: EmailRecipient[]
  ): Promise<EmailResult[]> {
    const results: EmailResult[] = [];
    const batchSize = 500; // Postmark batch limit
    
    for (let i = 0; i < recipients.length; i += batchSize) {
      const batch = recipients.slice(i, i + batchSize);
      
      const emails = batch.map(recipient => ({
        From: `${process.env.FROM_NAME} <${process.env.FROM_EMAIL}>`,
        To: recipient.email,
        Subject: this.personalizeContent(template.subject, recipient),
        HtmlBody: this.addTrackingPixels(
          this.personalizeContent(template.content, recipient),
          {
            campaignId: template.campaignId,
            contactId: recipient.id
          }
        ),
        MessageStream: 'outbound',
        Metadata: {
          campaign_id: template.campaignId,
          contact_id: recipient.id,
          user_id: recipient.userId
        },
        TrackOpens: true,
        TrackLinks: 'HtmlOnly'
      }));

      try {
        const batchResults = await this.client.sendEmailBatch(emails);
        
        batchResults.forEach((result, index) => {
          results.push({
            success: result.ErrorCode === 0,
            messageId: result.MessageID,
            error: result.ErrorCode !== 0 ? result.Message : undefined,
            recipient: batch[index].email,
            timestamp: new Date().toISOString()
          });
        });
      } catch (error) {
        // Handle batch failure
        batch.forEach(recipient => {
          results.push({
            success: false,
            error: error instanceof Error ? error.message : 'Batch send failed',
            recipient: recipient.email,
            timestamp: new Date().toISOString()
          });
        });
      }
    }
    
    return results;
  }

  private personalizeContent(content: string, recipient: EmailRecipient): string {
    // Same personalization logic as SendGrid
    let personalized = content;
    
    personalized = personalized.replace(/{{first_name}}/g, recipient.firstName || '');
    personalized = personalized.replace(/{{last_name}}/g, recipient.lastName || '');
    personalized = personalized.replace(/{{email}}/g, recipient.email);
    
    if (recipient.customFields) {
      Object.entries(recipient.customFields).forEach(([key, value]) => {
        const regex = new RegExp(`{{${key}}}`, 'g');
        personalized = personalized.replace(regex, String(value));
      });
    }
    
    return personalized;
  }

  private addTrackingPixels(html: string, trackingData: Record<string, any>): string {
    const trackingPixel = `<img src="${process.env.NEXT_PUBLIC_BASE_URL}/api/email/track/open?${
      new URLSearchParams(trackingData).toString()
    }" width="1" height="1" style="display:none;" alt="" />`;
    
    return html.replace('</body>', `${trackingPixel}</body>`);
  }
}

EMAIL QUEUE SYSTEM:
Create src/lib/email/queue.ts:

import { createClient } from '@/lib/supabase/client';
import { EmailService } from './service';

export interface EmailJob {
  id: string;
  campaign_id: string;
  recipient_emails: string[];
  template: any;
  priority: 'low' | 'normal' | 'high';
  scheduled_at?: string;
  status: 'pending' | 'processing' | 'completed' | 'failed';
  created_at: string;
}

export class EmailQueue {
  private supabase = createClient();
  private emailService = new EmailService();
  private isProcessing = false;

  async addJob(job: Omit<EmailJob, 'id' | 'status' | 'created_at'>): Promise<string> {
    const { data, error } = await this.supabase
      .from('email_jobs')
      .insert({
        ...job,
        status: 'pending',
        created_at: new Date().toISOString()
      })
      .select('id')
      .single();

    if (error) throw error;
    return data.id;
  }

  async processQueue(): Promise<void> {
    if (this.isProcessing) return;
    
    this.isProcessing = true;
    
    try {
      const { data: jobs, error } = await this.supabase
        .from('email_jobs')
        .select('*')
        .eq('status', 'pending')
        .order('priority', { ascending: false })
        .order('created_at', { ascending: true })
        .limit(10);

      if (error) throw error;

      for (const job of jobs || []) {
        await this.processJob(job);
      }
    } finally {
      this.isProcessing = false;
    }
  }

  private async processJob(job: EmailJob): Promise<void> {
    try {
      // Update job status to processing
      await this.supabase
        .from('email_jobs')
        .update({ status: 'processing' })
        .eq('id', job.id);

      // Send emails
      const results = await this.emailService.sendBulkEmails(
        job.template,
        job.recipient_emails
      );

      // Update job status and results
      await this.supabase
        .from('email_jobs')
        .update({ 
          status: 'completed',
          results: results,
          completed_at: new Date().toISOString()
        })
        .eq('id', job.id);

      // Log individual email events
      for (const result of results) {
        await this.supabase
          .from('email_events')
          .insert({
            campaign_id: job.campaign_id,
            contact_email: result.recipient,
            event_type: result.success ? 'sent' : 'failed',
            metadata: { 
              message_id: result.messageId,
              error: result.error 
            }
          });
      }
    } catch (error) {
      console.error('Job processing error:', error);
      
      await this.supabase
        .from('email_jobs')
        .update({ 
          status: 'failed',
          error: error instanceof Error ? error.message : 'Unknown error',
          completed_at: new Date().toISOString()
        })
        .eq('id', job.id);
    }
  }
}

EMAIL TRACKING:
Create src/app/api/email/track/ with:

  1. open/route.ts (Email open tracking):
import { NextRequest, NextResponse } from 'next/server';
import { createServerSupabaseClient } from '@/lib/supabase/server';

export async function GET(request: NextRequest) {
  const { searchParams } = new URL(request.url);
  const campaignId = searchParams.get('campaignId');
  const contactId = searchParams.get('contactId');

  if (campaignId && contactId) {
    try {
      const supabase = createServerSupabaseClient();
      
      // Log open event
      await supabase.from('email_events').insert({
        campaign_id: campaignId,
        contact_id: contactId,
        event_type: 'opened',
        metadata: {
          user_agent: request.headers.get('user-agent'),
          ip_address: request.ip,
          timestamp: new Date().toISOString()
        }
      });

      // Update campaign open count
      await supabase.rpc('increment_campaign_opens', {
        campaign_id: campaignId
      });
    } catch (error) {
      console.error('Open tracking error:', error);
    }
  }

  // Return 1x1 transparent pixel
  const pixel = Buffer.from(
    'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==',
    'base64'
  );

  return new NextResponse(pixel, {
    headers: {
      'Content-Type': 'image/png',
      'Cache-Control': 'no-cache, no-store, must-revalidate',
      'Pragma': 'no-cache',
      'Expires': '0'
    }
  });
}
  1. click/route.ts (Link click tracking):
  • URL redirection with click logging
  • UTM parameter tracking
  • A/B testing link variants
  • Click heatmap data collection

WEBHOOK HANDLING:
Create src/app/api/webhooks/ for handling email service webhooks:

  • Delivery confirmations
  • Bounce handling
  • Spam complaints
  • Unsubscribe requests

Include comprehensive error handling, retry logic, and delivery optimization.


**Expected Output**: Complete email service integration with delivery tracking and queue processing

---

## ⚑ Real-Time Features Implementation

### 🎯 Live Updates and Collaborative Features

Implementation of real-time notifications, live dashboard updates, collaborative editing, and instant user feedback across the platform.

### πŸ€– Claude Code Prompt #6: Real-Time Features Development

**Execution Priority**: FOURTH - Final integration of real-time capabilities

**Prompt for Claude Code**:

Implement comprehensive real-time features with the following specifications:

REAL-TIME INFRASTRUCTURE:
Create src/lib/real-time/ with:

  1. notifications.ts:
import { createClient } from '@/lib/supabase/client';
import { toast } from 'react-hot-toast';

export interface Notification {
  id: string;
  user_id: string;
  type: 'campaign_sent' | 'automation_triggered' | 'contact_imported' | 'system_alert';
  title: string;
  message: string;
  data?: Record<string, any>;
  read: boolean;
  created_at: string;
}

export class NotificationManager {
  private supabase = createClient();
  private subscription: any;

  startListening(userId: string) {
    this.subscription = this.supabase
      .channel(`notifications:${userId}`)
      .on('postgres_changes',
        {
          event: 'INSERT',
          schema: 'public',
          table: 'notifications',
          filter: `user_id=eq.${userId}`
        },
        (payload) => {
          this.handleNewNotification(payload.new as Notification);
        }
      )
      .subscribe();
  }

  stopListening() {
    if (this.subscription) {
      this.supabase.removeChannel(this.subscription);
    }
  }

  private handleNewNotification(notification: Notification) {
    // Show toast notification
    toast.success(notification.title, {
      duration: 5000,
      onClick: () => this.handleNotificationClick(notification)
    });

    // Dispatch custom event for notification bell update
    window.dispatchEvent(new CustomEvent('new-notification', {
      detail: notification
    }));
  }

  private handleNotificationClick(notification: Notification) {
    // Mark as read
    this.markAsRead(notification.id);

    // Navigate based on notification type
    switch (notification.type) {
      case 'campaign_sent':
        window.location.href = `/campaigns/${notification.data?.campaign_id}`;
        break;
      case 'automation_triggered':
        window.location.href = `/automations/${notification.data?.automation_id}`;
        break;
      case 'contact_imported':
        window.location.href = '/contacts';
        break;
    }
  }

  async markAsRead(notificationId: string) {
    await this.supabase
      .from('notifications')
      .update({ read: true })
      .eq('id', notificationId);
  }

  async getUnreadCount(userId: string): Promise<number> {
    const { count, error } = await this.supabase
      .from('notifications')
      .select('*', { count: 'exact', head: true })
      .eq('user_id', userId)
      .eq('read', false);

    if (error) throw error;
    return count || 0;
  }
}
  1. live-dashboard.ts:
import { createClient } from '@/lib/supabase/client';
import { Campaign, DashboardMetrics } from '@/types/dashboard';

export class LiveDashboard {
  private supabase = createClient();
  private metricsSubscription: any;
  private campaignSubscription: any;

  subscribeToMetricsUpdates(
    userId: string,
    onUpdate: (metrics: Partial<DashboardMetrics>) => void
  ) {
    // Subscribe to campaign changes that affect metrics
    this.metricsSubscription = this.supabase
      .channel('dashboard-metrics')
      .on('postgres_changes',
        {
          event: '*',
          schema: 'public',
          table: 'campaigns',
          filter: `user_id=eq.${userId}`
        },
        () => {
          this.refreshMetrics(userId, onUpdate);
        }
      )
      .on('postgres_changes',
        {
          event: '*',
          schema: 'public',
          table: 'email_events'
        },
        () => {
          this.refreshMetrics(userId, onUpdate);
        }
      )
      .subscribe();
  }

  subscribeToCampaignUpdates(
    userId: string,
    onUpdate: (campaigns: Campaign[]) => void
  ) {
    this.campaignSubscription = this.supabase
      .channel('campaign-updates')
      .on('postgres_changes',
        {
          event: '*',
          schema: 'public',
          table: 'campaigns',
          filter: `user_id=eq.${userId}`
        },
        async () => {
          const { data: campaigns } = await this.supabase
            .from('campaigns')
            .select('*')
            .eq('user_id', userId)
            .order('created_at', { ascending: false })
            .limit(10);

          if (campaigns) {
            onUpdate(campaigns);
          }
        }
      )
      .subscribe();
  }

  private async refreshMetrics(
    userId: string,
    onUpdate: (metrics: Partial<DashboardMetrics>) => void
  ) {
    try {
      const { data: metrics } = await this.supabase
        .rpc('get_dashboard_metrics', { user_id: userId });

      if (metrics) {
        onUpdate(metrics);
      }
    } catch (error) {
      console.error('Metrics refresh error:', error);
    }
  }

  unsubscribe() {
    if (this.metricsSubscription) {
      this.supabase.removeChannel(this.metricsSubscription);
    }
    if (this.campaignSubscription) {
      this.supabase.removeChannel(this.campaignSubscription);
    }
  }
}
  1. collaborative-editing.ts:
import { createClient } from '@/lib/supabase/client';
import { debounce } from 'lodash';

export interface EditingSession {
  id: string;
  user_id: string;
  user_name: string;
  document_id: string;
  document_type: 'campaign' | 'template' | 'automation';
  cursor_position?: number;
  selection_start?: number;
  selection_end?: number;
  last_activity: string;
}

export class CollaborativeEditor {
  private supabase = createClient();
  private sessionId: string;
  private documentId: string;
  private documentType: string;
  private subscription: any;
  private activeUsers: Map<string, EditingSession> = new Map();

  constructor(documentId: string, documentType: string) {
    this.documentId = documentId;
    this.documentType = documentType;
    this.sessionId = `${documentId}-${Date.now()}`;
  }

  async startSession(userId: string, userName: string) {
    // Create editing session
    await this.supabase
      .from('editing_sessions')
      .insert({
        id: this.sessionId,
        user_id: userId,
        user_name: userName,
        document_id: this.documentId,
        document_type: this.documentType,
        last_activity: new Date().toISOString()
      });

    // Subscribe to other users' activities
    this.subscription = this.supabase
      .channel(`editing:${this.documentId}`)
      .on('postgres_changes',
        {
          event: '*',
          schema: 'public',
          table: 'editing_sessions',
          filter: `document_id=eq.${this.documentId}`
        },
        (payload) => {
          this.handleSessionUpdate(payload);
        }
      )
      .subscribe();

    // Start heartbeat to maintain session
    this.startHeartbeat();
  }

  updateCursorPosition = debounce(async (position: number) => {
    await this.supabase
      .from('editing_sessions')
      .update({
        cursor_position: position,
        last_activity: new Date().toISOString()
      })
      .eq('id', this.sessionId);
  }, 100);

  updateSelection = debounce(async (start: number, end: number) => {
    await this.supabase
      .from('editing_sessions')
      .update({
        selection_start: start,
        selection_end: end,
        last_activity: new Date().toISOString()
      })
      .eq('id', this.sessionId);
  }, 100);

  private handleSessionUpdate(payload: any) {
    const session = payload.new as EditingSession;
    
    if (session.id !== this.sessionId) {
      if (payload.eventType === 'INSERT' || payload.eventType === 'UPDATE') {
        this.activeUsers.set(session.user_id, session);
        this.renderUserCursor(session);
      } else if (payload.eventType === 'DELETE') {
        this.activeUsers.delete(session.user_id);
        this.removeUserCursor(session.user_id);
      }
    }
  }

  private renderUserCursor(session: EditingSession) {
    // Emit event for UI to render user cursor
    window.dispatchEvent(new CustomEvent('user-cursor-update', {
      detail: {
        userId: session.user_id,
        userName: session.user_name,
        position: session.cursor_position,
        selectionStart: session.selection_start,
        selectionEnd: session.selection_end
      }
    }));
  }

  private removeUserCursor(userId: string) {
    window.dispatchEvent(new CustomEvent('user-cursor-remove', {
      detail: { userId }
    }));
  }

  private startHeartbeat() {
    setInterval(async () => {
      await this.supabase
        .from('editing_sessions')
        .update({ last_activity: new Date().toISOString() })
        .eq('id', this.sessionId);
    }, 30000); // Update every 30 seconds
  }

  async endSession() {
    await this.supabase
      .from('editing_sessions')
      .delete()
      .eq('id', this.sessionId);

    if (this.subscription) {
      this.supabase.removeChannel(this.subscription);
    }
  }
}

REAL-TIME COMPONENTS:
Create src/components/real-time/ with:

  1. NotificationBell.tsx:
import { useState, useEffect } from 'react';
import { BellIcon } from '@heroicons/react/24/outline';
import { NotificationManager } from '@/lib/real-time/notifications';

export function NotificationBell({ userId }: { userId: string }) {
  const [unreadCount, setUnreadCount] = useState(0);
  const [notifications, setNotifications] = useState<Notification[]>([]);
  const [manager] = useState(() => new NotificationManager());

  useEffect(() => {
    manager.startListening(userId);
    loadUnreadCount();

    const handleNewNotification = (event: CustomEvent) => {
      setUnreadCount(prev => prev + 1);
      setNotifications(prev => [event.detail, ...prev]);
    };

    window.addEventListener('new-notification', handleNewNotification as EventListener);

    return () => {
      manager.stopListening();
      window.removeEventListener('new-notification', handleNewNotification as EventListener);
    };
  }, [userId]);

  const loadUnreadCount = async () => {
    try {
      const count = await manager.getUnreadCount(userId);
      setUnreadCount(count);
    } catch (error) {
      console.error('Error loading unread count:', error);
    }
  };

  return (
    <div className="relative">
      <button className="p-2 text-gray-500 hover:text-gray-700">
        <BellIcon className="h-6 w-6" />
        {unreadCount > 0 && (
          <span className="absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full h-5 w-5 flex items-center justify-center">
            {unreadCount > 99 ? '99+' : unreadCount}
          </span>
        )}
      </button>
    </div>
  );
}
  1. LiveMetrics.tsx:
import { useState, useEffect } from 'react';
import { LiveDashboard } from '@/lib/real-time/live-dashboard';
import { DashboardMetrics } from '@/types/dashboard';

export function LiveMetrics({ userId }: { userId: string }) {
  const [metrics, setMetrics] = useState<DashboardMetrics | null>(null);
  const [liveDashboard] = useState(() => new LiveDashboard());

  useEffect(() => {
    liveDashboard.subscribeToMetricsUpdates(userId, (updatedMetrics) => {
      setMetrics(prev => prev ? { ...prev, ...updatedMetrics } : null);
    });

    return () => {
      liveDashboard.unsubscribe();
    };
  }, [userId]);

  if (!metrics) return null;

  return (
    <div className="grid grid-cols-4 gap-4">
      <MetricCard
        title="Total Campaigns"
        value={metrics.total_campaigns}
        change={metrics.campaigns_change_percent}
      />
      <MetricCard
        title="Total Contacts"
        value={metrics.total_contacts}
        change={metrics.contacts_change_percent}
      />
      <MetricCard
        title="Emails Sent"
        value={metrics.total_emails_sent}
        change={metrics.emails_change_percent}
      />
      <MetricCard
        title="Average Open Rate"
        value={`${metrics.average_open_rate.toFixed(1)}%`}
        change={metrics.open_rate_change_percent}
      />
    </div>
  );
}

WEBSOCKET INTEGRATION:
Create real-time WebSocket connections for:

  • Campaign send progress updates
  • Live email event tracking
  • Collaborative editing cursors
  • System status notifications
  • Performance monitoring alerts

PERFORMANCE OPTIMIZATION:

  • Connection pooling for Supabase subscriptions
  • Debounced real-time updates
  • Event batching for high-frequency updates
  • Memory leak prevention
  • Graceful connection handling

Include comprehensive error handling, connection recovery, and performance monitoring.


**Expected Output**: Complete real-time system with live updates, notifications, and collaborative features

---

## 🎯 API Integration Success Validation

### Comprehensive Testing & Verification

After implementing all API integrations, verify functionality with these validation steps:

#### πŸ”Œ API Endpoint Testing
- [ ] **Campaign API**: Create, read, update, delete campaigns successfully
- [ ] **Contact API**: Import, export, segment contacts with bulk operations
- [ ] **Template API**: Save, load, share email templates
- [ ] **Automation API**: Create, execute, monitor workflow automations

#### πŸ—„οΈ Database Integration Verification
- [ ] **Real-Time Subscriptions**: Live updates working across all components
- [ ] **Complex Queries**: Advanced filtering and analytics queries performing well
- [ ] **Data Relationships**: Proper foreign key relationships and data integrity
- [ ] **Performance**: Query optimization and indexing effective

#### πŸ“§ Email Service Validation
- [ ] **Email Delivery**: Test emails sending successfully via SendGrid/Postmark
- [ ] **Tracking**: Open and click tracking working correctly
- [ ] **Personalization**: Dynamic content and personalization tokens working
- [ ] **Queue Processing**: Bulk email sending with proper rate limiting

#### ⚑ Real-Time Features Testing
- [ ] **Live Dashboard**: Metrics updating in real-time
- [ ] **Notifications**: Push notifications working across browser tabs
- [ ] **Collaborative Editing**: Multiple users can edit simultaneously
- [ ] **Performance**: Real-time features not causing memory leaks

### πŸš€ Production Readiness Checklist

#### Error Handling & Resilience
- [ ] **API Error Responses**: Proper HTTP status codes and error messages
- [ ] **Database Connection Handling**: Graceful connection recovery
- [ ] **Email Service Fallbacks**: Retry logic and alternative providers
- [ ] **Real-Time Connection Recovery**: Automatic reconnection on failures

#### Security Implementation
- [ ] **Authentication Enforcement**: All APIs require proper authentication
- [ ] **Input Validation**: All user inputs validated and sanitized
- [ ] **Rate Limiting**: API endpoints protected against abuse
- [ ] **Data Encryption**: Sensitive data encrypted in transit and at rest

#### Performance Optimization
- [ ] **API Response Times**: All endpoints responding under 200ms
- [ ] **Database Query Performance**: Complex queries optimized with indexes
- [ ] **Email Sending Speed**: Bulk emails processing efficiently
- [ ] **Real-Time Performance**: Live updates not impacting app performance

This API integration implementation creates a production-ready backend that powers the email marketing platform with reliable data management, email delivery, and real-time user experiences. The system is designed to scale from MVP to enterprise-level usage.