Sending Email
This page covers conversational email — one-to-one messages inside a conversation. For bulk newsletters, see Email Campaigns.
There are a few supported ways to send conversational email through the API, and choosing the right one matters — especially when you need attachments.
Required scopes
| Scope | Purpose |
|---|---|
messages:create | Send email messages |
channels:read | Look up channel and sender options |
Option 1 — Send a message (recommended)
POST /api/v1/messages is the unified send endpoint used by every channel. For email, it sends into the conversation and reuses the conversation's subject.
curl -X POST "https://api.sendseven.com/api/v1/messages" \
-H "Authorization: Bearer s7_api_a1b2c3d4e5f6789012345678abcdef00" \
-H "Content-Type: application/json" \
-d '{
"conversation_id": "conv_email_99",
"text": "Thanks for reaching out — we have received your inquiry and will respond within 24 hours.",
"message_type": "text"
}'
An outbound email needs a subject. Provide one with a subject field, or send into a conversation that already has a subject — SendSeven reuses it (prefixed with Re: for replies). Without either, the send is rejected with EMAIL_SUBJECT_REQUIRED.
# First message on a new email conversation — include the subject
curl -X POST "https://api.sendseven.com/api/v1/messages" \
-H "Authorization: Bearer s7_api_a1b2c3d4e5f6789012345678abcdef00" \
-H "Content-Type: application/json" \
-d '{
"conversation_id": "conv_email_99",
"subject": "Your inquiry",
"text": "Hello! Here is the information you asked for.",
"message_type": "text"
}'
This is the path that supports attachments.
Option 2 — Reply to an inbound email
When a customer has emailed you and you want to reply within that thread (preserving In-Reply-To / References headers, CC list, and quoted history), reply to the specific inbound email message:
curl -X POST "https://api.sendseven.com/api/v1/email-integrations/email-messages/em_12345/reply" \
-H "Authorization: Bearer s7_api_a1b2c3d4e5f6789012345678abcdef00" \
-H "Content-Type: application/json" \
-d '{
"text_body": "Happy to help — here are the next steps.",
"html_body": "<p>Happy to help — here are the next steps.</p>",
"reply_all": false,
"preserve_cc": true
}'
| Field | Type | Description |
|---|---|---|
text_body / html_body | string | Reply body (plain and/or HTML) |
cc_emails / bcc_emails | array | Additional recipients |
preserve_cc | bool | Auto-include the original CC recipients (default true) |
reply_all | bool | Reply to all original recipients |
to_emails | array | Explicit recipient override |
subject_override | string | Override the reply subject (default Re: <original>) |
include_thread_history | bool | Append quoted prior thread beneath the reply |
attachment_ids | array | Attachments to include — see Attachments |
sender_id | string | Sender override from sender-options |
meta | object | Optional, for a reply you translated before sending: {"translations": {"original": "<your text>", "original_language": "de"}, "translated_to": "fr"}. Stored with the sent email so team members can later translate the original. Other keys are ignored. |
This path also supports attachments.
Option 3 — Compose a new email in a conversation
To start a brand-new outbound email (rather than reply to an inbound message) while controlling the subject, CC/BCC and sender explicitly, use the compose endpoint:
curl -X POST "https://api.sendseven.com/api/v1/email-integrations/conversations/conv_email_99/compose-email" \
-H "Authorization: Bearer s7_api_a1b2c3d4e5f6789012345678abcdef00" \
-H "Content-Type: application/json" \
-d '{
"subject": "Your invoice",
"text_body": "Please find your invoice attached.",
"attachment_ids": ["9b3f1a8e-7c2d-4e5b-9f01-12a3b4c5d6e7"]
}'
| Field | Type | Description |
|---|---|---|
subject | string | Required subject line |
text_body / html_body | string | Body (plain and/or HTML) |
to_email | string | Explicit recipient; defaults to the contact's primary email |
cc_emails / bcc_emails | array | Additional recipients |
attachment_ids | array | Attachments to include — see Attachments |
sender_id | string | Sender override from sender-options |
meta | object | Optional translation info, same as on a reply. |
This path supports attachments: attachment_ids takes the same generic attachment IDs the other paths accept, and an ID that does not resolve is rejected with 404 rather than sending the email without the file.
Overriding the sender
Both options accept a sender override. Fetch the available senders for the conversation from GET /api/v1/conversations/{id}/sender-options and pass the id as sender_id. See Mailboxes.
Sender errors
The compose and template endpoints never queue an email that cannot be sent. Instead they return:
| Status | error | Meaning |
|---|---|---|
422 | SENDER_INACTIVE | The sender's email connection is switched off or was deleted. With an explicit sender_id, the request fails rather than sending from a different address. Without one, SendSeven first tries the conversation's other senders and then your Default Support Mailbox, and returns this error only when none of them can send. |
422 | NO_SENDER_ADDRESS | The connection has no verified sender address. |
403 | SENDER_NOT_ALLOWED | You may not send from this sender_id. |
{
"detail": {
"error": "SENDER_INACTIVE",
"message": "The email connection for this sender is switched off or was removed. Switch it back on or choose a different sender.",
"sender_id": "mbx_002"
}
}
To fix it, switch the connection back on, or pick another sender from sender-options. That list only includes senders whose connection is active.
Translate an email
Received and sent emails can be translated on request. This is the Translate button below an email in the app. Call it only on an explicit request from a team member: SendSeven never translates customer emails automatically.
curl -X POST "https://api.sendseven.com/api/v1/email-messages/em_12345/translate" \
-H "Authorization: Bearer s7_api_a1b2c3d4e5f6789012345678abcdef00" \
-H "Content-Type: application/json" \
-d '{"target_language": "en"}'
| Field | Type | Meaning |
|---|---|---|
target_language | string | ISO 639-1 code, optionally with a region (pt-BR). |
source | string | sent (the default) translates the email as sent. original translates the author's original text of a sent email that was written in another language and sent translated (its meta.translations.original, see the reply and compose meta field). |
Only the newest message is translated: quoted earlier messages and the signature are left out, as plain text. Required scope: messages:read. An email in a conversation you cannot open returns 404.
Response 200 (source sent):
{
"original": "Bonjour Madame, merci pour votre message.",
"translated": "Hello Madam, thank you for your message.",
"language": "en",
"message_id": "em_12345",
"truncated": false,
"cached": false
}
Response 200 (source original):
{
"translated": "Hello Madam, thank you for your message.",
"target_language": "en",
"source": "original",
"cached": false,
"message_id": "em_12345",
"truncated": false
}
cached is true when the translation was already stored on the email: no new translation is made. With source original, asking for the original's own language returns the original text with cached true. Translations are stored with the email (at most 8 languages each for the sent text and the original), so every team member gets the same text. Translation is available on Professional, Scale and Enterprise with AI features and Chat Translation switched on. It is free on the workspace's Fast translation level and charged by usage on Advanced (see AI credits).
| Status | Body | When |
|---|---|---|
400 | {"detail": "Email message has no text content to translate"} | source sent and the email has no text. |
403 | {"detail": {"code": "feature_disabled", "feature": "translation"}} | Translation is not available on the plan or is switched off for the workspace. |
404 | {"detail": "Email message not found"} | Unknown email, or a conversation you cannot open. |
413 | {"detail": {"code": "translate_too_large", ...}} | The email is too long to translate in one go. |
422 | {"detail": {"code": "no_original", ...}} | source original on a received email or on a sent email without a stored original. |
422 | {"detail": {"code": "invalid_source", ...}} | source is not sent or original. |
422 | {"detail": {"code": "invalid_language", ...}} | target_language is not a supported language code. |
429 | {"detail": {"code": "translation_rate_limited", ...}} | Too many translations; honour Retry-After. |
Email events
Outbound and inbound email produce dedicated webhook events (email.sent, email.delivered, email.bounced, email.opened, email.complained, email.received). See Webhook Events.
Next steps
- Attachments — send email with files
- Mailboxes — choose the sender identity