Skip to main content

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)โ€‹

FieldTypeRequiredDescription
subjectstringYesEmail subject line (max 255 characters)
body_htmlstringYesRich HTML body (<p>, <strong>, <em>, <ul>, <a>, etc.)
cc_senderbooleanNoWhen true, BCCs the sender (the owner of the API key) if their email is available. Defaults to false.
booking_idintegerNoThe 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.
attachmentsarrayNoEither 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:

PlaceholderReplaced 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โ€‹

StatusMeaning
queuedLog row created, mail has not yet been dispatched
sentMail was handed off to the mail transport successfully
failedMail could not be sent โ€” see failure_reason

Errorsโ€‹

StatusCodeCause
403forbiddenAPI key lacks the customers:write scope, or the customer belongs to a different supplier
404resource_not_foundCustomer ID does not exist
422validation_errorMissing subject or body_html, or invalid attachment
422email_send_failedMail 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"