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. Everything you need 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.
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) for voice/SMS/WhatsApp. For email, put the recipient email address in this field. |
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. |
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 |
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 |
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}}) |
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 |
Email fields are the same as in Outbound email.
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 message (call, SMS, WhatsApp, or email) |
conversational | phone, sms, wmsg, wvoice | Two-way AI conversation; may connect to a live agent |
confirmational | phone, sms, … | Confirms an existing appointment (booking_id required) |
appointment_booking | phone, sms, … | Books a new appointment using your calendar setup |
Email only supports type: "informational".
Channels
channel | Description |
|---|---|
phone | Outbound voice call |
sms | Outbound SMS conversation |
wmsg | WhatsApp message |
wvoice | WhatsApp voice call |
email | One-shot outbound email |
Outbound email
Set channel to "email" and type to "informational".
Recipient
| API | Recipient field |
|---|---|
POST /integration/start | phone_number = email address |
POST /start | email_address or client_email |
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)
Send the body content only (not full page wrapper). Hub adds your account header, footer, and logo.
{
"channel": "email",
"type": "informational",
"domain_name": "acme",
"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"
}
}
Supported tags include <p>, <strong>, <em>, <br/>, <a href=\"...\">, lists, and headings.
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.
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 HTML and template fields, provide a brief instruction:
{
"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, else instruction, else a default subject |
{{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) |
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 to your account |
| 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 for your domain | Wait or contact Aventora to resume outbound |
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
Document version: June 2026