API Documentation

Complete reference for the Email Promotion Platform API

Authentication

All API endpoints (except /health) require tenant authentication. Provide tenant identification via one of the following methods:

Subdomain

Access via tenant subdomain

https://tenant1.sendpromotion.email/api/campaigns

HTTP Header

Send X-Tenant-ID header

X-Tenant-ID: 1

Cookie

Set tenant_id cookie

tenant_id=1

Health API

GET /health

Health check endpoint to verify API status

Response (200 OK)

{
    "status": "healthy",
    "timestamp": "2024-01-15T10:30:00+00:00",
    "checks": {
        "config": {
            "status": "ok"
        },
        "database": {
            "status": "ok"
        }
    }
}

Campaigns API

Base Path: /api/campaigns

GET /api/campaigns

List all campaigns with pagination and filters

Query Parameters

Parameter Type Default Description
page integer 1 Page number (1-based)
per_page integer 20 Items per page (max 100)
status string - Filter by status (draft, scheduled, sending, sent, paused, cancelled)
search string - Search campaigns by name

Response (200 OK)

{
    "success": true,
    "data": {
        "data": [
            {
                "id": 1,
                "tenant_id": 1,
                "name": "Summer Sale 2024",
                "subject": "50% Off Everything!",
                "from_name": "Acme Corp",
                "from_email": "noreply@acme.com",
                "reply_to_email": "support@acme.com",
                "status": "draft",
                "scheduled_at": null,
                "started_at": null,
                "completed_at": null,
                "target_list_id": 5,
                "total_recipients": 0,
                "sent_count": 0,
                "delivered_count": 0,
                "opened_count": 0,
                "clicked_count": 0,
                "bounced_count": 0,
                "unsubscribed_count": 0,
                "created_by": 1,
                "created_at": "2024-01-15 10:30:00",
                "updated_at": "2024-01-15 10:30:00",
                "deleted_at": null
            }
        ],
        "pagination": {
            "page": 1,
            "per_page": 20,
            "total": 45,
            "total_pages": 3,
            "has_next": true,
            "has_prev": false
        }
    }
}
GET /api/campaigns/{id}

Get a single campaign by ID

Path Parameters

Parameter Type Description
id integer Campaign ID

Response (200 OK)

{
    "success": true,
    "data": {
        "id": 1,
        "tenant_id": 1,
        "name": "Summer Sale 2024",
        "subject": "50% Off Everything!",
        "from_name": "Acme Corp",
        "from_email": "noreply@acme.com",
        "reply_to_email": "support@acme.com",
        "status": "draft",
        "scheduled_at": null,
        "started_at": null,
        "completed_at": null,
        "target_list_id": 5,
        "total_recipients": 0,
        "sent_count": 0,
        "delivered_count": 0,
        "opened_count": 0,
        "clicked_count": 0,
        "bounced_count": 0,
        "unsubscribed_count": 0,
        "created_by": 1,
        "created_at": "2024-01-15 10:30:00",
        "updated_at": "2024-01-15 10:30:00",
        "deleted_at": null
    }
}
POST /api/campaigns

Create a new campaign

Request Body

Required fields: name, subject, from_name, from_email

Optional fields: status, scheduled_at, target_list_id, reply_to_email

{
    "name": "Summer Sale 2024",
    "subject": "50% Off Everything!",
    "from_name": "Acme Corp",
    "from_email": "noreply@acme.com",
    "reply_to_email": "support@acme.com",
    "status": "draft",
    "scheduled_at": null,
    "target_list_id": 5
}

Response (201 OK)

{
    "success": true,
    "data": {
        "id": 1,
        "tenant_id": 1,
        "name": "Summer Sale 2024",
        "subject": "50% Off Everything!",
        "status": "draft",
        "created_at": "2024-01-15 10:30:00"
    }
}
PUT /api/campaigns/{id}

Update an existing campaign (partial updates supported)

Path Parameters

Parameter Type Description
id integer Campaign ID

Request Body

Optional fields: name, subject, from_name, from_email, status, scheduled_at, target_list_id

{
    "name": "Summer Sale 2024 - Updated",
    "status": "scheduled",
    "scheduled_at": "2024-01-20 10:00:00"
}

Response (200 OK)

{
    "success": true,
    "data": {
        "id": 1,
        "name": "Summer Sale 2024 - Updated",
        "status": "scheduled",
        "updated_at": "2024-01-15 11:00:00"
    }
}
DELETE /api/campaigns/{id}

Delete a campaign (soft delete)

Path Parameters

Parameter Type Description
id integer Campaign ID

Response (200 OK)

{
    "success": true,
    "message": "Campaign deleted successfully"
}

AI API

Base Path: /api/ai

POST /api/ai/generate-subject

Generate a compelling email subject line using AI

Request Body

Required fields: campaign_name

Optional fields: description

{
    "campaign_name": "Summer Sale 2024",
    "description": "50% off all products, limited time offer"
}

Response (200 OK)

{
    "success": true,
    "data": {
        "subject": "Summer Sale: 50% Off Everything - Limited Time!",
        "generated_by": "ollama"
    }
}

Error Responses

Status 503:

{
    "error": true,
    "message": "AI service is not available"
}

Status 400:

{
    "error": true,
    "message": "campaign_name is required"
}
POST /api/ai/rewrite-body

Rewrite email body content using AI

Request Body

Required fields: body

Optional fields: tone, length

{
    "body": "Check out our new products!",
    "tone": "professional",
    "length": "medium"
}

Response (200 OK)

{
    "success": true,
    "data": {
        "body": "We are excited to introduce our latest product line...",
        "generated_by": "ollama"
    }
}

Error Responses

Status 503:

{
    "error": true,
    "message": "AI service is not available"
}

Status 400:

{
    "error": true,
    "message": "body is required"
}