Appearance
Email System API Reference
Complete API reference for email system endpoints.
Authentication
All endpoints require authentication via Bearer token:
Authorization: Bearer <token>Most endpoints also require email verification:
X-Email-Verified: trueEmail Webhooks
POST /api/webhooks/email/:tenantId
Process incoming email for a specific tenant.
Path Parameters:
tenantId(string, required): Tenant ID
Headers:
Content-Type: application/jsonx-email-signature(string, optional): HMAC signature for verification
Request Body:
json
{
"from": "sender@example.com",
"to": "tenant@domain.com",
"subject": "Email subject",
"body": "Email body text",
"tenantId": "optional-tenant-id"
}Response:
json
{
"success": true,
"response": "Generated response text",
"actions": ["Extracted 3 fields", "Generated AI response"]
}Error Responses:
400: Invalid request body401: Missing or invalid signature404: Tenant not found429: Usage limit exceeded
POST /api/webhooks/email/incoming
Catch-all endpoint that extracts tenant from email address.
Request Body:
json
{
"from": "sender@example.com",
"to": "tenant-slug@domain.com",
"subject": "Email subject",
"body": "Email body text"
}Response:
Same as /api/webhooks/email/:tenantId
Error Responses:
400: Missing "to" email address404: No tenant found for email address
Email Workflows
GET /api/email-workflows
List all workflows for the tenant.
Query Parameters:
- None
Response:
json
{
"workflows": [
{
"id": "workflow-id",
"name": "Lead Capture",
"description": "Handles lead inquiries",
"goal": "lead_capture",
"is_active": true,
"priority": 5,
"workflow_config": {
"steps": [...]
},
"context": "Business context...",
"response_template": "Template...",
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-01T00:00:00Z"
}
]
}POST /api/email-workflows
Create a new workflow.
Request Body:
json
{
"name": "Workflow Name",
"description": "Workflow description",
"goal": "general_inquiry",
"is_active": true,
"priority": 0,
"workflow_config": {
"steps": [
{
"id": "step-id",
"type": "extract_info",
"config": {
"fields": "name, email, phone"
}
}
]
},
"context": "Business context for AI",
"response_template": "Response template with {variables}"
}Response:
json
{
"workflow": {
"id": "workflow-id",
...
}
}Validation:
name: Required, stringgoal: Required, one of:general_inquiry,lead_capture,helpdesk,sales,appointment_bookingpriority: Optional, number (default: 0)is_active: Optional, boolean (default: true)
PUT /api/email-workflows/:id
Update an existing workflow (partial update supported).
Path Parameters:
id(string, required): Workflow ID
Request Body:
Partial workflow object (only include fields to update):
json
{
"is_active": false,
"priority": 10
}Response:
json
{
"workflow": {
"id": "workflow-id",
...
}
}Error Responses:
400: No fields to update404: Workflow not found
DELETE /api/email-workflows/:id
Delete a workflow.
Path Parameters:
id(string, required): Workflow ID
Response:
json
{
"success": true
}Email Context
GET /api/email-context
List all context library entries.
Response:
json
{
"contexts": [
{
"id": "context-id",
"context_key": "company_info",
"context_value": "Business information...",
"is_active": true,
"created_at": "2025-01-01T00:00:00Z"
}
]
}POST /api/email-context
Create a new context entry.
Request Body:
json
{
"context_key": "company_info",
"context_value": "Business information...",
"is_active": true
}Response:
json
{
"context": {
"id": "context-id",
...
}
}DELETE /api/email-context/:id
Delete a context entry.
Path Parameters:
id(string, required): Context ID
Response:
json
{
"success": true
}Email Configuration
GET /api/email-config
Get email configuration for tenant.
Response:
json
{
"incoming_email_address": "tenant@domain.com",
"email_domain": "domain.com",
"smtp_config": {
"host": "smtp.example.com",
"port": 587,
"user": "username",
"password": "***",
"from_email": "noreply@domain.com"
},
"email_verified": true,
"email_auto_respond": true
}Note: Password is masked as *** for security.
POST /api/email-config
Update email configuration.
Request Body:
json
{
"smtp_config": {
"host": "smtp.example.com",
"port": 587,
"user": "username",
"password": "password",
"from_email": "noreply@domain.com"
},
"email_auto_respond": true,
"imap_config": {
"imap_host": "imap.example.com",
"imap_port": 993,
"imap_username": "username",
"imap_password": "password",
"imap_mailbox": "INBOX",
"imap_enabled": true
}
}Validation:
smtp_config.host: Required if smtp_config providedsmtp_config.port: Required if smtp_config providedsmtp_config.user: Required if smtp_config provided
Response:
json
{
"success": true
}Emailit Integration
GET /api/emailit/domains
List all domains from Emailit.
Response:
json
{
"domains": [
{
"id": "domain-id",
"domain": "example.com",
"verification_status": "verified",
"dns_records": [
{
"type": "TXT",
"name": "@",
"value": "verification-string"
}
],
"verified_at": "2025-01-01T00:00:00Z"
}
]
}POST /api/emailit/domains
Add a new domain to Emailit.
Request Body:
json
{
"domain": "example.com"
}Response:
json
{
"domain": {
"id": "domain-id",
"domain": "example.com",
"verification_status": "pending",
"dns_records": [...]
}
}GET /api/emailit/domains/:id/status
Get domain verification status.
Path Parameters:
id(string, required): Domain ID
Response:
json
{
"verification_status": "verified",
"dns_records": [...]
}POST /api/emailit/domains/:id/verify
Trigger domain verification.
Path Parameters:
id(string, required): Domain ID
Response:
json
{
"verification_status": "verified"
}POST /api/emailit/domains/:id/credentials
Create SMTP credentials for verified domain.
Path Parameters:
id(string, required): Domain ID
Request Body:
json
{
"username": "optional-username"
}Response:
json
{
"credential": {
"id": "credential-id",
"username": "smtp-username",
"password": "smtp-password",
"domain_id": "domain-id"
}
}Note: Password is only returned once. Store securely.
GET /api/emailit/credentials
List SMTP credentials.
Response:
json
{
"credentials": [
{
"id": "credential-id",
"username": "smtp-username",
"domain_id": "domain-id",
"is_active": true,
"created_at": "2025-01-01T00:00:00Z"
}
]
}Error Codes
400: Bad Request - Invalid request body or parameters401: Unauthorized - Missing or invalid authentication403: Forbidden - Insufficient permissions404: Not Found - Resource not found429: Too Many Requests - Rate limit exceeded500: Internal Server Error - Server error
Rate Limiting
Email processing is subject to usage limits based on tenant plan:
- Check limits before processing
- Returns
429if limit exceeded - Limits reset per billing period
Webhook Signatures
For webhook endpoints, optional HMAC-SHA256 signature verification:
Header:
x-email-signature: <hmac-sha256-signature>Verification:
- Uses
EMAIL_WEBHOOK_SECRETenvironment variable - Signature computed over raw request body
- Constant-time comparison for security

