AI Bot Vendor - Dialer Requirements (Beta)

Wants to integrate your platform with Dialer?

This guide is for customers who want to connect their own AI voice bot to the CommPeak Dialer (instead of using a managed available engines). It is the full integration contract. The contract is vendor-neutral: any bot that satisfies it will work.

Your bot has two responsibilities:

A. Accept a SIP call from the dialer and read the per-call context we attach as custom SIP headers

B. Call two dialer webhooks during the call - one to transfer to a human, one to end the call with a disposition

📘

Onboarding is done with CommPeak

There is no self-serve "custom bot" setup yet. Build your bot to this contract, then contact your CommPeak account manager. We register your engine and provide: the dialer source IPs to allowlist, your webhook URL + Bearer token, your account's status codes, and confirm your concurrency limit (it becomes the Bot Flow channel count)

How it fits together

A predictive campaign dials a lead; when a live person answers, the dialer bridges the call to your bot with the lead's context attached to the INVITE.

sequenceDiagram
  participant D as CommPeak Dialer
  participant B as Your AI bot
  D->>B: SIP INVITE sip:{number}@{your host} + X-* headers
  B-->>D: 200 OK (answer the call)
  Note over B: Bot runs the qualifying conversation
  Note over D,B: Every webhook carries Authorization Bearer + call_id (= X-Dialer-Call-Id)
  alt Lead asks for a human
    B->>D: POST /transfer  { call_id, summary }
    D-->>B: { result: "<line to speak>" }
    D->>D: Bridge the lead to an available human in its group
  else Call is ending
    B->>D: POST /hangup  { call_id, status_code, comment, next_call_at }
    D-->>B: { result: ok }
    D->>B: SIP BYE (dialer ends the call)
    opt Your side hangs up first
      B->>D: SIP BYE (optional)
    end
  end

Part A - Receiving the call (SIP)

Dial target

The dialer originates sip:{number}@{host}:

  • {number}: the E.164 phone number you bind to the bot. This is the inbound routing key (route the call by the dialed number), not the bot/assistant ID
  • {host}: your SIP host, e.g. sip.example.com:5060;transport=tcp.

You give CommPeak the host and number at onboarding, and you must allowlist the dialer's FreeSWITCH source IPs (we provide them) so your SIP endpoint accepts our INVITE

Per-call context headers

The dialer attaches lead and call context as custom X-… SIP headers on the INVITE. Read them off the incoming SIP message (most bot platforms expose SIP headers as variables).

HeaderCarriesExample
X-Dialer-Call-IdCall-correlation id - you MUST echo this back as call_id on every webhooka UUID
X-Tenant-IdAccount (tenant) id42
X-Lead-IdLead id99812
X-Lead-First-NameLead first nameJane
X-Lead-Last-NameLead last nameDoe
X-Lead-PhoneLead phone+15551234567
X-Campaign-IdCampaign id7
X-Campaign-NameCampaign nameQ3 Outreach
X-OIYour CRM's original identifiercrm-8821
X-Lead-Local-TimeThe lead's local wall-clock time (Y-m-d H:i)2026-06-30 14:05
X-Lead-TimezoneThe lead's GMT-offset labelGMT+3

Nullable fields are sent as empty strings, not omitted.

🚧

Use the lead's local time for callbacks

When the lead asks for a callback, compute the time against X-Lead-Local-Time/X-Lead-Timezone - never your bot's own clock - then send it as next_call_at (see Part B)

Inbound calls

If you also accept inbound calls (a caller dialing in via an IVR), the INVITE adds:

HeaderCarries
X-Sourceinbound
X-DIDThe number the caller dialed
X-Caller-NumberThe caller's number
X-Lead-MatchedWhether the caller matched a known lead

When no lead is matched, the dialer accepts only these reserved status_code values on hangup (recorded for reporting only): INBOUND_RESOLVED, INBOUND_NO_RESOLUTION, INBOUND_TRANSFERRED, INBOUND_ABANDONED.

Part B - Calling the Dialer webhooks

Endpoints

Both are POST, Content-Type: application/json. {engine} and {bot_flow_id} are filled into the full URL we give you at onboarding.

POST  /integrations/aibot/{engine}/transfer/{bot_flow_id}
POST  /integrations/aibot/{engine}/hangup/{bot_flow_id}

Authentication

Send the per-engine token as a Bearer header on every request:

Authorization: Bearer <your-webhook-token>

It's verified in constant time; a missing or blank token is rejected with HTTP 401. (No request-body HMAC signature is required.)

Correlation & idempotency

Every webhook body must include:

  • call_id (required): exactly the X-Dialer-Call-Id you received on the SIP INVITE. This is how the dialer ties the webhook to the live call and lead.
  • engine_event_id (recommended): a stable per-conversation id of yours. The dialer dedupes on (call_id, action, engine_event_id) for 24h, so a retry of the same webhook is safely ignored. Omit it and no dedupe happens.

