Dialer integration

Push calls from any dialer into AskElephant, deep-link back to the originating system, and retrieve AI-generated insights

View as Markdown

Overview

The AskElephant public API lets any dialer or call recording system push calls for processing and retrieve AI-generated insights (action items, signals, transcripts) when they are ready. The integration flow is:

  1. Ingest — Your dialer submits a call recording via POST /v2/engagements
  2. Process — AskElephant transcribes the recording and runs AI analysis
  3. Notify — A webhook fires when the transcript is ready
  4. Retrieve — Your system fetches insights via GET /v2/engagements/{id}?expand=action_items,signals

The external_url field on each engagement lets you deep-link from AskElephant back to the call in your dialer’s UI, and from your dialer into the AskElephant engagement.

Prerequisites

  • An AskElephant workspace with API access enabled
  • An API key (sk-apik_<id>.<secret>) — see Authentication
  • A webhook endpoint configured in Settings > Webhooks — see Webhooks
  • Publicly accessible HTTPS URLs for your call recordings

Step 1 — Submit a call recording

When a call ends and a recording is available, submit it to AskElephant:

$curl --request POST \
> --url 'https://app.askelephant.ai/api/v2/engagements' \
> --header 'Authorization: sk-apik_<id>.<secret>' \
> --header 'Content-Type: application/json' \
> --data '{
> "type": "CALL",
> "title": "Sales call with Jane Doe",
> "source_system": "my-dialer",
> "external_id": "call-20260513-001",
> "media_url": "https://recordings.example.com/call-20260513-001.mp3",
> "external_url": "https://my-dialer.example.com/calls/call-20260513-001",
> "run_workflows": true,
> "participants": [
> { "name": "Alice Smith", "email": "alice@example.com", "is_owner": true },
> { "name": "Jane Doe", "email": "jane@customer.com", "phone": "+14155550100" }
> ]
> }'

Request fields

FieldRequiredDescription
typeYesCALL for phone calls, MEETING for video meetings
titleYesDisplay title for the engagement
source_systemYesIdentifier for your dialer (e.g. wavv, my-dialer). Stored as metadata for traceability
external_idYesUnique ID for this call in your system. Used as the workspace-scoped idempotency key — submitting the same external_id again returns the existing engagement
media_urlYesPublicly accessible HTTPS URL to the audio or video recording
external_urlNoURL linking back to this call in your dialer’s UI. Accepts https://, http://, and custom deep-link schemes (e.g. wavv://call/123). Returned in API responses and webhook payloads
run_workflowsYesSet true to enable automation (recap emails, workflow triggers). Set false for historical imports
participantsNoList of call participants with name, email, and/or phone. Mark the agent as is_owner: true
start_atNoISO 8601 timestamp for when the call started. Defaults to the current time
is_privateNoMark the engagement as private (restricted visibility)

Response

1{
2 "object": "engagement",
3 "id": "ngmt_01JWAS...",
4 "title": "Sales call with Jane Doe",
5 "engagement_type": "CALL",
6 "data_source": "PUBLIC_API",
7 "processing_status": "PENDING",
8 "is_internal": false,
9 "is_private": false,
10 "external_url": "https://my-dialer.example.com/calls/call-20260513-001",
11 "engagement_at": "2026-05-13T14:00:00.000Z",
12 "start_at": "2026-05-13T14:00:00.000Z",
13 "owner_user_id": "usr_01JWAS...",
14 "created_at": "2026-05-13T14:00:00.000Z",
15 "updated_at": "2026-05-13T14:00:00.000Z"
16}

Save the id — you will need it to fetch insights later.

Idempotency

The external_id field serves as the workspace-scoped idempotency key. If you submit the same external_id again (even with different field values), the API returns the existing engagement unchanged. This means you can safely retry failed submissions without creating duplicates.

Step 2 — Subscribe to the transcript webhook

In Settings > Webhooks, subscribe to the v1.engagement.transcript_timeline.completed event type. This event fires when the engagement transcript has been processed and is ready for retrieval.

Example webhook payload:

1{
2 "id": "evt_01JWAS...",
3 "type": "v1.engagement.transcript_timeline.completed",
4 "api_version": "v1",
5 "created_at": "2026-05-13T14:15:00.000Z",
6 "workspace_id": "wrks_01JWAS...",
7 "data": {
8 "object": {
9 "object": "engagement",
10 "id": "ngmt_01JWAS...",
11 "title": "Sales call with Jane Doe",
12 "engagement_type": "CALL",
13 "data_source": "PUBLIC_API",
14 "processing_status": "COMPLETED",
15 "external_url": "https://my-dialer.example.com/calls/call-20260513-001",
16 "engagement_at": "2026-05-13T14:00:00.000Z",
17 "start_at": "2026-05-13T14:00:00.000Z",
18 "end_at": "2026-05-13T14:30:00.000Z",
19 "duration_seconds": 1800,
20 "created_at": "2026-05-13T14:00:00.000Z",
21 "updated_at": "2026-05-13T14:15:00.000Z"
22 }
23 }
24}

The data.object is the full engagement, including the external_url you provided at creation time.

Webhook delivery

