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
/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
/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
}
}
}
/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
}
}
/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"
}
}
/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"
}
}
/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
/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"
}
/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"
}