Transfer to a human

POST /integrations/aibot/{engine}/transfer/{bot_flow_id}

FieldRequiredMeaning
call_idYesThe correlation ID
summaryYesA short recap shown to the human who receives the call
engine_event_idRecommendedAI Engine call ID/UUID

You don't pick a target - the dialer bridges the lead to an available human in the lead's predictive group. Keep the lead on the line; the dialer un-bridges your leg and runs the human search.

Response: { "result": "<a short line to speak to the caller>" } (e.g. "Transferring you now, please hold."). Some integrations return { "result": "ok" } - speak your own hold line in that case.

End the call (hangup)

POST /integrations/aibot/{engine}/hangup/{bot_flow_id}

FieldRequiredMeaning
call_idYesThe correlation ID
status_codeYesThe disposition for the lead - one of your account's status codes (see below)
commentNoOne-sentence outcome, saved as a comment on the lead
next_call_atNoCallback time in ISO-8601 with UTC offset, e.g. 2026-06-17T20:00:00+03:00. Blank, past, or unparseable values are ignored. Stored as UTC
summaryNoConversation summary
engine_event_idRecommendedAI Engine call ID/UUID

An unknown/unmapped status_code applies the campaign's default status and returns HTTP 400 with { "error": "..." }.

Response: { "result": "ok" }. After processing hangup, the dialer sends a SIP BYE and ends the call - make sure your SIP endpoint handles it gracefully. You can also send your own BYE as soon as hangup succeeds (whichever side's BYE lands first ends the call), but it's optional. Calling hangup more than once is unnecessary.

Status codes

Your valid status_code values are provided by CommPeak at setup - they map to your account's lead statuses. Treat the set as a fixed enum and have your model pick from it. Codes are not sent per call.

Part C - What your Bot must implement

Concretely, your bot needs:

  1. A transfer_to_human action → POST …/transfer with summary + the correlation envelope + Bearer. Trigger it only when the lead explicitly asks for a human now.
  2. A hangup action → POST …/hangup with status_code (+ optional comment, next_call_at, summary) + the correlation envelope + Bearer. Trigger it when the call is ending.
  3. A call-termination step - after hangup succeeds, the dialer sends a SIP BYE to end the call; handle it gracefully. Sending your own BYE first is optional. Don't call hangup twice.

Part D - Vendor API Access the Dialer needs

To connect your vendor account as an AI Engine and import a bot as a Bot Flow, the Dialer calls your vendor account's API directly. The API key you provide must allow the reads below - without them the Engine cannot be created and bots cannot be imported.

API credentials

What the Dialer needsWhy
API base URLAll reads/writes below are sent here
API key / tokenAuthenticates the Dialer against your account
📘

NOTE

Credentials are stored encrypted and are never exposed back in the UI (masked on edit; leave blank to keep the stored value).

Connectivity test

The Engine's Test connection runs these read probes - all must return successfully before the Engine can be used:

Bot list

The bot must already exist on your vendor account - the Dialer never authors bots. When creating a Bot Flow, the Dialer enumerates your account's bots to build the import list:

Bots already imported into another Bot Flow are hidden from the list (one Bot Flow per vendor bot).

Max concurrent calls (outbound channels)

A Bot Flow's Outbound Channels (simultaneous calls - one AI Agent is created per channel) is validated against the bot's concurrency limit on the vendor side:

Your account-level Dialer limits (max concurrent AI agents, AI-per-human ratio) always apply on top.

Auto-provisioning write access ("Set it for me")

If you use the recommended one-click setup, the same API key must also allow creating/updating on your account: the webhook tools attached to the bot and the SIP phone number binding - plus, per vendor: Vapi - the BYO SIP trunk credential (POST /credential) and the assistant update; ElevenLabs - the webhook secret (POST /v1/convai/secrets) and the agent workflow update. If your key is read-only, choose "I'll set it up myself" and follow the post-save guide instead.

Integration checklist

  • SIP endpoint answers sip:{number}@{host} and the dialer's source IPs are allow listed.

  • Bot reads X-Dialer-Call-Id and the X-Lead-*/X-Campaign-* context headers.

  • Callback times are computed from X-Lead-Local-Time/X-Lead-Timezone.

  • Webhooks send Authorization: Bearer <token> and call_id (= X-Dialer-Call-Id).

  • hangup always sends a valid status_code; the bot handles the dialer's BYE that follows (its own BYE is optional).

  • transfer sends a useful summary for the receiving human.

  • (Inbound) handles X-Source=inbound context and the reserved INBOUND_* codes.

  • API key created with the scopes above and pasted into the AI Engine.

  • Test connection passes (all probes green).

  • The bot exists on the vendor account before creating the Bot Flow.

  • Bot concurrency on the vendor covers the Outbound Channels you plan to set.

✔️ Build to this contract, then contact CommPeak to onboard your bot.


Did this page help you?