API Reference
Complete API documentation for the StoryFlow email management system, including endpoints, request/response formats, and code examples.
Authentication
All API endpoints require authentication using session-based auth or API tokens.
Headers
Authorization: Bearer <session_token>
Content-Type: application/json
``` -->
### Permissions
- **Admin APIs**: Require premium subscription tier (admin access)
- **User APIs**: Require valid user session
- **Webhook APIs**: Require webhook signature verification
## Admin APIs
Admin endpoints for managing the email system (prefix: `/api/admin/email/`)
### Email Templates
#### List Templates
```http
GET /api/admin/email/templates
``` -->
**Query Parameters:**
| Parameter | Type | Description | Default |
|-----------|------|-------------|---------|
| `category` | string | Filter by category (`transactional`, `marketing`, etc.) | `all` |
| `search` | string | Search in template name and description | - |
| `status` | string | Filter by status (`active`, `inactive`, `all`) | `all` |
| `limit` | number | Number of templates to return | `20` |
| `offset` | number | Pagination offset | `0` |
**Response:**
```json
{
"success": true,
"templates": [
{
"id": "uuid",
"name": "welcome_new_user",
"display_name": "Welcome to StoryFlow",
"description": "Welcome email for new users",
"category": "onboarding",
"subject_template": "Welcome to StoryFlow, {{user_name}}!",
"html_template": "<!DOCTYPE html>...",
"text_template": "Welcome to StoryFlow...",
"available_variables": {
"user_name": "User's display name",
"onboarding_url": "URL to start onboarding"
},
"required_variables": ["user_name", "onboarding_url"],
"is_active": true,
"is_system": true,
"total_sent": 1250,
"total_opened": 875,
"total_clicked": 234,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-20T15:45:00Z"
}
],
"pagination": {
"total": 15,
"limit": 20,
"offset": 0,
"hasMore": false
}
}
``` -->
#### Create Template
```http
POST /api/admin/email/templates
``` -->
**Request Body:**
```json
{
"name": "story_reminder_monthly",
"display_name": "Monthly Story Reminder",
"description": "Monthly reminder to continue working on stories",
"category": "reminder",
"subject_template": "Monthly check-in: {{story_title}}",
"html_template": "<!DOCTYPE html><html>...</html>",
"text_template": "Hi {{user_name}}...",
"available_variables": {
"user_name": "User's display name",
"story_title": "Title of the story",
"continue_url": "URL to continue the story"
},
"default_variables": {
"story_title": "Your Story"
},
"required_variables": ["user_name", "continue_url"],
"trigger_events": ["story_reminder"],
"send_delay_hours": 0,
"max_sends_per_user": null,
"is_active": true
}
``` -->
**Response:**
```json
{
"success": true,
"template": {
"id": "new-template-uuid",
"name": "story_reminder_monthly",
// ... full template object
},
"message": "Email template created successfully"
}
``` -->
#### Get Template
```http
GET /api/admin/email/templates/{id}
``` -->
**Response:**
```json
{
"success": true,
"template": {
// Full template object with all fields
}
}
``` -->
#### Update Template
```http
PUT /api/admin/email/templates/{id}
``` -->
**Request Body:** Same as create template
**Response:**
```json
{
"success": true,
"template": {
// Updated template object
},
"message": "Template updated successfully"
}
``` -->
#### Delete Template
```http
DELETE /api/admin/email/templates/{id}
``` -->
**Response:**
```json
{
"success": true,
"message": "Template deleted successfully"
}
``` -->
### Email Analytics
#### Get Analytics Data
```http
GET /api/admin/email/analytics
``` -->
**Query Parameters:**
| Parameter | Type | Description | Default |
|-----------|------|-------------|---------|
| `period` | number | Number of days to analyze | `30` |
| `template_id` | string | Filter by specific template | - |
| `category` | string | Filter by email category | - |
**Response:**
```json
{
"success": true,
"period": 30,
"overall_stats": {
"total_sent": 5420,
"total_delivered": 5298,
"total_opened": 2115,
"total_clicked": 423,
"total_failed": 122,
"delivery_rate": "97.75",
"open_rate": "39.93",
"click_rate": "20.00",
"failure_rate": "2.25"
},
"template_performance": [
{
"id": "template-uuid",
"name": "welcome_new_user",
"display_name": "Welcome to StoryFlow",
"category": "onboarding",
"total_sent": 234,
"total_delivered": 230,
"total_opened": 145,
"total_clicked": 67,
"delivery_rate": "98.29",
"open_rate": "63.04",
"click_rate": "46.21"
}
],
"daily_trends": [
{
"date": "2024-01-20",
"sent": 45,
"delivered": 44,
"opened": 18,
"clicked": 5
}
],
"category_breakdown": [
{
"category": "onboarding",
"total_sent": 890,
"total_delivered": 875,
"total_opened": 523,
"total_clicked": 234,
"template_count": 3,
"delivery_rate": "98.31",
"open_rate": "59.77",
"click_rate": "44.75"
}
],
"recent_activity": [
{
"id": "email-uuid",
"subject": "Welcome to StoryFlow, John!",
"to_email": "john@example.com",
"status": "sent",
"created_at": "2024-01-22T10:30:00Z",
"email_templates": {
"name": "welcome_new_user",
"display_name": "Welcome to StoryFlow",
"category": "onboarding"
}
}
],
"queue_status": {
"pending": 12,
"processing": 3
}
}
``` -->
### A/B Testing
#### Create A/B Test
```http
POST /api/admin/email/ab-test
``` -->
**Request Body:**
```json
{
"base_template_id": "base-template-uuid",
"variant_name": "subject_test_1",
"variant_display_name": "Subject Line Test Variant",
"variant_subject": "🎉 Welcome to StoryFlow, {{user_name}}!",
"variant_html": "<!DOCTYPE html>...",
"variant_text": "Welcome text...",
"test_percentage": 50,
"test_duration_days": 7,
"success_metric": "open_rate"
}
``` -->
**Response:**
```json
{
"success": true,
"ab_test": {
"id": "test-uuid",
"name": "Welcome to StoryFlow - subject_test_1 Test",
"base_template_id": "base-template-uuid",
"variant_template_id": "variant-template-uuid",
"test_percentage": 50,
"success_metric": "open_rate",
"status": "running",
"start_date": "2024-01-22T10:30:00Z",
"end_date": "2024-01-29T10:30:00Z"
},
"base_template": {
// Base template object
},
"variant_template": {
// Variant template object
},
"message": "A/B test created successfully"
}
``` -->
#### List A/B Tests
```http
GET /api/admin/email/ab-test
``` -->
**Query Parameters:**
| Parameter | Type | Description | Default |
|-----------|------|-------------|---------|
| `status` | string | Filter by status (`running`, `completed`, `paused`) | - |
| `limit` | number | Number of tests to return | `20` |
| `offset` | number | Pagination offset | `0` |
**Response:**
```json
{
"success": true,
"ab_tests": [
{
"id": "test-uuid",
"name": "Welcome Email Subject Test",
"status": "completed",
"base_template": {
"id": "base-uuid",
"name": "welcome_new_user",
"display_name": "Welcome to StoryFlow"
},
"variant_template": {
"id": "variant-uuid",
"name": "welcome_new_user_variant_emoji",
"display_name": "Welcome to StoryFlow (Variant emoji)"
},
"test_percentage": 50,
"success_metric": "open_rate",
"start_date": "2024-01-15T10:00:00Z",
"end_date": "2024-01-22T10:00:00Z",
"results": {
"base_stats": {
"sent": 127,
"opened": 78,
"clicked": 23,
"open_rate": 0.6142,
"click_rate": 0.2949
},
"variant_stats": {
"sent": 131,
"opened": 89,
"clicked": 31,
"open_rate": 0.6794,
"click_rate": 0.3483
},
"winner": "variant",
"confidence": 95,
"is_significant": true,
"improvement": "10.62",
"total_samples": 258
}
}
],
"total": 1
}
``` -->
## User APIs
User-facing endpoints for email management (prefix: `/api/user/emails/`)
### Received Emails
#### List User's Emails
```http
GET /api/user/emails/received
``` -->
**Query Parameters:**
| Parameter | Type | Description | Default |
|-----------|------|-------------|---------|
| `limit` | number | Number of emails to return | `50` |
| `offset` | number | Pagination offset | `0` |
| `unread_only` | boolean | Only return unread emails | `false` |
**Response:**
```json
{
"success": true,
"emails": [
{
"id": "email-uuid",
"subject": "Time to add to your story: Childhood Memories",
"html_content": "<!DOCTYPE html>...",
"text_content": "Hi John...",
"template_variables": {
"user_name": "John",
"story_title": "Childhood Memories",
"continue_url": "/stories/123/continue"
},
"status": "sent",
"created_at": "2024-01-22T10:30:00Z",
"sent_at": "2024-01-22T10:31:00Z",
"opened_at": null,
"clicked_at": null,
"email_templates": {
"id": "template-uuid",
"name": "story_reminder_weekly",
"display_name": "Weekly Story Reminder",
"category": "reminder"
}
}
],
"total": 15,
"limit": 50,
"offset": 0,
"has_more": false
}
``` -->
#### Mark Emails as Read/Clicked
```http
POST /api/user/emails/received
``` -->
**Request Body:**
```json
{
"email_ids": ["email-uuid-1", "email-uuid-2"],
"action": "mark_opened"
}
``` -->
**Actions:**
- `mark_opened`: Mark emails as opened/read
- `mark_clicked`: Mark emails as clicked (also sets opened)
**Response:**
```json
{
"success": true,
"message": "2 emails marked as opened"
}
``` -->
## Automation Service APIs
Internal APIs for triggering email automation (used by other system components)
### Trigger Events
#### Generic Event Trigger
```typescript
import { emailAutomationService } from '@/lib/email/email-automation-service'
await emailAutomationService.triggerEvent({
event: 'story_created',
user_id: 'user-uuid',
template_variables: {
story_title: 'My New Story',
story_url: '/stories/123'
},
delay_hours: 0,
conditions: {
user_segment: 'active'
}
})
``` -->
#### Specific Event Methods
**User Signup**
```typescript
await emailAutomationService.triggerUserSignup('user-uuid', {
user_name: 'John Doe',
signup_source: 'web'
})
``` -->
**Story Reminder**
```typescript
await emailAutomationService.triggerStoryReminder('user-uuid', {
story_id: 'story-uuid',
story_title: 'Childhood Memories',
last_updated: '2024-01-15'
})
``` -->
**Family Invitation**
```typescript
await emailAutomationService.triggerFamilyInvitation('user-uuid', {
family_id: 'family-uuid',
family_name: 'Smith Family',
inviter_name: 'John Smith',
invitation_token: 'abc123xyz'
})
``` -->
### Queue Processing
#### Process Email Queue
```typescript
// Process up to 50 emails from queue
await emailAutomationService.processEmailQueue(50)
``` -->
This method is typically called by a cron job or background service.
## Webhook APIs
Endpoints for handling external service webhooks (prefix: `/api/webhooks/email/`)
### Resend Webhooks
#### Email Events
```http
POST /api/webhooks/email/resend
``` -->
**Request Body (from Resend):**
```json
{
"type": "email.delivered",
"created_at": "2024-01-22T10:32:00Z",
"data": {
"email_id": "provider-email-id",
"to": "user@example.com",
"subject": "Welcome to StoryFlow"
}
}
``` -->
**Webhook Events:**
- `email.sent`: Email was sent successfully
- `email.delivered`: Email was delivered to inbox
- `email.opened`: Recipient opened the email
- `email.clicked`: Recipient clicked a link
- `email.bounced`: Email bounced (hard or soft)
- `email.complained`: Recipient marked as spam
**Response:**
```json
{
"success": true,
"message": "Event processed"
}
``` -->
## Error Responses
All endpoints use consistent error response format:
### Error Format
```json
{
"error": "Error message describing what went wrong",
"code": "ERROR_CODE",
"details": {
"field": "specific field that caused the error",
"value": "invalid value"
}
}
``` -->
### Common HTTP Status Codes
| Status | Description |
|--------|-------------|
| `400` | Bad Request - Invalid request data |
| `401` | Unauthorized - Authentication required |
| `403` | Forbidden - Insufficient permissions |
| `404` | Not Found - Resource doesn't exist |
| `409` | Conflict - Resource already exists |
| `422` | Unprocessable Entity - Validation failed |
| `429` | Too Many Requests - Rate limit exceeded |
| `500` | Internal Server Error - System error |
### Error Examples
**Validation Error (400)**
```json
{
"error": "Missing required fields: name, subject_template, html_template",
"code": "VALIDATION_ERROR",
"details": {
"missing_fields": ["name", "subject_template", "html_template"]
}
}
``` -->
**Permission Error (403)**
```json
{
"error": "Admin access required",
"code": "INSUFFICIENT_PERMISSIONS"
}
``` -->
**Not Found Error (404)**
```json
{
"error": "Email template not found",
"code": "TEMPLATE_NOT_FOUND",
"details": {
"template_id": "invalid-uuid"
}
}
``` -->
## Rate Limits
API endpoints have rate limits to prevent abuse:
| Endpoint Group | Limit | Window |
|----------------|-------|--------|
| Admin APIs | 100 requests | 1 minute |
| User APIs | 60 requests | 1 minute |
| Webhook APIs | 1000 requests | 1 minute |
**Rate Limit Headers:**
```http
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200
``` -->
## SDK Examples
### TypeScript/Node.js
```typescript
import { StoryFlowEmailClient } from '@mystoryflow/email-sdk'
const client = new StoryFlowEmailClient({
apiKey: process.env.STORYFLOW_API_KEY,
baseUrl: 'https://mystoryflow.com/api'
})
// List templates
const templates = await client.admin.templates.list({
category: 'onboarding',
limit: 10
})
// Create template
const newTemplate = await client.admin.templates.create({
name: 'welcome_variant',
display_name: 'Welcome Email Variant',
category: 'onboarding',
subject_template: 'Welcome {{user_name}}!',
html_template: '<html>...</html>'
})
// Get analytics
const analytics = await client.admin.analytics.get({
period: 30,
category: 'reminder'
})
``` -->
### cURL Examples
**Create Template:**
```bash
curl -X POST "https://mystoryflow.com/api/admin/email/templates" \
-H "Authorization: Bearer your-session-token" \
-H "Content-Type: application/json" \
-d '{
"name": "test_template",
"display_name": "Test Template",
"category": "system",
"subject_template": "Test: {{user_name}}",
"html_template": "<p>Hello {{user_name}}!</p>"
}'
``` -->
**Get Analytics:**
```bash
curl "https://mystoryflow.com/api/admin/email/analytics?period=7" \
-H "Authorization: Bearer your-session-token"
``` -->
**List User Emails:**
```bash
curl "https://mystoryflow.com/api/user/emails/received?limit=10&unread_only=true" \
-H "Authorization: Bearer your-session-token"
``` -->
For implementation details and code examples, see the [Technical Architecture](./technical-architecture) and [Setup Guide](./setup-configuration).