Aventora CRM ↔ Hub outbound email templates
How aventora-crm Quick Aventora / Engage by Aventora uses Engagement Hub outbound email templates configured in aventora-admin.
Audience: CRM admins, integrators, workflow authors.
Related docs:
- Engagement Hub Start API — canonical client guide (start + email inline HTML)
- Outbound Email — Hub
POST /startemail internals, placeholders, SMTP - Aventora User Manual — §2.5 (Engage by Aventora), §3.11.1 (Admin Outbound Email)
- Aventora CRM ↔ Hub — CRM ↔ Hub engagement lifecycle, webhooks
Two different “template” concepts
| CRM Quick Aventora templates | Hub outbound email templates | |
|---|---|---|
| Where defined | Built into CRM (aventora-message-templates.ts) | aventora-admin → Account Settings → Outbound Email |
| Purpose | Build instruction text (phone/SMS/email brief) | HTML email body + subject + branding |
| Placeholders | {{firstName}}, meeting fields, etc. | {{CUSTOMER_NAME}}, {{SUBJECT}}, {{ORGANIZATION_NAME}}, optional {{POLICY_NUMBER}}, … |
| Storage | CRM repo | Hub data/email_templates/{domain}.json |
They work together for email:
- CRM quick template → instruction (always sent).
- Hub layout (optional) → branded HTML + SMTP send when
emailTemplateIdis set.
Architecture
Prerequisites
| Layer | Requirement |
|---|---|
| Admin | Outbound Email: SMTP tested, at least one email template, branding optional |
| Hub | Deployed build with email field pass-through on /integration/start and /start |
| CRM server | AVENTORA_BASE_URL in environment |
| CRM workspace | AVENTORA_API_KEY, assigned domain (Settings → Applications) |
| CRM user | Initiator phone on profile; person has email (and name for {{CUSTOMER_NAME}}) |
CRM REST API
All paths are under the CRM API host (same origin as the CRM app in typical deployments). Authenticate with the workspace member JWT used for other Aventora REST calls.
GET /rest/aventora/email-templates
Lists Hub layouts for the workspace domain.
Response:
{
"templates": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Policy renewal",
"subjectTemplate": "Your policy renewal — {{SUBJECT}}",
"customPlaceholderKeys": ["POLICY_NUMBER", "RENEWAL_DATE"]
}
]
}
customPlaceholderKeys— placeholders found in subject/body excludingSUBJECT,CUSTOMER_NAME,ORGANIZATION_NAME.- Empty
templates— often means SMTP/email not configured for the domain on Hub.
POST /rest/aventora/start-engagement
When channel is email and type is informational:
| Field | Maps to Hub | Purpose |
|---|---|---|
personId | source_record_id | Person UUID |
contactIdentifier | recipient | Email address |
instruction | instruction | Brief (required unless emailBodyHtml or a Hub template is provided) |
clientName | client_name | {{CUSTOMER_NAME}} (optional; server uses person name if omitted) |
emailSubject | email_subject | Subject + {{SUBJECT}} |
emailBodyHtml | email_body_html | Inline HTML body (mutually exclusive with template id/name) |
emailTemplateId | email_template_id | Hub template UUID |
emailTemplateName | email_template_name | Alternative to id |
emailTemplateParams | email_template_params | e.g. { "policy_number": "POL-99" } → {{POLICY_NUMBER}} |
Example:
{
"personId": "uuid-of-person",
"channel": "email",
"type": "informational",
"instruction": "Policy renewal reminder",
"contactIdentifier": "customer@example.com",
"clientName": "Alex Morgan",
"emailSubject": "Your policy renewal",
"emailTemplateId": "550e8400-e29b-41d4-a716-446655440000",
"emailTemplateParams": {
"policy_number": "POL-2026-8842",
"renewal_date": "June 15, 2026"
}
}
Hub also accepts the same fields on POST /integration/start and POST /start (snake_case) for non-CRM integrators.
GET /rest/aventora/person-views
Lists Person views the caller can see in the workspace (workspace-shared views for API keys; plus the member’s unlisted views when using a user JWT).
Response:
{
"views": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Policy renewals",
"type": "TABLE",
"visibility": "WORKSPACE"
}
]
}
Use a returned id as viewId on bulk start. The CRM applies that view’s filters at send time (current matching People, not a snapshot).
POST /rest/aventora/start-engagement-bulk
Same email fields as start-engagement. Recipients are exactly one of: an explicit list, every eligible Person, or a Person view — never combine them.
| Recipients | Body |
|---|---|
| Some contacts | personIds: array of Person UUIDs (max 1000) |
| All contacts | "audience": "all" (do not send personIds or viewId) |
| Person view | viewId: UUID from GET /rest/aventora/person-views (optional "audience": "view") |
Missing personIds does not mean all. CRM loads People (from the ids, the whole workspace, or the view filters), skips do not contact and missing email (for channel: "email"), chunks Hub submits at 1000 rows, and returns aggregated counts. View audiences are not capped at 1000 People — CRM pages and chunks like audience: "all".
All-contacts example:
{
"audience": "all",
"channel": "email",
"type": "informational",
"emailSubject": "Your policy renewal",
"emailBodyHtml": "<p>Dear {{CUSTOMER_NAME}},</p><p>Policy reminder.</p>"
}
Some-contacts example:
{
"personIds": ["uuid-1", "uuid-2"],
"channel": "email",
"type": "informational",
"emailSubject": "Your policy renewal",
"emailTemplateId": "550e8400-e29b-41d4-a716-446655440000",
"emailTemplateParams": {
"policy_number": "POL-2026-8842"
}
}
Person-view example:
{
"viewId": "550e8400-e29b-41d4-a716-446655440000",
"channel": "email",
"type": "informational",
"emailSubject": "Your policy renewal",
"emailTemplateId": "550e8400-e29b-41d4-a716-446655440000",
"emailTemplateParams": {
"policy_number": "POL-2026-8842"
}
}
Response:
{
"batchId": "batch-1",
"batchIds": ["batch-1", "batch-2"],
"matchedCount": 1502,
"queuedCount": 1480,
"skippedCount": 22,
"errors": ["uuid-dnc: do not contact"]
}
batchId— first Hub batch (backward compatible).batchIds— one id per Hub chunk when the audience is larger than 1000.matchedCount— People considered (personIdslength, all People foraudience: "all", or People matchingviewId).skippedCount— CRM skips (do not contact / missing email) plus Hub skips.
Do not send emailBodyHtml together with emailTemplateId / emailTemplateName.
Integration context (alternative)
{
"phone_number": "customer@example.com",
"domain_name": "aventora",
"source_record_id": "...",
"source_org_id": "...",
"channel": "email",
"type": "informational",
"instruction": "...",
"context": {
"email_template_id": "...",
"email_template_params": { "policy_number": "POL-99" }
}
}
Quick Aventora UI (shipped)
When Channel = Email in Engage by Aventora:
- Email layout (Engagement Hub) — dropdown from
GET /rest/aventora/email-templates. - Email subject — required when a layout is selected.
- Template fields — one input per
customPlaceholderKey. - Instruction — from CRM quick template (unchanged).
Optional developer mapping on CRM quick templates (aventora-message-templates.ts):
hubEmailTemplateName— pre-select Hub layout by name when templates load.defaultEmailSubject— initial subject when pre-selecting.
Without a layout, send still works (instruction-only / Hub LLM path). See Outbound Email send paths.
Configuration
CRM server
| Variable | Required | Description |
|---|---|---|
AVENTORA_BASE_URL | Yes | Hub base URL (e.g. https://hub.example.com) |
CRM workspace (UI)
| Application variable | Required | Description |
|---|---|---|
AVENTORA_API_KEY | Yes | Account Hub API key |
| Assigned domain | Yes | Domain slug for Hub |
CRM frontend (optional)
| Variable | Default |
|---|---|
REACT_APP_AVENTORA_EMAIL_TEMPLATES_ENDPOINT | {REACT_APP_SERVER_BASE_URL}/rest/aventora/email-templates |
REACT_APP_AVENTORA_START_ENDPOINT | {SERVER}/rest/aventora/start-engagement |
Override these only in local development. In production the CRM injects the server base URL automatically — leave email-templates unset to use the default path on the same host.
Workflows
Built-in CRM workflow actions (preferred):
- Send Email (Engagement Hub) — informational email for a Person (
personId+ subject/body or Hub template). Executes HubPOST /integration/startwithchannel=emailandtype=informational. - Aventora Engagement / Bulk Engagement — phone, SMS, or email with a Cockpit action type dropdown and a multiline Instruction prefilled from that action (editable); when channel is Email, configure subject, HTML body, or Hub layout template (same fields as Engage by Aventora).
Advanced / custom HTTP (still supported):
- HTTP request step →
POST {CRM_SERVER}/rest/aventora/start-engagementwith person id from trigger + email fields above. - Map workflow variables into
emailTemplateParams. - Confirm Aventora CRM workflow auth can call workspace REST (Bearer token model).
Sender for all Hub email paths is Engagement Hub → Outbound Email (System SMTP, Google, or Microsoft)—not CRM connected-account Gmail send scopes.
Troubleshooting
| Symptom | Check |
|---|---|
| Layout dropdown empty | Admin Outbound Email + SMTP; workspace API key and domain |
| 403 on list/start | AVENTORA_API_KEY, AVENTORA_BASE_URL, APP_SECRET if key is encrypted |
| Layout selected, send fails | Hub logs; template id exists; all template fields filled |
| Wrong customer name | Person name on record; or pass clientName explicitly |
| Placeholder not replaced | Use {{UPPER_SNAKE}} in Hub template; pass snake_case keys in emailTemplateParams |
| Person-views list empty | Create a workspace-visible People view in CRM; API keys do not see unlisted/personal views |
| viewId send fails | Confirm the id is from GET /rest/aventora/person-views; view must be on Person, not Company |
Documentation map
| Doc | Content |
|---|---|
| Engagement Hub Start API | Canonical client guide — /integration/start, /start, email_body_html |
| Outbound Email | Hub email internals, placeholders, branding |
| Aventora User Manual | End-user Engage + Admin setup |
| This file | CRM REST + UI + config |
| Aventora CRM ↔ Hub | Engagements, pause, webhooks |
Deploy order
- Aventora-Assistant —
/integration/start+/startemail fields,email_addressfor email channel. - aventora-crm —
GET /rest/aventora/email-templates,GET /rest/aventora/person-views, start-engagement pass-through, Engage UI, workflow Send Email (Engagement Hub) + Start Engagement email fields. - aventora-admin — template authoring (unchanged; source of truth).
Changelog
| Date | Change |
|---|---|
| 2026-08-23 | Person view audience: GET /rest/aventora/person-views lists Person views. POST /rest/aventora/start-engagement-bulk accepts viewId (mutually exclusive with personIds and "audience": "all"). CRM applies the view filters at send time, skips do-not-contact / missing email, and chunks Hub submits at 1000. |
| 2026-08-20 | Bulk email to all contacts: POST /rest/aventora/start-engagement-bulk accepts "audience": "all" (mutually exclusive with personIds). CRM resolves People, skips do-not-contact / missing email, and chunks Hub submits at 1000. REST start/bulk action pass emailBodyHtml through to Hub. |
| 2026-08-17 | Aventora Engagement / Bulk Engagement workflow steps use a cockpit action type dropdown and a multiline instruction field prefilled from the selected action. |
| 2026-07-31 | Documented built-in workflow actions for Hub informational email (Send Email + Start/Bulk Engagement email fields). |