Customer Emails
Send a custom (rich-text) email to a customer directly via the API. The email is rendered in your supplier's branded template and logged to customer_email_logs for auditing.
This is the same pathway used by the in-app Send email offcanvas on the customer detail page, the MCP tool send_customer_email, and the AI assistant โ so every entry point produces identical behaviour.
Send Custom Emailโ
Endpointโ
POST /v1/customers/{id}/email
Authenticationโ
Requires an API key with the customers:write scope.
Request Body (JSON)โ
| Field | Type | Required | Description |
|---|---|---|---|
subject | string | Yes | Email subject line (max 255 characters) |
body_html | string | Yes | Rich HTML body (<p>, <strong>, <em>, <ul>, <a>, etc.) |
cc_sender | boolean | No | When true, BCCs the sender (the owner of the API key) if their email is available. Defaults to false. |
booking_id | integer | No | The booking this email is about. Pass it and the email appears on that booking's Messages tab in the app. The booking must belong to the same supplier; an id that does not returns 404. |
attachments | array | No | Either multipart file uploads (up to 10 files, 10MB each, 25MB total) or an array of { filename, content (base64), mime } objects. |
Placeholdersโ
Both subject and body_html support the following placeholders, replaced at send time:
| Placeholder | Replaced with |
|---|---|
{customer_name} | Customer's first + last name |
{first_name} | Customer's first name |
{last_name} | Customer's last name |
{business_name} | Your business name |
{supplier_name} | Your business name (alias of business_name) |
Attachment Restrictionsโ
- Max files: 10 per email
- Max file size: 10MB each
- Max total size: 25MB across all attachments
- Blocked extensions:
.exe,.bat,.cmd,.com,.sh,.ps1,.msi,.vbs,.js,.jar,.php,.phtml,.pl,.py,.rb,.asp,.aspx, and similar executable/scripting formats
Example Request (JSON, no attachments)โ
curl -X POST "https://app.equipdash.com/api/v1/customers/123/email" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "Thanks for your recent rental",
"body_html": "<p>Hi {first_name},</p><p>Thanks again for renting with us โ we hope you had a great time.</p>",
"cc_sender": false
}'
Example Request (about a specific booking)โ
Pass booking_id when the email concerns one booking. It then shows on that
booking's Messages tab alongside the confirmation and reminders.
curl -X POST "https://app.equipdash.com/api/v1/customers/123/email" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "Your gear is ready for pickup",
"body_html": "<p>Hi {first_name}, everything is packed and ready from 9am.</p>",
"booking_id": 4821
}'
Example Request (multipart, with attachment)โ
curl -X POST "https://app.equipdash.com/api/v1/customers/123/email" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "subject=Your invoice" \
-F "body_html=<p>Hi {first_name}, here is your invoice.</p>" \
-F "cc_sender=true" \
-F "attachments[]=@/path/to/invoice.pdf"
Example Request (JSON with base64 attachment)โ
curl -X POST "https://app.equipdash.com/api/v1/customers/123/email" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "Receipt attached",
"body_html": "<p>Receipt for your last visit is attached.</p>",
"attachments": [
{
"filename": "receipt.pdf",
"content": "JVBERi0xLjQK...",
"mime": "application/pdf"
}
]
}'
Response (201 Created)โ
{
"data": {
"id": 42,
"customer_id": 123,
"booking_id": null,
"supplier_id": 7,
"subject": "Thanks for your recent rental",
"body_html": "<p>Hi Sarah,</p><p>Thanks again for renting with us โ we hope you had a great time.</p>",
"body_text": "Hi Sarah, Thanks again for renting with us โ we hope you had a great time.",
"cc_sender": false,
"attachments": [],
"status": "sent",
"failure_reason": null,
"sent_at": "2026-04-18T10:30:00+00:00",
"sent_by_user_id": null,
"sent_via_api_key_id": 11,
"created_at": "2026-04-18T10:30:00+00:00",
"updated_at": "2026-04-18T10:30:00+00:00"
},
"meta": {
"request_id": "req_abc123",
"timestamp": "2026-04-18T10:30:00+00:00"
}
}
Status Fieldโ
| Status | Meaning |
|---|---|
queued | Log row created, mail has not yet been dispatched |
sent | Mail was handed off to the mail transport successfully |
failed | Mail could not be sent โ see failure_reason |
Errorsโ
| Status | Code | Cause |
|---|---|---|
| 403 | forbidden | API key lacks the customers:write scope, or the customer belongs to a different supplier |
| 404 | resource_not_found | Customer ID does not exist |
| 422 | validation_error | Missing subject or body_html, or invalid attachment |
| 422 | email_send_failed | Mail transport error or the customer has no email address |
Use Casesโ
Post-Rental Thank Youโ
Trigger from your webhook on booking.completed:
curl -X POST "https://app.equipdash.com/api/v1/customers/{{ customer_id }}/email" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "How was your rental, {first_name}?",
"body_html": "<p>Hi {first_name},</p><p>Thanks for choosing {business_name}! We'\''d love to hear how it went โ reply to this email with any feedback.</p>"
}'
Balance Reminderโ
Chain after a balance_outstanding check:
curl -X POST "https://app.equipdash.com/api/v1/customers/{{ customer_id }}/email" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"subject": "Friendly reminder โ balance owing on your booking",
"body_html": "<p>Hi {first_name},</p><p>Just a quick note that your booking still has an outstanding balance. You can settle up anytime at <a href=\"https://app.equipdash.com/bookings/123/pay\">this link</a>.</p>",
"cc_sender": true
}'
Proactive Check-in with Attachmentโ
curl -X POST "https://app.equipdash.com/api/v1/customers/{{ customer_id }}/email" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "subject=Your gear is ready โ map attached" \
-F "body_html=<p>Hi {first_name}, your gear is ready. Map to our pickup location attached.</p>" \
-F "attachments[]=@./pickup-map.pdf"