Skip to main content

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:

ItemDescription
Hub base URLYour Engagement Hub API host (e.g. https://phone.aventora.ai or https://phone.aventora.ca). No trailing slash.
API keyA secret key tied to your account. Send it on every request. Store it server-side only — never in a browser or mobile app.
Domain nameYour 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-Secret header 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.


For most integrations, use POST /integration/start. It:

  1. Accepts your request immediately.
  2. Returns an engagement_id you can track.
  3. Starts the call or message in the background.
  4. 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

FieldTypeDescription
phone_numberstringCustomer phone in E.164 format (e.g. +14165551234) for voice/SMS/WhatsApp. For email, put the recipient email address in this field.
domain_namestringYour tenant domain (provided by Aventora).
source_record_idstringId of the record in your system (contact, lead, case, etc.).
source_org_idstringYour organization or workspace id (often the same as domain_name).

Common optional fields

FieldTypeDefaultDescription
channelstring"phone"phone, sms, wmsg, wvoice, or email
typestring"informational"See Engagement types
instructionstringWhat the AI should say or do. Required for most phone/SMS flows; optional for email when using HTML or a template.
client_namestringCustomer display name
source_systemstringName of your product (e.g. my_crm)
source_objectstringRecord type in your system (e.g. contact, lead)
source_user_idstringId of the user in your system who triggered the engagement
external_user_idstringAventora user id, if provided for per-agent routing or email settings
user_phone_numberstringAgent/broker phone for conversational engagements
initiator_phone_numberstringSame as user_phone_number
test_modebooleanfalseWhen true, no live call or email is sent (for testing)
contextobjectOptional JSON stored with the engagement; email fields may be nested here

Email-only fields

May be sent at the top level or inside context:

FieldTypeDescription
email_subjectstringEmail subject line
email_body_htmlstringHTML body with {{PLACEHOLDER}} tags — see Outbound email
email_template_idstringId of a saved email template on your account
email_template_namestringTemplate name (if you do not use email_template_id)
email_template_paramsobjectValues 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

ChannelHow to pass the customer
phone, sms, wmsg, wvoicephone_number (E.164; US 10-digit numbers are normalized to +1…)
emailemail_address or client_email

Common fields

FieldDefaultDescription
domain_nameYour tenant domain
channelphonephone, sms, wmsg, wvoice, email
typeinformationalSee Engagement types
instructionScript or brief
languageenen, es, fr, de, pt, zh, fa, ar, hi, ja, ko
client_nameCustomer name
scheduled_timenowISO 8601 UTC datetime to schedule for later
user_phone_numberAgent phone (conversational)
booking_idRequired when type is confirmational
test_modefalseTest 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

typeChannelsWhat it does
informationalAll, including emailDelivers a one-way message (call, SMS, WhatsApp, or email)
conversationalphone, sms, wmsg, wvoiceTwo-way AI conversation; may connect to a live agent
confirmationalphone, sms, …Confirms an existing appointment (booking_id required)
appointment_bookingphone, sms, …Books a new appointment using your calendar setup

Email only supports type: "informational".


Channels

channelDescription
phoneOutbound voice call
smsOutbound SMS conversation
wmsgWhatsApp message
wvoiceWhatsApp voice call
emailOne-shot outbound email

Outbound email

Set channel to "email" and type to "informational".

Recipient

APIRecipient field
POST /integration/startphone_number = email address
POST /startemail_address or client_email

How the email body is built

Use exactly one of these approaches per request:

PriorityFieldDescription
1email_body_htmlYour HTML with {{PLACEHOLDER}} tags
2email_template_id or email_template_nameA template saved on your account
3instructionA 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):

PlaceholderSource
{{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 keyPlaceholder 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)

MethodPathPurpose
GET/account-settings/email-templatesList templates
POST/account-settings/email-templatesCreate template
PUT/account-settings/email-templatesUpdate template
DELETE/account-settings/email-templatesDelete template
POST/account-settings/send-test-emailSend 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:

FieldDescription
engagement_idSame id returned from /integration/start
statusCurrent status (e.g. Completed, Failed)
outcomeResult label when available
summaryShort text summary of the engagement
started_at / completed_atISO timestamps
historyAttempt and status events
transcriptConversation messages (role, content, timestamp)
event_typeUsually engagement.updated
sent_atWhen 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

HTTPMeaningWhat to do
400Invalid 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
402Insufficient creditsAdd credits to your account
403Invalid API key, or contact is on Do Not Call / Do Not Email listCheck key; verify the customer can be contacted
404Domain not found or not linked to your accountConfirm domain_name with Aventora
422Required field missing on /integration/startInclude phone_number, domain_name, source_record_id, source_org_id
503Engagements paused for your domainWait 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

  1. Call POST /integration/start with test_mode: true for each channel you use.
  2. Confirm you receive engagement_id and can GET /integration/engagement/{id}.
  3. Test email with email_body_html and with a template id.
  4. Test pause and cancel on a queued engagement.
  5. If using webhooks, confirm your endpoint receives a test payload from Aventora.
  6. Repeat with test_mode: false for one real contact per channel.

Quick reference

ActionMethodPath
Start engagementPOST/integration/start
Get statusGET/integration/engagement/{engagement_id}
PausePOST/integration/pause
CancelPOST/integration/cancel
Direct startPOST/start
List email templatesGET/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_id or call_sid
  • domain_name
  • Timestamp (UTC)
  • HTTP status and response body from Hub
  • Channel and type used

Document version: June 2026