email api reference
email api reference
this document covers all email api endpoints their request/response formats and usage examples
table of contents
- authentication
- post /api/email/send
- post /api/email/bulk
- get /api/email/status/[email_id]
- get /api/email/track
- post /api/email/track
- error codes
authentication
all email api endpoints require authentication headers:
X-Company-Id: <company_uuid>
X-Organization-Id: <organization_uuid>
X-User-Id: <user_uuid>
Content-Type: application/json
```typescript
some templates (like `password-reset` `welcome` `verification`) don't require authentication as they're used during signup/login flows
---
## post /api/email/send
send a single email using a template or custom html
### request
```typescript
POST /api/email/send HTTP/1.1
Host: app.suitsbooks.com
Content-Type: application/json
X-Company-Id: 123e4567-e89b-12d3-a456-426614174000
X-Organization-Id: 123e4567-e89b-12d3-a456-426614174001
X-User-Id: 123e4567-e89b-12d3-a456-426614174002
{
"to": "customer@example.com",
"subject": "Your invoice is ready",
"template_id": "invoice",
"template_data": {
"RECIPIENT_NAME": "John Doe",
"AUTHOR_NAME": "SuitsBooks",
"INVOICE_NUMBER": "INV-2025-001",
"AMOUNT_TOTAL": "€1,234.56",
"DUE_DATE": "December 15, 2025",
"INVOICE_URL": "https://app.suitsbooks.com/invoices/inv_123"
}
}
```typescript
### request body
| field | type | required | description |
|-------|------|----------|-------------|
| `to` | string \| object \| array | yes | recipient(s) |
| `subject` | string | yes | email subject (max 200 chars) |
| `template_id` | string | yes | template identifier |
| `template_data` | object | no | variables for template |
| `from` | string | no | sender (default: from config) |
| `reply_to` | string | no | reply-to address |
| `cc` | string \| array | no | cc recipients |
| `bcc` | string \| array | no | bcc recipients |
| `attachments` | array | no | file attachments |
| `tags` | array | no | tags for tracking |
| `resource_type_ref` | string | no | link to resource type |
| `resource_id_ref` | string | no | link to resource id |
| `html_body` | string | no | custom html (for `template_id: "custom"`) |
| `locale` | string | no | locale (default: "en-us") |
| `language` | string | no | language (default: "en") |
### recipient formats
```json
// Simple string
"to": "user@example.com"
// With name
"to": { "email": "user@example.com", "name": "John Doe" }
// Multiple recipients
"to": ["user1@example.com", "user2@example.com"]
// Multiple with names
"to": [
{ "email": "user1@example.com", "name": "User One" },
{ "email": "user2@example.com", "name": "User Two" }
]
```typescript
### attachments format
```json
"attachments": [
{
"filename": "invoice.pdf",
"content": "base64EncodedContent...",
"contentType": "application/pdf"
},
{
"filename": "logo.png",
"path": "https://example.com/logo.png"
}
]
```typescript
### response
#### success (200)
```json
{
"success": true,
"email_id": "123e4567-e89b-12d3-a456-426614174000",
"resend_id": "re_abc123xyz",
"message": "Email sent successfully"
}
```typescript
#### error (400/401/500)
```json
{
"success": false,
"error": "Invalid email address provided."
}
```typescript
### examples
#### send invoice email
```bash
curl -X POST https://app.suitsbooks.com/api/email/send \
-H "Content-Type: application/json" \
-H "X-Company-Id: company_123" \
-H "X-User-Id: user_123" \
-d '{
"to": "customer@example.com",
"subject": "Invoice INV-001 from SuitsBooks",
"template_id": "invoice",
"template_data": {
"RECIPIENT_NAME": "John Doe",
"AUTHOR_NAME": "SuitsBooks",
"INVOICE_NUMBER": "INV-001",
"AMOUNT_TOTAL": "€100.00",
"DUE_DATE": "December 31, 2025",
"INVOICE_URL": "https://app.suitsbooks.com/invoices/123"
},
"resource_type_ref": "invoice",
"resource_id_ref": "inv_123"
}'
```typescript
#### send custom html email
```bash
curl -X POST https://app.suitsbooks.com/api/email/send \
-H "Content-Type: application/json" \
-H "X-Company-Id: company_123" \
-H "X-User-Id: user_123" \
-d '{
"to": "user@example.com",
"subject": "Custom Message",
"template_id": "custom",
"html_body": "<html><body><h1>Hello!</h1><p>This is a custom email.</p></body></html>"
}'
```typescript
#### send with attachments
```bash
curl -X POST https://app.suitsbooks.com/api/email/send \
-H "Content-Type: application/json" \
-H "X-Company-Id: company_123" \
-H "X-User-Id: user_123" \
-d '{
"to": "customer@example.com",
"subject": "Your invoice with PDF",
"template_id": "invoice",
"template_data": { ... },
"attachments": [
{
"filename": "invoice.pdf",
"content": "JVBERi0xLjQKJ...",
"contentType": "application/pdf"
}
]
}'
```typescript
---
## post /api/email/bulk
send multiple emails in batches
### request
```typescript
POST /api/email/bulk HTTP/1.1
Host: app.suitsbooks.com
Content-Type: application/json
X-Company-Id: company_123
X-Organization-Id: org_123
X-User-Id: user_123
{
"emails": [
{
"id": "email-1",
"to": "user1@example.com",
"subject": "Invoice #001",
"template_id": "invoice",
"template_data": {
"INVOICE_NUMBER": "001",
"AMOUNT_TOTAL": "€100.00"
}
},
{
"id": "email-2",
"to": "user2@example.com",
"subject": "Invoice #002",
"template_id": "invoice",
"template_data": {
"INVOICE_NUMBER": "002",
"AMOUNT_TOTAL": "€200.00"
}
}
],
"batchDelay": 1000
}
```typescript
### request body
| field | type | required | description |
|-------|------|----------|-------------|
| `emails` | array | yes | array of email objects (max 100) |
| `batchdelay` | number | no | delay between batches in ms (default: 1000) |
each email object in the array follows the same format as the single send endpoint plus an optional `id` field for tracking
### response
#### success (200)
```json
{
"success": true,
"total": 10,
"sent": 10,
"failed": 0,
"results": [
{
"id": "email-1",
"success": true,
"email_id": "123e4567-e89b-12d3-a456-426614174000"
},
{
"id": "email-2",
"success": true,
"email_id": "123e4567-e89b-12d3-a456-426614174001"
}
]
}
```typescript
#### partial success (200)
```json
{
"success": false,
"total": 10,
"sent": 8,
"failed": 2,
"results": [
{
"id": "email-1",
"success": true,
"email_id": "..."
},
{
"id": "email-5",
"success": false,
"error": "Invalid email address provided."
},
{
"id": "email-9",
"success": false,
"error": "Emails to this domain are not allowed."
}
]
}
```typescript
### rate limits
- maximum 100 emails per bulk request
- emails processed in batches of 50
- configurable delay between batches
### example
```bash
curl -X POST https://app.suitsbooks.com/api/email/bulk \
-H "Content-Type: application/json" \
-H "X-Company-Id: company_123" \
-H "X-User-Id: user_123" \
-d '{
"emails": [
{
"id": "inv-001",
"to": "customer1@example.com",
"subject": "Invoice #001",
"template_id": "invoice",
"template_data": {
"RECIPIENT_NAME": "Customer 1",
"INVOICE_NUMBER": "001"
}
},
{
"id": "inv-002",
"to": "customer2@example.com",
"subject": "Invoice #002",
"template_id": "invoice",
"template_data": {
"RECIPIENT_NAME": "Customer 2",
"INVOICE_NUMBER": "002"
}
}
],
"batchDelay": 500
}'
```typescript
---
## get /api/email/status/[email_id]
get the status and details of a sent email
### request
```typescript
GET /api/email/status/123e4567-e89b-12d3-a456-426614174000 HTTP/1.1
Host: app.suitsbooks.com
X-User-Id: user_123
```typescript
### response
#### success (200)
```json
{
"success": true,
"data": {
"email_id": "123e4567-e89b-12d3-a456-426614174000",
"created_at": "2025-12-01T10:30:00Z",
"subject": "Your invoice is ready",
"recipient_email": "customer@example.com",
"recipient_name": "John Doe",
"status": "delivered",
"template_id": "invoice",
"opened": true,
"delivered": true,
"resource_type_ref": "invoice",
"resource_id_ref": "inv_123"
}
}
```typescript
### status values
| status | description |
|--------|-------------|
| `pending` | queued for sending |
| `sent` | sent to resend |
| `delivered` | delivered to recipient |
| `opened` | recipient opened email |
| `bounced` | email bounced |
| `failed` | failed to send |
### example
```bash
curl https://app.suitsbooks.com/api/email/status/123e4567-e89b-12d3-a456-426614174000 \
-H "X-User-Id: user_123"
```typescript
---
## get /api/email/track
track email opens via an invisible tracking pixel
### usage
include this pixel in your email templates:
```html
<img
src="https://app.suitsbooks.com/api/email/track?view_key={{VIEW_KEY}}"
width="1"
height="1"
alt=""
/>
```typescript
### request
```typescript
GET /api/email/track?view_key=abc123xyz HTTP/1.1
Host: app.suitsbooks.com
```typescript
### response
returns a 1x1 transparent gif image
the endpoint updates the email record:
- sets `opened = true`
- updates `time` with the open timestamp
### headers
```typescript
Content-Type: image/gif
Cache-Control: no-store, no-cache, must-revalidate
```typescript
---
## post /api/email/track
track email events programmatically
### request
```typescript
POST /api/email/track HTTP/1.1
Host: app.suitsbooks.com
Content-Type: application/json
{
"view_key": "abc123xyz",
"event_type": "clicked"
}
```typescript
### event types
| event | description |
|-------|-------------|
| `delivered` | email was delivered |
| `opened` | email was opened |
| `clicked` | link was clicked |
### response
```json
{
"success": true
}
```typescript
### example
```bash
curl -X POST https://app.suitsbooks.com/api/email/track \
-H "Content-Type: application/json" \
-d '{
"view_key": "abc123xyz",
"event_type": "clicked"
}'
```typescript
---
## error codes
### http status codes
| code | meaning |
|------|---------|
| 200 | success |
| 400 | bad request - invalid payload |
| 401 | unauthorized - missing or invalid auth headers |
| 404 | not found - email or resource not found |
| 500 | internal server error |
### error messages
| error | description | resolution |
|-------|-------------|------------|
| `missing required fields` | required fields not provided | include all required fields |
| `invalid email address provided.` | email format is invalid | use valid email format |
| `emails to this domain are not allowed.` | domain is blocked | use different email domain |
| `email template not found.` | template id doesn't exist | use valid template_id |
| `email subject is required.` | subject not provided | include subject field |
| `email recipient is required.` | no recipient specified | include to field |
| `email service not configured.` | resend api key missing | configure resend_api_key |
| `too many recipients. maximum is 50.` | too many recipients | split into multiple requests |
| `attachment exceeds maximum size limit.` | attachment too large | reduce attachment size |
| `too many attachments. maximum is 10.` | too many attachments | reduce number of attachments |
| `unauthorized` | auth headers missing/invalid | include valid auth headers |
### error response format
```json
{
"success": false,
"error": "Error message here"
}
```typescript
for bulk operations errors are included in the results array:
```json
{
"success": false,
"total": 10,
"sent": 8,
"failed": 2,
"results": [
{ "id": "1", "success": false, "error": "Invalid email address" }
]
}
```typescript