XYLEX Group

email api reference

email api reference

this document covers all email api endpoints their request/response formats and usage examples

table of contents


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