Aventora Engagement Hub — Start API
This guide explains how to start outbound customer engagements through the Aventora Engagement Hub API: phone calls, SMS, WhatsApp, and email.
You can integrate from your CRM, website backend, or any server that can make HTTPS requests. MCP clients (Cursor, Claude Desktop) can use the same account key against Engagement Hub MCP (POST /mcp) instead of calling these REST paths directly.
Everything you need for REST is in this document.
What you will receive from Aventora
Before integrating, confirm you have:
| Item | Description |
|---|---|
| Hub base URL | Your Engagement Hub API host (e.g. https://phone.aventora.ai or https://phone.aventora.ca). No trailing slash. |
| API key | A secret key tied to your account. Send it on every request. Store it server-side only — never in a browser or mobile app. |
| Domain name | Your tenant slug (e.g. acme). Required on every start request as domain_name. |
Optional (ask your Aventora contact if you need them):
- Webhook URL — your HTTPS endpoint to receive engagement updates when a call or message completes.
- Webhook secret — shared secret; Hub sends it in the
X-Aventora-Webhook-Secretheader so you can verify requests. - Email template IDs — if you use pre-built layouts configured on your account.
- User ID — if your account uses per-agent email branding or routing (
external_user_id).
Your account must have sufficient credits and outbound channels enabled (voice, SMS, email, etc.). Email requires outbound SMTP to be configured on your Aventora account.
Platform partners: If you bill customers directly, configure plans and top-ups with the Engagement Hub Billing API before starting engagements on their accounts.
Authentication
Every request uses your API key as a Bearer token:
Authorization: Bearer <your_api_key>
Content-Type: application/json
Invalid or missing keys return 403 Forbidden.
Recommended flow
For most integrations, use POST /integration/start. It:
- Accepts your request immediately.
- Returns an
engagement_idyou can track. - Starts the call or message in the background.
- Lets you poll status, pause, or cancel the engagement.
Your system Engagement Hub
| |
| POST /integration/start |
|------------------------------------->|
| { engagement_id, status: accepted }|
|<-------------------------------------|
| |
| GET /integration/engagement/{id} | (optional: poll until complete)
|------------------------------------->|
| |
| <-- webhook POST (optional) | (Hub notifies your URL)
Alternative: POST /start is a simpler, direct start that returns a call_sid immediately. Use it for lightweight callbacks when you do not need engagement_id, pause/cancel, or webhooks. Both endpoints are documented below.
Start an engagement
POST /integration/start
URL: {HUB_BASE_URL}/integration/start
Required fields
| Field | Type | Description |
|---|---|---|
phone_number | string | Customer phone in E.164 format (e.g. +14165551234). Required for conversational phone and SMS. For email, prefer email_address for the recipient. phone_number is optional on email and stored as n/a when omitted, including conversational email. Connect-now is skipped when the stored number is n/a. Legacy clients may still send the recipient email in phone_number for non-conversational email. |
domain_name | string | Your tenant domain (provided by Aventora). |
source_record_id | string | Id of the record in your system (contact, lead, case, etc.). |
source_org_id | string | Your organization or workspace id (often the same as domain_name). |
Common optional fields
| Field | Type | Default | Description |
|---|---|---|---|
channel | string | "phone" | phone, sms, wmsg, wvoice, or email |
type | string | "informational" | See Engagement types |
instruction | string | — | What the AI should say or do. Required for most phone/SMS flows; optional for email when using HTML or a template. Unwrapped text is a brief (Hub polishes the first SMS). Wrap the whole string in [...] to send as written. {name} / {firstName} fill the contact first name. See How to write Instructions. |
client_name | string | — | Customer display name |
source_system | string | — | Name of your product (e.g. my_crm) |
source_object | string | — | Record type in your system (e.g. contact, lead) |
source_user_id | string | — | Id of the user in your system who triggered the engagement |
external_user_id | string | — | Aventora user id, if provided for per-agent routing or email settings |
user_phone_number | string | — | Agent/broker phone for conversational engagements |
initiator_phone_number | string | — | Same as user_phone_number |
email_address | string | — | Recipient email for channel: "email". Preferred over putting the email in phone_number. |
notify_call_request | boolean | false | Conversational SMS only. When true, customer agreement to connect sends a call-request secure-link SMS to user_phone_number instead of a live Twilio conference. Completes with outcome call_requested. |
test_mode | boolean | false | When true, no live call or email is sent (for testing) |
context | object | — | Optional JSON stored with the engagement; email fields may be nested here |
Email-only fields
May be sent at the top level or inside context:
| Field | Type | Description |
|---|---|---|
email_subject | string | Email subject line. Optional: if omitted, Hub writes a subject from the engagement instruction and type. Saved templates with their own subject pattern still use that pattern. |
email_body_html | string | HTML body with {{PLACEHOLDER}} tags — see Outbound email |
email_template_id | string | Id of a saved email template on your account |
email_template_name | string | Template name (if you do not use email_template_id) |
email_template_params | object | Values for custom placeholders (e.g. policy_number → {{POLICY_NUMBER}}) |
from_name | string | Optional From display name (the name recipients see). Overrides account From Name for this send. CRM sets this to Profile name, default initiator, or workspace display name. |
email_attachments | array | Optional image files the recipient downloads. Each item is { "filename", "content_type", "data_base64" }. JPEG, PNG, GIF, or WebP. At most 5 images, 4 MB each, 8 MB combined. Ignored when channel is not email. |
Success response
HTTP 200
{
"status": "accepted",
"engagement_id": "eng_a1b2c3d4e5f6789012345678",
"created_at": "2026-06-18T14:30:00.000Z"
}
Save engagement_id to track, pause, cancel, or correlate with webhooks.
Example — outbound phone call
POST https://phone.aventora.ai/integration/start
Authorization: Bearer <your_api_key>
Content-Type: application/json
{
"phone_number": "+14165551234",
"domain_name": "acme",
"source_record_id": "contact-98765",
"source_org_id": "acme",
"source_system": "my_crm",
"channel": "phone",
"type": "informational",
"instruction": "Confirm tomorrow's appointment and offer to reschedule if needed.",
"client_name": "Alex Morgan"
}
Example — SMS conversation
{
"phone_number": "+14165551234",
"domain_name": "acme",
"source_record_id": "lead-123",
"source_org_id": "acme",
"channel": "sms",
"type": "conversational",
"instruction": "The customer asked about 42 Main St. Offer to connect them with an agent.",
"user_phone_number": "+14165559999",
"client_name": "Jordan Lee"
}
Example — email with inline HTML
{
"phone_number": "customer@example.com",
"domain_name": "acme",
"source_record_id": "contact-456",
"source_org_id": "acme",
"channel": "email",
"type": "informational",
"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>Questions? Reply to this email.</p><p>Regards,<br/>{{ORGANIZATION_NAME}}</p>",
"email_template_params": {
"policy_number": "POL-2026-8842",
"renewal_date": "June 15, 2026"
}
}
Example — email with a saved template
{
"phone_number": "customer@example.com",
"domain_name": "acme",
"source_record_id": "contact-456",
"source_org_id": "acme",
"channel": "email",
"type": "informational",
"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"
}
}
Direct start (optional)
POST /start
URL: {HUB_BASE_URL}/start
Use when you only need to fire a single call or message and receive a call_sid back. You do not get an engagement_id or built-in pause/cancel.
Contact field by channel
| Channel | How to pass the customer |
|---|---|
phone, sms, wmsg, wvoice | phone_number (E.164; US 10-digit numbers are normalized to +1…) |
email | email_address or client_email |
Common fields
| Field | Default | Description |
|---|---|---|
domain_name | — | Your tenant domain |
channel | phone | phone, sms, wmsg, wvoice, email |
type | informational | See Engagement types |
instruction | — | Script or brief |
language | en | en, es, fr, de, pt, zh, fa, ar, hi, ja, ko |
client_name | — | Customer name |
scheduled_time | now | ISO 8601 UTC datetime to schedule for later |
user_phone_number | — | Agent phone (conversational) |
booking_id | — | Required when type is confirmational |
test_mode | false | Test run without live send |
afterHoursQuestions | null | Optional pre-call questionnaire: a list of { id, prompt, expected }. expected is a regular expression (.+ accepts any non-empty answer). Null or [] leaves the call unchanged. Hub asks on the same channel as the engagement: spoken on a phone or WhatsApp voice call, SMS for SMS, WhatsApp for a WhatsApp message, and email for email. A closed-office phone call that continues by text asks on that text. Answers are stored beside the call exactly as the customer said or wrote them (the full reply, not only the part that matched). expected only checks the reply: when it does not match, Hub asks once more, keeps the latest reply, and moves on. Spoken numbers such as "fifty seven" count as digits when checking. A skip ("I don't know") leaves the answer blank. Answers do not change status, outcome, or scheduling. |
questionnaireWhen | after_hours | after_hours asks only while the call center is closed. always asks on every call, including during open hours. Ignored when afterHoursQuestions is null or empty. |
Email fields are the same as in Outbound email.
Example — pre-call questionnaire
{
"phone_number": "+14165551234",
"domain_name": "acme",
"type": "conversational",
"channel": "phone",
"instruction": "Follow up on the website form submission.",
"questionnaireWhen": "after_hours",
"afterHoursQuestions": [
{
"id": "vin",
"prompt": "What is the vehicle VIN?",
"expected": "[A-HJ-NPR-Z0-9]{17}"
},
{
"id": "license",
"prompt": "What is the driver's license number?",
"expected": ".+"
}
]
}
You may send fields flat or nested under body:
{
"phone_number": "+14165551234",
"domain_name": "acme",
"type": "informational",
"body": {
"instruction": "Leave a voicemail about Saturday's open house."
}
}
Success response
{
"call_sid": "CA1234567890abcdef",
"status": "call_initiated",
"phone_number": "+14165551234",
"billing_request_id": "CA1234567890abcdef"
}
If the agent is busy or the engagement is scheduled for later, you may receive a queued response:
{
"call_sid": "QUEUED_uuid",
"status": "queued",
"message": "Call queued for scheduled time: 2026-06-18T15:00:00Z",
"scheduled_time": "2026-06-18T15:00:00Z"
}
Example — scheduled phone callback
{
"phone_number": "+14165551234",
"domain_name": "acme",
"type": "conversational",
"channel": "phone",
"instruction": "Follow up on the website form submission.",
"scheduled_time": "2026-06-19T14:30:00Z",
"client_name": "Alex Morgan"
}
Engagement types
type | Channels | What it does |
|---|---|---|
informational | All, including email | Delivers a one-way first message (call, SMS, WhatsApp, or email). On phone, the opening greets the customer and speaks the instruction immediately (Deepgram Voice Agent and Pipecat). On SMS and email, a later customer reply upgrades the engagement to conversational. |
conversational | phone, sms, wmsg, wvoice, email | Two-way AI conversation; may connect to a live agent. Phone and SMS require a customer phone_number. Email does not. For SMS, set notify_call_request: true to SMS the agent a call request instead of bridging. |
confirmational | phone, sms, … | Confirms an existing appointment (booking_id required) |
appointment_booking | phone, sms, … | Books a new appointment using your calendar setup |
Email supports informational first-message sends and interactive types including conversational. A reply to informational email continues on the same thread.
Channels
channel | Description |
|---|---|
phone | Outbound voice call |
sms | Outbound SMS conversation |
wmsg | WhatsApp message |
wvoice | WhatsApp voice call |
email | Outbound email (informational first message or interactive conversational) |
Outbound email
Set channel to "email". Use type: "informational" for a first-message send that can continue if the customer replies, or type: "conversational" (and other interactive types) to start already in a two-way flow.
Recipient
| API | Recipient field |
|---|---|
POST /integration/start | email_address (preferred). Legacy: phone_number = email address. Optional customer phone in phone_number when email_address is set. |
POST /start | email_address or client_email. Optional customer phone in phone_number. |
How the email body is built
Use exactly one of these approaches per request:
| Priority | Field | Description |
|---|---|---|
| 1 | email_body_html | Your HTML with {{PLACEHOLDER}} tags |
| 2 | email_template_id or email_template_name | A template saved on your account |
| 3 | instruction | A short brief; Hub generates a simple HTML paragraph |
Important: Do not send email_body_html together with email_template_id or email_template_name. The API returns 400 if both are provided.
Inline HTML (email_body_html)
email_body_html is the full HTML document Hub sends after replacing {{PLACEHOLDER}} tags. Include <style>, layout tables, and optional <html>/<body> as needed. Hub does not wrap this in account header, footer, or logo. Saved templates still use branding wrap.
{
"channel": "email",
"type": "informational",
"domain_name": "acme",
"email_address": "customer@example.com",
"client_name": "Alex Morgan",
"email_subject": "Your policy renewal",
"email_body_html": "<style>body {margin: 0;}</style><body><p>Dear {{CUSTOMER_NAME}},</p><p>Policy <strong>{{POLICY_NUMBER}}</strong> renews on {{RENEWAL_DATE}}.</p><p>Regards,<br/>{{ORGANIZATION_NAME}}</p></body>",
"email_template_params": {
"policy_number": "POL-2026-8842",
"renewal_date": "June 15, 2026"
}
}
Supported tags include <style>, <html>, <body>, <p>, <strong>, <em>, <br/>, <a href=\"...\">, lists, headings, and tables. Email clients may still strip <script>.
When email_body_html is present, instruction is not used to generate the body. It may still influence the subject if email_subject is omitted. Bulk JSON/CSV rows with email_body_html are replayed onto POST /start with that field intact.
Saved template
List templates on your account:
GET {HUB_BASE_URL}/account-settings/email-templates?domain_name=acme
Authorization: Bearer <your_api_key>
Example response:
{
"templates": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Policy renewal",
"subjectTemplate": "Your policy renewal",
"customPlaceholderKeys": ["POLICY_NUMBER", "RENEWAL_DATE"]
}
]
}
Start with the template id:
{
"channel": "email",
"type": "informational",
"domain_name": "acme",
"email_address": "customer@example.com",
"email_template_id": "550e8400-e29b-41d4-a716-446655440000",
"email_subject": "Your policy renewal",
"email_template_params": {
"policy_number": "POL-2026-8842",
"renewal_date": "June 15, 2026"
}
}
Example template body (as stored on your account):
<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>
AI-generated body from instruction
If you omit email_subject, Hub writes a short inbox subject from instruction and type. Pass email_subject only when you want to override that.
{
"channel": "email",
"type": "informational",
"domain_name": "acme",
"email_address": "customer@example.com",
"client_name": "Alex Morgan",
"email_subject": "Update on your claim",
"instruction": "Let the customer know their claim was received and review will take 3-5 business days.",
"language": "en"
}
Placeholders
Built-in (set automatically — do not pass these in email_template_params):
| Placeholder | Source |
|---|---|
{{SUBJECT}} | email_subject if provided; otherwise a subject Hub writes from the engagement instruction and type |
{{CUSTOMER_NAME}} | client_name, else recipient email, else "Customer" |
{{ORGANIZATION_NAME}} | Your organization name on the account |
Custom — pass in email_template_params:
| Request key | Placeholder in HTML/subject |
|---|---|
policy_number | {{POLICY_NUMBER}} |
renewal_date | {{RENEWAL_DATE}} |
agent_name | {{AGENT_NAME}} |
Rules:
- Keys: letters, digits, underscore; must start with a letter.
- Values are converted to strings; empty values are skipped.
- Placeholders work in subject, body, and header/footer branding.
Manage email templates (API)
| Method | Path | Purpose |
|---|---|---|
| GET | /account-settings/email-templates | List templates |
| POST | /account-settings/email-templates | Create template |
| PUT | /account-settings/email-templates | Update template |
| DELETE | /account-settings/email-templates | Delete template |
| POST | /account-settings/send-test-email | Send a test message |
Include domain_name in the query string or body. Add external_user_id if your account uses per-user templates.
Track an engagement
After POST /integration/start, use the returned engagement_id.
Get status
GET {HUB_BASE_URL}/integration/engagement/{engagement_id}
Authorization: Bearer <your_api_key>
Example response
{
"engagement_id": "eng_a1b2c3d4e5f6789012345678",
"status": "In Progress",
"outcome": null,
"summary": null,
"started_at": "2026-06-18T14:30:05.000Z",
"completed_at": null,
"channel": "phone",
"type": "informational",
"contact_identifier": "+14165551234",
"history": [
{
"started_at": "2026-06-18T14:30:05.000Z",
"status": "In Progress",
"event_type": "Scheduled",
"call_outcome": null
}
],
"transcript": [
{
"role": "assistant",
"content": "Hi Alex, this is a reminder about your appointment tomorrow.",
"timestamp": "2026-06-18T14:30:12.000Z"
}
],
"delivery_type": "pull",
"event_type": "engagement.updated",
"sent_at": "2026-06-18T14:35:00.000Z"
}
Poll until status indicates completion (e.g. Completed, Failed, Cancelled) or until completed_at is set.
Pause
POST {HUB_BASE_URL}/integration/pause
Authorization: Bearer <your_api_key>
Content-Type: application/json
{
"engagement_id": "eng_a1b2c3d4e5f6789012345678"
}
Cancel
POST {HUB_BASE_URL}/integration/cancel
Authorization: Bearer <your_api_key>
Content-Type: application/json
{
"engagement_id": "eng_a1b2c3d4e5f6789012345678"
}
Both return:
{
"ok": true,
"engagement_id": "eng_a1b2c3d4e5f6789012345678"
}
Webhooks (optional)
Instead of polling, ask Aventora to register your HTTPS endpoint. When an engagement finishes or updates, Hub POSTs a JSON payload to your URL.
Verify requests: compare the X-Aventora-Webhook-Secret header to the secret Aventora gives you.
Typical payload fields:
| Field | Description |
|---|---|
engagement_id | Same id returned from /integration/start |
status | Current status (e.g. Completed, Failed) |
outcome | Result label when available |
summary | Short text summary of the engagement |
started_at / completed_at | ISO timestamps |
history | Attempt and status events |
transcript | Conversation messages (role, content, timestamp). Outgoing email messages may also include email_status (sent, delivered, opened, bounced, failed), email_sent_at, email_delivered_at, and email_opened_at. |
event_type | Usually engagement.updated |
sent_at | When this payload was sent |
Use engagement_id to match the webhook to the record in your system (source_record_id from your start request).
Error responses
| HTTP | Meaning | What to do |
|---|---|---|
| 400 | Invalid request (missing field, bad email, template conflict, email not configured on account) | Fix the request body; confirm email/SMTP is set up on your account |
| 402 | Insufficient credits | Add credits via Engagement Hub Billing API (partners) or your Aventora contact |
| 403 | Invalid API key, or contact is on Do Not Call / Do Not Email list | Check key; verify the customer can be contacted |
| 404 | Domain not found or not linked to your account | Confirm domain_name with Aventora |
| 422 | Required field missing on /integration/start | Include phone_number, domain_name, source_record_id, source_org_id |
| 503 | Engagements paused; phone start outside assigned user's call hours (OUTSIDE_WORKING_HOURS); Hub rate limit (RATE_LIMIT_DEFERRED); or Twilio REST unreachable (TWILIO_UNREACHABLE_DEFERRED) | Wait and retry. Rate-limit and Twilio-unreachable starts are re-queued for one hour and are not marked Failed. After-hours phone starts are not marked delivered and are not billed. |
Error bodies are JSON with a detail field describing the problem.
Testing
Set "test_mode": true on your start request to validate integration without placing a live call or sending a real email. Hub returns success responses with test identifiers.
Always test from your server, not from a browser, so your API key stays private.
Checklist
- Call
POST /integration/startwithtest_mode: truefor each channel you use. - Confirm you receive
engagement_idand canGET /integration/engagement/{id}. - Test email with
email_body_htmland with a template id. - Test pause and cancel on a queued engagement.
- If using webhooks, confirm your endpoint receives a test payload from Aventora.
- Repeat with
test_mode: falsefor one real contact per channel.
Quick reference
| Action | Method | Path |
|---|---|---|
| Start engagement | POST | /integration/start |
| Get status | GET | /integration/engagement/{engagement_id} |
| Pause | POST | /integration/pause |
| Cancel | POST | /integration/cancel |
| Direct start | POST | /start |
| List email templates | GET | /account-settings/email-templates?domain_name=… |
All requests: Authorization: Bearer <your_api_key> and Content-Type: application/json on POST bodies.
Support
For API keys, domain setup, webhook registration, email templates, credit, or channel enablement, contact your Aventora account representative.
When reporting an issue, include:
engagement_idorcall_siddomain_name- Timestamp (UTC)
- HTTP status and response body from Hub
- Channel and
typeused
Changelog
| Date | Change |
|---|---|
| 2026-10-04 | Email delivery and opens: Webhook and engagement-status transcripts for outgoing email include email_status, email_sent_at, email_delivered_at, and email_opened_at. The first open and a bounce send engagement.updated. |
| 2026-09-29 | afterHoursQuestions answers are stored in full. |
| 2026-09-28 | email_attachments: Optional image files on email /start, /integration/start, and once on POST /bulk-calls/submit (stored on the batch, not on every row). JPEG, PNG, GIF, or WebP. At most 5 images, 4 MB each, 8 MB combined. System, Google, Microsoft, and SMTP attach them as files. |
| 2026-09-26 | afterHoursQuestions follows the engagement channel. Phone and WhatsApp voice ask on the call before connect. SMS, WhatsApp message, and email send on that channel. A closed-office phone fallback that already switched to text keeps the questions on that text. |
| 2026-09-25 | Conversational email can start without a customer phone_number. Hub stores n/a and skips connect-now until a phone exists. Phone and SMS conversational still require a customer phone. |
| 2026-09-24 | The first message includes the greeting and the questionnaire together. Email lists every question in that first email. SMS, phone, and WhatsApp include the greeting and the first question in the same message. |
| 2026-09-24 | A cancelled, done, failed, incomplete, or blocked engagement no longer treats a later customer text as a questionnaire answer. The reply follows the normal engagement path. |
| 2026-09-24 | questionnaireWhen: after_hours (default) or always on POST /start and on Email Pull. always asks the same side questionnaire during open hours. Read answers under Engagement Hub → Questionnaire. |
| 2026-09-23 | afterHoursQuestions: Optional on POST /start and on Email Pull configurations (copied onto each start that configuration creates). Collected on a side SMS or email. Read answers under Engagement Hub → Questionnaire. |
| 2026-09-19 | Partner bulk From name: Queued bulk /start applies row or campaign from_name and initiator external_user_id so API bulk email matches UI From. CRM API-key bulk falls back to workspace display name. |
| 2026-09-18 | Bulk email from_name: Hub ingest now copies row from_name onto the queued engagement so CRM/API bulk email uses the same From display name as /integration/start. |
| 2026-09-17 | Informational email replies: Informational /start email sets Reply-To and opens an email session. A customer reply reopens the engagement and upgrades it to conversational. |
| 2026-09-16 | Appointment email booking: Availability for today starts from now. If a booking is rejected, the same reply includes remaining times instead of promising a later email. Offered slots stay on the email session so a later “book that time” reply can complete the calendar booking. |
| 2026-09-16 | Appointment email replies: When the customer asks for the next available time, Hub looks up calendar slots instead of asking them to pick a date. Replies sign off with the organization name. System/SES omits CID logos; platform SMTP includes a plain-text part to reduce Gmail Promotions placement. |
| 2026-09-16 | Email subject from the engagement: If email_subject is omitted, Hub writes the inbox subject from instruction and engagement type. Header/footer branding is unchanged. An explicit email_subject or a saved template subject pattern still wins. |
| 2026-09-16 | Conversational email sends immediately: /start does not wait on voice call hours for email. Call hours apply later only when Hub places the connect-now conference. |
| 2026-09-16 | Conversational phone required: Every conversational start (including email) must include a real customer phone_number. Hub returns 400 if it is missing or a placeholder such as n/a, and stores the number on call_logs.phone_number. |
| 2026-09-16 | Conversational email connect-now: Keep the customer phone_number on email starts. When the customer replies they are ready, Hub places the conference call. email_address is the preferred recipient field on /integration/start. Quoted reply threads are stripped from the transcript. |
| 2026-09-16 | from_name: Optional From display name on /integration/start, /start, and bulk email rows. Overrides Hub From Name for that send. CRM-originated email sets this to the user's Profile full name. |
| 2026-09-15 | instruction markup: Wrap the whole string in [...] to send as written. Unwrapped text stays a brief. {name} and related {field} tokens fill from client_name. See How to write Instructions. |
| 2026-09-14 | Inline HTML is the full document: email_body_html is sent as-is after placeholder fill (no Hub branding wrap). Bulk queue replay copies email_body_html onto POST /start. |
| 2026-09-02 | Twilio REST 502/503 (or connection failure) on SMS/call create returns 503 with detail.error=TWILIO_UNREACHABLE_DEFERRED and re-queues the engagement for one hour instead of marking it Failed. |
| 2026-09-02 | Timeout-deferred phone retries wait for the next still-open call hours (not now+1min). Queued Hub retries do not SMS-fallback after hours; morning opening still sends when call hours are open. |
| 2026-08-25 | Informational phone /start greets the customer and delivers instruction in the first spoken turn on both Deepgram Voice Agent and Pipecat. |
| 2026-08-25 | Immediate phone /start uses the assigned user's call hours. After-hours rejection is 503 with detail.error=OUTSIDE_WORKING_HOURS and does not mark the engagement delivered or charge credits. |
| 2026-08-18 | Claude Custom Connectors authenticate to Hub MCP with mcp:tools OAuth tokens. Those tokens are not Hub API keys and cannot call /integration/start. See Engagement Hub MCP. |
| 2026-08-18 | MCP: named Hub tools at POST /mcp wrap these REST APIs. See Engagement Hub MCP. |
| 2026-07-14 | notify_call_request: Optional boolean on /integration/start and /start for conversational SMS. When true, customer agreement to connect sends a secure callback-request SMS to user_phone_number instead of a live conference; engagement completes with outcome call_requested. |
Document version: July 2026