Webhooks are delivered by Svix with automatic retries and exponential backoff. Your endpoint should:

  • Return a 2xx status within 15 seconds
  • Be idempotent — the same event may be delivered more than once
  • Verify the Svix signature before processing — see Verifying webhook signatures

Step 3 — Retrieve insights

When you receive the v1.engagement.transcript_timeline.completed webhook, fetch the engagement with expanded insights:

$curl --request GET \
> --url 'https://app.askelephant.ai/api/v2/engagements/ngmt_01JWAS...?expand=action_items,signals' \
> --header 'Authorization: sk-apik_<id>.<secret>' \
> --header 'Accept: application/json'

Response with insights

1{
2 "object": "engagement",
3 "id": "ngmt_01JWAS...",
4 "title": "Sales call with Jane Doe",
5 "engagement_type": "CALL",
6 "processing_status": "COMPLETED",
7 "external_url": "https://my-dialer.example.com/calls/call-20260513-001",
8 "action_items": [
9 {
10 "object": "engagement_action_item",
11 "id": "ai_01JWAS...",
12 "title": "Send pricing proposal",
13 "description": "Alice agreed to send the updated pricing proposal to Jane by Friday.",
14 "due_on": "2026-05-16",
15 "assigned_to_user_name": "Alice Smith",
16 "assigned_to_user_email": "alice@example.com",
17 "created_at": "2026-05-13T14:15:00.000Z",
18 "updated_at": "2026-05-13T14:15:00.000Z"
19 }
20 ],
21 "signals": [
22 {
23 "object": "engagement_signal",
24 "id": "sig_01JWAS...",
25 "annotation_definition_id": "adef_01JWAS...",
26 "name": "Budget Discussion",
27 "data_type": "BOOLEAN",
28 "value": true
29 }
30 ],
31 "created_at": "2026-05-13T14:00:00.000Z",
32 "updated_at": "2026-05-13T14:15:00.000Z"
33}

Available expand fields

Expand valueDescription
action_itemsAI-generated action items with assignees and due dates
signalsExtracted signals and annotations
transcriptFull text transcript
contactsContact participants linked to the engagement
companiesCompanies associated via participants
ownerThe workspace user who owns the engagement
media_urlTemporary signed download URL for the recording
tagsTags applied to the engagement

Combine multiple expand fields with commas: ?expand=action_items,signals,transcript

Timing considerations

The v1.engagement.transcript_timeline.completed event fires when the transcript is ready. AI-derived insights (action items, signals) are generated through independent processing pipelines and may still be in progress when the transcript event fires.

Recommended approach: When you receive the webhook, wait 30-60 seconds before fetching insights with ?expand=action_items,signals. If the action_items or signals arrays are empty, retry after a short delay. Most insights are available within 2-3 minutes of transcript completion.

WAVV event mapping

If you are integrating WAVV (or a similar dialer), here is how WAVV call lifecycle events map to AskElephant API calls:

WAVV eventAskElephant actionNotes
CallStartedNo action neededOptionally store the call metadata locally for the later submission
CallEndedNo action neededWait for the recording to be available before submitting
CallRecordedPOST /v2/engagementsSubmit with type: "CALL", the recording URL as media_url, and the WAVV call URL as external_url

WAVV-specific guidance

  • Use "source_system": "wavv" to identify calls from WAVV in AskElephant
  • Set external_id to the WAVV call ID for idempotency (e.g. "wavv-call-12345")
  • Set external_url to the WAVV call detail URL or use a deep-link scheme (e.g. wavv://call/12345) if the WAVV app supports deep linking
  • Map WAVV agent info to the participant with is_owner: true
  • Map the WAVV lead/contact to additional participants with their name, email, and/or phone

Deep linking with external_url

The external_url field creates a bidirectional link between AskElephant and your dialer:

  • Dialer to AskElephant: Your dialer can link to the AskElephant engagement using the engagement id returned in the creation response
  • AskElephant to dialer: The external_url is stored with the engagement and included in all engagement API responses and webhook payloads, letting downstream systems link back to the call in your dialer

The field accepts:

  • Standard URLs: https://my-dialer.example.com/calls/123
  • Custom app deep-link schemes: wavv://call/123, tel:+14155550100

Dangerous schemes (javascript:, data:, vbscript:, blob:, file:) are rejected.

Error handling

HTTP statusMeaningAction
200Idempotent match — engagement already exists for this external_idNo action needed; the existing engagement is returned
201Engagement created successfullyStore the engagement id for later retrieval
400Invalid request bodyCheck required fields and field formats
401Invalid or missing API keyVerify your Authorization header
422Validation error (e.g. blocked URL scheme, invalid media_url)Check the error response for details
429Rate limitedRetry after the delay indicated in the Retry-After header

Complete integration checklist

  1. Obtain an API key from Settings > API Keys
  2. Configure a webhook endpoint in Settings > Webhooks and subscribe to v1.engagement.transcript_timeline.completed
  3. Implement Svix signature verification on your webhook handler
  4. When a call recording is ready, POST /v2/engagements with the recording URL, call metadata, and external_url
  5. When you receive the transcript webhook, fetch GET /v2/engagements/{id}?expand=action_items,signals to retrieve insights
  6. Display insights in your dialer UI alongside the call details