Engagement Hub — Outbound email (technical)
Technical reference for informational outbound email via the Hub POST /start API, email templates, placeholders, and branding.
Audience: Integrators, bulk workers, CRM custom apps, automation engineers.
Canonical client guide: ENGAGEMENT_HUB_START_API.md — share with clients; includes /integration/start, /start, and full email_body_html documentation. Update that file when email start fields change.
Related user guide: AVENTORA_USER_MANUAL.md — §3.11 Account Settings (Outbound Email tab).
Overview
| Layer | Responsibility |
|---|---|
| aventora-admin | SMTP settings, header/footer/logo branding, template library (account + optional per-user) |
| Aventora-Assistant (Hub) | POST /start with channel: "email", template resolution, placeholder fill, SMTP send |
| domain-chatbot | Domain logo asset (GET /stats/logo/{domain_name}) when “Include domain logo” is enabled |
Email channel supports type: "informational" only. The call is marked Done after a successful one-shot SMTP send (no voice/SMS session).
Prerequisites
- Outbound SMTP configured in Admin → Engagement Hub → Account Settings → Outbound Email.
domain_nameon the/startrequest must match the tenant domain.- Hub API key with permission to initiate calls (
/start). - Engagement hub not paused (
engagement_hub_paused).
Optional: per-user SMTP/branding/templates when outbound_email_user_overrides_enabled is true and user_id is sent.
POST /start — email + informational
Authentication: Authorization: Bearer <hub_api_key>
Required fields
| Field | Description |
|---|---|
channel | "email" |
type | "informational" |
domain_name | Tenant slug (e.g. aventora) |
email_address or client_email | Recipient (validated format) |
Common optional fields
| Field | Description |
|---|---|
user_id | Hub user id — per-user SMTP/templates/branding when overrides enabled |
client_name | {{CUSTOMER_NAME}} (fallback: recipient email) |
email_subject | Subject line and {{SUBJECT}} value |
instruction | See Send paths below |
email_body_html | Inline HTML body with {{PLACEHOLDER}} tags (mutually exclusive with email_template_id / email_template_name) |
email_template_id | UUID of a saved template (Admin or API) |
email_template_name | Template name if id omitted |
email_template_params | Object of extra placeholder values (this document) |
language | ISO-ish code; used only when no template (LLM body), default en |
Fields may be top-level or nested under body (Hub accepts both).
Legacy alias
template_params is accepted as an alias for email_template_params.
Placeholders
Built-in (always set by Hub)
| Placeholder | Source |
|---|---|
{{SUBJECT}} | email_subject, else instruction, else "Message from your provider" |
{{CUSTOMER_NAME}} | client_name, else recipient email, else "Customer" |
{{ORGANIZATION_NAME}} | Account setting organization_name for the domain |
Built-in keys cannot be overridden via email_template_params.
Optional extra parameters (email_template_params)
Pass a JSON object on /start. Each key becomes an uppercase placeholder:
| Request key | Placeholder in template |
|---|---|
policy_number | {{POLICY_NUMBER}} |
renewal_date | {{RENEWAL_DATE}} |
agent_name | {{AGENT_NAME}} |
Rules:
- Keys must match
^[A-Za-z][A-Za-z0-9_]*$(letters, digits, underscore; must start with a letter). - Values are converted to strings; empty strings are skipped.
- Reserved keys
SUBJECT,CUSTOMER_NAME,ORGANIZATION_NAMEinemail_template_paramsare ignored. - Substitution runs in template subject, template body, and branding header/footer HTML.
Example request
{
"channel": "email",
"type": "informational",
"domain_name": "aventora",
"email_address": "customer@example.com",
"client_name": "Alex Morgan",
"email_subject": "Your policy renewal",
"email_template_id": "550e8400-e29b-41d4-a716-446655440000",
"email_template_params": {
"policy_number": "POL-2026-8842",
"renewal_date": "June 15, 2026",
"agent_name": "Jamie Lee"
}
}
Example template body snippet:
<p>Dear {{CUSTOMER_NAME}},</p>
<p>Policy <strong>{{POLICY_NUMBER}}</strong> renews on {{RENEWAL_DATE}}.</p>
<p>Your advisor {{AGENT_NAME}} can answer any questions.</p>
<p>Best regards,<br/>{{ORGANIZATION_NAME}}</p>
Send paths
Conflict rule: do not send email_body_html together with email_template_id or email_template_name — Hub returns 400.
A — Inline HTML (email_body_html)
fill_email_templatereplaces placeholders inemail_body_htmlandemail_subject(subject defaults to{{SUBJECT}}when omitted).instructionis not used for body generation (may still affect{{SUBJECT}}fallback whenemail_subjectis omitted).- Wrap with branding (header, footer, CID inline logo).
- SMTP send.
B — Template selected (email_template_id or email_template_name)
- Load template from
data/email_templates/{domain}.json(or per-user file if applicable). fill_email_templatereplaces all placeholders (built-in +email_template_params).instructiondoes not generate the body; it only affects{{SUBJECT}}whenemail_subjectis omitted.- Wrap with branding (header, footer, CID inline logo).
- SMTP send.
If the template is not found, Hub falls through to path C.
C — No inline HTML or template (or template not found)
instructionis treated as a brief.- LLM (
expand_instruction_to_email_body) writes a short plain-text paragraph. - Wrapped in
<p>…</p>, subject fromemail_subjector default. - Branding wrap still applies;
email_template_paramsstill fill header/footer placeholders only.
Example — inline HTML
{
"channel": "email",
"type": "informational",
"domain_name": "aventora",
"email_address": "customer@example.com",
"client_name": "Alex Morgan",
"email_subject": "Your policy renewal",
"email_body_html": "<p>Dear {{CUSTOMER_NAME}},</p><p>Policy <strong>{{POLICY_NUMBER}}</strong> renews on {{RENEWAL_DATE}}.</p><p>Regards,<br/>{{ORGANIZATION_NAME}}</p>",
"email_template_params": {
"policy_number": "POL-2026-8842",
"renewal_date": "June 15, 2026"
}
}
Bulk CSV uploads may include an email_body_html column for channel=email rows (no instruction required when inline HTML or a template reference is present).
Priority when sources are present: email_body_html → saved template → instruction (LLM). Only one body source per request; inline HTML and template id/name cannot be combined.
Branding
Configured in Admin → Outbound Email (account or per-user):
- Custom header HTML
- Custom footer HTML
- Domain logo and/or custom logo URL
Templates store body content only; branding wraps every outbound send.
Logo is attached as an inline CID image for email client compatibility.
Template storage API (Hub)
Proxied via aventora-admin for browser users; integrators may call Hub directly with the account API key.
| Method | Hub path | Purpose |
|---|---|---|
| GET | /account-settings/email-templates | List templates |
| POST | /account-settings/email-templates | Create |
| PUT | /account-settings/email-templates | Update |
| DELETE | /account-settings/email-templates | Delete |
| GET | /account-settings/email-template-catalog | System library |
| POST | /account-settings/send-test-email | SMTP + template test |
Query/body may include external_user_id when using user-scoped templates.
Call log behavior
phone_numberis stored asn/afor email channel.- Status moves to Done with outcome delivered after successful SMTP.
- Failed SMTP → Failed with reason.
Errors (common)
| HTTP | Meaning |
|---|---|
| 400 | Missing email, invalid type/channel combo, missing domain_name, unknown template (if strictly required by caller) |
| 400 | SMTP not configured |
| 403 | DNC / auth |
| 503 | Engagement hub paused |
CRM (Twenty / Quick Aventora)
User guide: AVENTORA_USER_MANUAL.md §2.5, §3.11.1. CRM integration detail: CRM_OUTBOUND_EMAIL_TEMPLATES.md.
CRM does not store Hub templates. It lists layouts from Hub and passes selections on start.
UI flow
- Person → Engage by Aventora → informational quick template.
- Channel =
email. - CRM calls
GET /rest/aventora/email-templates(workspace JWT). - User picks Email layout, subject, and dynamic template fields.
- CRM calls
POST /rest/aventora/start-engagement→ HubPOST /integration/start→ internalPOST /start.
CRM REST — list templates
Authentication: CRM workspace JWT (Authorization: Bearer …).
| Method | Path | Response |
|---|---|---|
| GET | /rest/aventora/email-templates | { templates: [{ id, name, subjectTemplate, customPlaceholderKeys }] } |
Server proxies Hub GET /account-settings/email-templates?domain_name=… using the workspace application variable AVENTORA_API_KEY (account-scoped Hub key). Requires outbound email configured for the domain (SMTP); otherwise Hub may return 400 and CRM returns an empty list.
CRM REST — start with layout
Authentication: CRM workspace JWT.
| CRM JSON field | Hub /integration/start → /start |
|---|---|
clientName | client_name → {{CUSTOMER_NAME}} |
emailSubject | email_subject → {{SUBJECT}} |
emailBodyHtml | email_body_html (mutually exclusive with template id/name) |
emailTemplateId | email_template_id |
emailTemplateName | email_template_name |
emailTemplateParams | email_template_params (keys → {{KEY}}) |
personId, channel, type, instruction, contactIdentifier behave as for phone/SMS. For email, contactIdentifier is the recipient address. If clientName is omitted, twenty-server derives it from the person name fields when present.
CRM server environment
| Variable | Where | Purpose |
|---|---|---|
AVENTORA_BASE_URL | twenty-server .env | Hub root URL for /integration/start and template proxy |
AVENTORA_API_KEY | CRM workspace application settings | Bearer token for Hub (per account) |
| Assigned domain | CRM workspace application settings | domain_name for Hub |
CRM frontend environment (optional)
| Variable | Default |
|---|---|
REACT_APP_AVENTORA_EMAIL_TEMPLATES_ENDPOINT | {REACT_APP_SERVER_BASE_URL}/rest/aventora/email-templates |
Usually unset when CRM UI and API share one host. Override only for split-domain deployments.
Workflows
Use POST /rest/aventora/start-engagement with the same JSON body and workflow-appropriate auth. Map workflow variables into emailTemplateParams. No dedicated Aventora workflow action ships in the repo today.
Version note
email_template_params— custom placeholders on informational email sends.- CRM UI +
GET /rest/aventora/email-templates— Quick Aventora email layout picker (aventora-crmmain).
Documented in ENGAGEMENT_HUB_START_API.md (canonical), this file, AVENTORA_USER_MANUAL.md §2.5 / §3.11.1, and CRM_OUTBOUND_EMAIL_TEMPLATES.md.