ReferenceReference by module

Voice API

Every Voice action (22) and data model (3): endpoints, scopes, input, preconditions, events and examples.

Your Eras answer the phone and your website by voice, book, take messages and file every call in the Inbox.

Module code voice · 22 actions · 3 data models · 13 events. A key or token never does more here than the person behind it can; row-level security applies exactly as in the app. Scopes: voice (everything), voice:read (read only) or voice:<capability>.

Resources

ResourceTableList and readPOSTPATCHDELETE
voice_agentsvoice_agent/api/v1/voice_agentsvoice.update
voice_callsvoice_call/api/v1/voice_calls
voice_whatsapp_linesvoice_whatsapp_line/api/v1/voice_whatsapp_lines

Lists take limit (up to 200), cursor, order (e.g. -created_at), fields and q; every other query parameter is a column filter: ?status=paid, ?total[gte]=100, ?id[in]=a,b, ?x=null.

Actions

ActionNeedsWhat it does
voice.answer_permissionvoice:handleThe customer answered the call permission
voice.await_permissionvoice:handleWait for the customer’s permission to call
voice.complete_callvoice:handleFile a finished call
voice.connect_whatsappvoice:manageAnswer WhatsApp calls
voice.connect_whatsapp_callvoice:handleEra picked up a WhatsApp call
voice.decide_whatsapp_callvoice:writeAnswer a ringing WhatsApp call with Era, or let it ring
voice.enablevoice:manageGive an Era a voice
voice.fail_callvoice:handleA call did not happen
voice.mark_dialedvoice:handleA call was placed
voice.open_callvoice:handleA call began
voice.record_syncvoice:handleRecord the voice provider’s answer
voice.record_turnvoice:handleRecord what Era did on a call
voice.record_whatsappvoice:handleRecord whether WhatsApp calls are on
voice.removevoice:deleteTake an Era’s voice away
voice.set_enabledvoice:manageSwitch an Era’s voice on or off
voice.set_outcomevoice:writeCorrect a call’s outcome
voice.set_whatsapp_linevoice:manageAnswer WhatsApp calls on my computer
voice.start_callvoice:writeHave Era call someone
voice.start_whatsapp_callvoice:writeCall someone on WhatsApp with Era
voice.take_over_whatsapp_callvoice:writeTake the WhatsApp call over from Era
voice.updatevoice:manageChange an Era’s voice
voice.whatsapp_ringvoice:handleA WhatsApp call is ringing on the computer

voice.answer_permission

The customer answered the call permission — Allowed: the call is placed now. Declined: it is cancelled and nothing is charged. Machine-only.

Needs voice:handle · changes data

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/voice_calls/{id}/actions/answer_permission
API key or OAuth token · voice:handle
  • Canonical address: POST /api/v1/actions/voice.answer_permission

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Call · id of voice_call
grantedbooleanyesAllowed

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_awaitingOnly a call waiting for permission takes the answer.

Events it publishes: voice.call_missed

What it writes: voice_call (update) — awaiting → queued (allowed) or cancelled (declined, released)

Errors: 401 no or expired credential · 403 the credential does not hold voice:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_awaiting · 429 slow down

voice.await_permission

Wait for the customer’s permission to call — WhatsApp lets a business call only someone who allowed it: the request went out, the call waits for their answer. Machine-only.

Needs voice:handle · changes data

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/voice_calls/{id}/actions/await_permission
API key or OAuth token · voice:handle
  • Canonical address: POST /api/v1/actions/voice.await_permission

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Call · id of voice_call
requestIdstringPermission request message · max 200

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_queuedOnly a queued WhatsApp call waits for permission.

What it writes: voice_call (update) — queued → awaiting permission

Errors: 401 no or expired credential · 403 the credential does not hold voice:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_queued · 429 slow down

voice.complete_call

File a finished call — Writes the transcript, summary, outcome and length, meters the real minutes on your own voice key and tells workflows. Machine-only.

Needs voice:handle · reaches outside (sends, publishes or charges)

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/voice_calls/{id}/actions/complete_call
API key or OAuth token · voice:handle
  • Canonical address: POST /api/v1/actions/voice.complete_call

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Call · id of voice_call
transcriptobject / arrayTranscript
summarystringSummary · max 4000
durationSecnumberyesLength (seconds) · min 0 · max 14400
endReasonstringHow it ended · max 200
transferredbooleanPut through to a person
externalIdstringProvider call · max 120
fromNumberstringFrom · max 40
toNumberstringTo · max 40
conversationIduuidInbox conversation · id of conversation
customerIduuidCustomer · id of customer
recordingbooleanHas a recording
recordingFileIduuidRecording file
languagestringLanguage · max 8
providerActionsobject / arrayProvider actions

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
call_not_foundThe call must exist here.
call_finishedA call is filed once.

Events it publishes: voice.call_finished, voice.appointment_booked, voice.lead_captured, voice.message_taken, voice.transfer_requested, voice.whatsapp_call_finished

What it writes: voice_call (update) — → completed, with transcript, outcome and cost

Errors: 401 no or expired credential · 403 the credential does not hold voice:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 call_not_found, call_finished · 429 slow down

voice.connect_whatsapp

Answer WhatsApp calls — The Era answers voice calls on your WhatsApp Business number too, and files each one in that customer’s WhatsApp chat.

Needs voice:manage · reaches outside (sends, publishes or charges)

POSThttps://app.getera.io/api/v1/voice_agents/{id}/actions/connect_whatsapp
API key or OAuth token · voice:manage
  • Canonical address: POST /api/v1/actions/voice.connect_whatsapp

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Voice · id of voice_agent
inboxIduuidWhatsApp number (Inbox channel) · id of inbox

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
voice_not_foundThe voice must exist here.
inbox_not_whatsappCalls come to an active WhatsApp Cloud API channel.
whatsapp_takenOne Era answers one WhatsApp number.

Events it publishes: voice.agent_changed

What it writes: voice_agent (update) — Points the WhatsApp line at the Era (pending until Meta and the voice provider take it)

curl -X POST https://app.getera.io/api/v1/voice_agents/VOICE_AGENT_ID/actions/connect_whatsapp \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"inboxId":"INBOX_ID"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "voice.agent_changed"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.voiceAgents.connectWhatsapp("VOICE_AGENT_ID", {
  inboxId: "INBOX_ID"
})
era voice_agents connect_whatsapp VOICE_AGENT_ID \
  --inbox-id "INBOX_ID"
tools/call
{
  "name": "era__voice__connect_whatsapp",
  "arguments": {
    "id": "VOICE_AGENT_ID",
    "inboxId": "INBOX_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold voice:manage · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 voice_not_found, inbox_not_whatsapp, whatsapp_taken · 429 slow down

voice.connect_whatsapp_call

Era picked up a WhatsApp call — The computer answered (or placed) the WhatsApp call and the voice is connected — minutes and money checked first. Machine-only.

Needs voice:handle · reaches outside (sends, publishes or charges)

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/voice_calls/{id}/actions/connect_whatsapp_call
API key or OAuth token · voice:handle
  • Canonical address: POST /api/v1/actions/voice.connect_whatsapp_call

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Call · id of voice_call
deviceIduuidComputer

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_ringingOnly a waiting WhatsApp call connects, once.
wrong_computerThe computer that has the call connects it.
voice_not_foundThe talking Era must have a voice.
voice_offThe voice must be on.
minutes_used_upThe month’s call minutes must not be used up.
no_sourceSomething must be able to pay for the minutes.
budget_exceededThe AI budget must have room.

Events it publishes: voice.call_started

What it writes: voice_call (update) — queued → in progress, with its reservation

Errors: 401 no or expired credential · 403 the credential does not hold voice:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_ringing, wrong_computer, voice_not_found, voice_off, minutes_used_up, no_source, budget_exceeded · 429 slow down

voice.decide_whatsapp_call

Answer a ringing WhatsApp call with Era, or let it ring — While a WhatsApp call rings on your computer: Era answers it, or it keeps ringing for you. A workflow on “WhatsApp call ringing” uses this too.

Needs voice:write · reaches outside (sends, publishes or charges)

POSThttps://app.getera.io/api/v1/voice_calls/{id}/actions/decide_whatsapp_call
API key or OAuth token · voice:write
  • Canonical address: POST /api/v1/actions/voice.decide_whatsapp_call

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Call · id of voice_call
answerbooleanyesEra answers

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_ringingOnly a ringing WhatsApp call is decided.

What it writes: voice_call (update) — Writes the decision; a call left to ring is closed without cost

curl -X POST https://app.getera.io/api/v1/voice_calls/VOICE_CALL_ID/actions/decide_whatsapp_call \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"answer":true}'
Response
{
  "ok": true,
  "result": "…",
  "events": []
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.voiceCalls.decideWhatsappCall("VOICE_CALL_ID", {
  answer: true
})
era voice_calls decide_whatsapp_call VOICE_CALL_ID \
  --answer true
tools/call
{
  "name": "era__voice__decide_whatsapp_call",
  "arguments": {
    "id": "VOICE_CALL_ID",
    "answer": true
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold voice:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_ringing · 429 slow down

voice.enable

Give an Era a voice — An Era answers the phone, the website’s voice button and you in the app — with the voice, greeting, hours and abilities you pick.

Needs voice:manage · changes data

POSThttps://app.getera.io/api/v1/voice_agents/actions/enable
API key or OAuth token · voice:manage
  • Canonical address: POST /api/v1/actions/voice.enable

Input

FieldTypeRequiredNotes
agentIduuidyesEra · id of ai_agent
inboxIduuidyesPhone line (Inbox channel) · id of inbox
voiceIdstringVoice · max 120
voiceNamestringVoice name · max 120
languagestringLanguage · max 8
greetingstringGreeting · max 600
personastringManner · max 4000
afterHoursstring (enum)Outside opening hours · Allowed values: answer, take_message, transfer, closed_message
afterHoursMessagestringClosed message · max 600
transferNumberstringTransfer number · max 32
toolsobject / arrayWhat it may do · check_availability, book_appointment, cancel_appointment, order_status, capture_lead, answer_question, take_message, transfer_to_human
approvalToolsobject / arrayAsk me first for
knowledgeBaseIdsobject / arrayKnowledge bases
maxCallMinutesnumberLongest call (minutes) · min 1 · max 60
widgetEnabledbooleanVoice button on my website
widgetSiteIduuidWebsite · id of site
widgetLabelstringButton text · max 60
appEnabledbooleanTalk to it in the app
outboundEnabledbooleanMay make calls
disclosureEnabledbooleanSay it is an AI and the call is recorded
confirmBookingbooleanSend a WhatsApp/SMS confirmation after a booking

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
agent_not_foundThe Era must exist here.
already_has_voiceAn Era has one voice.
inbox_not_voiceCalls land on an active voice channel.
inbox_takenOne Era answers one line.
unknown_toolEvery ability must be one a voice Era has.
bad_transfer_numberA transfer number is a full international phone number.
transfer_needs_numberPutting calls through needs a transfer number.
unknown_languageThe language must be one the voice speaks.
unknown_knowledge_baseKnowledge bases are picked by id.
site_not_foundThe website must be this workspace’s.

Events it publishes: voice.agent_changed

What it writes: voice_agent (insert) — Writes the voice, switched off until it is ready

curl -X POST https://app.getera.io/api/v1/voice_agents/actions/enable \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"agentId":"AI_AGENT_ID","inboxId":"INBOX_ID"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "voice.agent_changed"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.voiceAgents.enable({
  agentId: "AI_AGENT_ID",
  inboxId: "INBOX_ID"
})
era voice_agents enable \
  --agent-id "AI_AGENT_ID" \
  --inbox-id "INBOX_ID"
tools/call
{
  "name": "era__voice__enable",
  "arguments": {
    "agentId": "AI_AGENT_ID",
    "inboxId": "INBOX_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold voice:manage · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 agent_not_found, already_has_voice, inbox_not_voice, inbox_taken, unknown_tool, bad_transfer_number, transfer_needs_number, unknown_language, unknown_knowledge_base, site_not_found · 429 slow down

voice.fail_call

A call did not happen — Busy, no answer or failed: nothing is metered and a missed call can be followed up. Machine-only.

Needs voice:handle · reaches outside (sends, publishes or charges)

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/voice_calls/{id}/actions/fail_call
API key or OAuth token · voice:handle
  • Canonical address: POST /api/v1/actions/voice.fail_call

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Call · id of voice_call
statusstringyesWhat happened · max 12
reasonstringWhy · max 600

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
call_finishedA call is filed once.
invalid_stateMissed, failed or cancelled.

Events it publishes: voice.call_missed

What it writes: voice_call (update) — → missed / failed / cancelled, released

Errors: 401 no or expired credential · 403 the credential does not hold voice:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 call_finished, invalid_state · 429 slow down

voice.mark_dialed

A call was placed — The provider is ringing the number. Machine-only.

Needs voice:handle · changes data

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/voice_calls/{id}/actions/mark_dialed
API key or OAuth token · voice:handle
  • Canonical address: POST /api/v1/actions/voice.mark_dialed

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Call · id of voice_call
externalIdstringyesProvider call · max 120
callSidstringTelephony id · max 120

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
not_queuedOnly a queued call can be dialled, once.

What it writes: voice_call (update) — queued → in progress

Errors: 401 no or expired credential · 403 the credential does not hold voice:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 not_queued · 429 slow down

voice.open_call

A call began — Records a call the moment it starts — the phone, the website button or the app — after checking minutes and the voice key. Machine-only.

Needs voice:handle · reaches outside (sends, publishes or charges)

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/voice_calls/actions/open_call
API key or OAuth token · voice:handle
  • Canonical address: POST /api/v1/actions/voice.open_call

Input

FieldTypeRequiredNotes
voiceAgentIduuidyesVoice · id of voice_agent
channelstring (enum)yesChannel · Allowed values: phone, widget, app, whatsapp
bridgestringHow it reached Era · max 20
waCallIdstringWhatsApp call · max 200
directionstring (enum)Direction · Allowed values: inbound, outbound
fromNumberstringFrom · max 40
toNumberstringTo · max 40
externalIdstringProvider call · max 120
callSidstringTelephony id · max 120
principalUserIduuidTalking member
practicebooleanPractice call

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
voice_not_foundThe voice must exist here.
voice_offThe voice must be on.
channel_offThe website button or the in-app voice must be on for a call there.
unknown_bridgeThe way the call reached Era must be a known one.
minutes_used_upThe month’s call minutes must not be used up.
no_sourceThe workspace’s own voice key must be able to run it.
budget_exceededThe AI budget must have room.

Events it publishes: voice.call_started

What it writes: voice_call (insert) — Opens the call

Errors: 401 no or expired credential · 403 the credential does not hold voice:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 voice_not_found, voice_off, channel_off, unknown_bridge, minutes_used_up, no_source, budget_exceeded · 429 slow down

voice.record_sync

Record the voice provider’s answer — The provider took (or refused) the Era’s voice and number. Machine-only.

Needs voice:handle · changes data

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/voice_agents/{id}/actions/record_sync
API key or OAuth token · voice:handle
  • Canonical address: POST /api/v1/actions/voice.record_sync

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Voice · id of voice_agent
statusstringyesState · max 10
externalAgentIdstringProvider agent · max 120
externalPhoneIdstringProvider number · max 120
voiceIdstringVoice · max 120
errorstringWhy · max 600

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
voice_not_foundThe voice must exist here.
invalid_stateA sync is synced or failed.

Events it publishes: voice.sync_failed

What it writes: voice_agent (update) — Writes the provider ids and the sync state

Errors: 401 no or expired credential · 403 the credential does not hold voice:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 voice_not_found, invalid_state · 429 slow down

voice.record_turn

Record what Era did on a call — Adds the actions of one reply to the call’s log and keeps its working memory. Machine-only.

Needs voice:handle · changes data

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/voice_calls/{id}/actions/record_turn
API key or OAuth token · voice:handle
  • Canonical address: POST /api/v1/actions/voice.record_turn

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Call · id of voice_call
actionsobject / arrayActions
memoryobject / arrayWorking memory
externalIdstringProvider call · max 120

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
call_not_openOnly a call in progress takes new actions.

What it writes: voice_call (update) — Appends actions, replaces memory

Errors: 401 no or expired credential · 403 the credential does not hold voice:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 call_not_open · 429 slow down

voice.record_whatsapp

Record whether WhatsApp calls are on — Meta took the calling settings and the voice provider took the bridged number — or one of them refused. Machine-only.

Needs voice:handle · changes data

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/voice_agents/{id}/actions/record_whatsapp
API key or OAuth token · voice:handle
  • Canonical address: POST /api/v1/actions/voice.record_whatsapp

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Voice · id of voice_agent
statusstringyesState · max 10
externalPhoneIdstringProvider number · max 120
errorstringWhy · max 600

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
voice_not_foundThe voice must exist here.
invalid_stateOn, off or failed.

Events it publishes: voice.sync_failed

What it writes: voice_agent (update) — Writes the WhatsApp line state and the provider number id

Errors: 401 no or expired credential · 403 the credential does not hold voice:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 voice_not_found, invalid_state · 429 slow down

voice.remove

Take an Era’s voice away — The Era stops answering calls. Its call history stays.

Needs voice:delete · removes or cannot be undone · asks a person to confirm when Era runs it

POSThttps://app.getera.io/api/v1/voice_agents/{id}/actions/remove
API key or OAuth token · voice:delete
  • Canonical address: POST /api/v1/actions/voice.remove

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Voice · id of voice_agent

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
voice_not_foundThe voice must exist here.

Events it publishes: voice.agent_changed

What it writes: voice_agent (delete) — Deletes the voice; calls keep their history

curl -X POST https://app.getera.io/api/v1/voice_agents/VOICE_AGENT_ID/actions/remove \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "voice.agent_changed"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.voiceAgents.remove("VOICE_AGENT_ID")
era voice_agents remove VOICE_AGENT_ID
tools/call
{
  "name": "era__voice__remove",
  "arguments": {
    "id": "VOICE_AGENT_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold voice:delete · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 voice_not_found · 429 slow down

voice.set_enabled

Switch an Era’s voice on or off — On: it answers calls. Off: calls are not answered by Era; nothing is lost.

Needs voice:manage · changes data

POSThttps://app.getera.io/api/v1/voice_agents/{id}/actions/set_enabled
API key or OAuth token · voice:manage
  • Canonical address: POST /api/v1/actions/voice.set_enabled

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Voice · id of voice_agent
enabledbooleanyesOn

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
voice_not_foundThe voice must exist here.
no_voiceA voice is picked before it goes on.
inbox_not_voiceA line is picked before it goes on.

Events it publishes: voice.agent_changed

What it writes: voice_agent (update) — Flips the switch

curl -X POST https://app.getera.io/api/v1/voice_agents/VOICE_AGENT_ID/actions/set_enabled \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"enabled":true}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "voice.agent_changed"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.voiceAgents.setEnabled("VOICE_AGENT_ID", {
  enabled: true
})
era voice_agents set_enabled VOICE_AGENT_ID \
  --enabled true
tools/call
{
  "name": "era__voice__set_enabled",
  "arguments": {
    "id": "VOICE_AGENT_ID",
    "enabled": true
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold voice:manage · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 voice_not_found, no_voice, inbox_not_voice · 429 slow down

voice.set_outcome

Correct a call’s outcome — When Era read a call wrong — it was really a booking, a lead, a message.

Needs voice:write · changes data

POSThttps://app.getera.io/api/v1/voice_calls/{id}/actions/set_outcome
API key or OAuth token · voice:write
  • Canonical address: POST /api/v1/actions/voice.set_outcome

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Call · id of voice_call
outcomestring (enum)yesOutcome · Allowed values: booked, cancelled, lead, message, answered, transferred, no_action, failed

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
call_not_finishedOnly a finished call is corrected.

What it writes: voice_call (update) — Writes the outcome

curl -X POST https://app.getera.io/api/v1/voice_calls/VOICE_CALL_ID/actions/set_outcome \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"outcome":"booked"}'
Response
{
  "ok": true,
  "result": "…",
  "events": []
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.voiceCalls.setOutcome("VOICE_CALL_ID", {
  outcome: "booked"
})
era voice_calls set_outcome VOICE_CALL_ID \
  --outcome "booked"
tools/call
{
  "name": "era__voice__set_outcome",
  "arguments": {
    "id": "VOICE_CALL_ID",
    "outcome": "booked"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold voice:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 call_not_finished · 429 slow down

voice.set_whatsapp_line

Answer WhatsApp calls on my computer — Era answers the WhatsApp voice calls on your computer’s WhatsApp — which ones, after how many seconds, and whether it may also call people for you. No phone number needed.

Needs voice:manage · changes data

POSThttps://app.getera.io/api/v1/voice_whatsapp_lines/actions/set_whatsapp_line
API key or OAuth token · voice:manage
  • Canonical address: POST /api/v1/actions/voice.set_whatsapp_line

Input

FieldTypeRequiredNotes
voiceAgentIduuidyesEra that talks · id of voice_agent
deviceIduuidComputer · The Era Desktop whose WhatsApp it answers; empty = any of yours.
enabledbooleanOn
answerRulestring (enum)Which calls · Allowed values: all, unknown, contacts, in_hours, after_hours, workflow
ringSecondsnumberLet it ring first (seconds) · min 0 · max 40
ownerNamestringWhose assistant Era says it is · max 120
outboundEnabledbooleanMay call people for me
answerVideobooleanAlso answer video calls (voice only)

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
voice_not_foundThe talking Era must have a voice here.

What it writes: voice_whatsapp_line (upsert) — Writes the workspace’s one WhatsApp-on-the-computer line

curl -X POST https://app.getera.io/api/v1/voice_whatsapp_lines/actions/set_whatsapp_line \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"voiceAgentId":"VOICE_AGENT_ID"}'
Response
{
  "ok": true,
  "result": "…",
  "events": []
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.voiceWhatsappLines.setWhatsappLine({
  voiceAgentId: "VOICE_AGENT_ID"
})
era voice_whatsapp_lines set_whatsapp_line \
  --voice-agent-id "VOICE_AGENT_ID"
tools/call
{
  "name": "era__voice__set_whatsapp_line",
  "arguments": {
    "voiceAgentId": "VOICE_AGENT_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold voice:manage · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 voice_not_found · 429 slow down

voice.start_call

Have Era call someone — Era rings a customer now from your number — to confirm a booking, follow up a lead, say an order is ready. Minutes are checked first.

Needs voice:write · reaches outside (sends, publishes or charges) · asks a person to confirm when Era runs it

POSThttps://app.getera.io/api/v1/voice_calls/actions/start_call
API key or OAuth token · voice:write
  • Canonical address: POST /api/v1/actions/voice.start_call

Input

FieldTypeRequiredNotes
voiceAgentIduuidyesEra · id of voice_agent
tostringyesNumber · Any way it is written: 0532 123 45 67 or +90… · max 40
purposestringWhat the call is for · max 1000
customerIduuidCustomer · id of customer
channelstring (enum)Call on · Allowed values: phone, whatsapp

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
voice_not_foundThe voice must exist here.
voice_offThe voice must be on.
outbound_offThe Era must be allowed to make calls.
bad_numberThe number must be callable.
no_phone_lineA connected number is needed to call out.
whatsapp_calling_offA WhatsApp call needs WhatsApp calls switched on for this Era.
minutes_used_upThe month’s call minutes must not be used up.
outbound_limitThe daily outbound limit must not be reached.
no_sourceThe workspace’s own voice key must be able to run it.
budget_exceededThe AI budget must have room.

Events it publishes: voice.call_started

What it writes: voice_call (insert) — Queues the call

curl -X POST https://app.getera.io/api/v1/voice_calls/actions/start_call \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"voiceAgentId":"VOICE_AGENT_ID","to":"Number"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "voice.call_started"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.voiceCalls.startCall({
  voiceAgentId: "VOICE_AGENT_ID",
  to: "Number"
})
era voice_calls start_call \
  --voice-agent-id "VOICE_AGENT_ID" \
  --to "Number"
tools/call
{
  "name": "era__voice__start_call",
  "arguments": {
    "voiceAgentId": "VOICE_AGENT_ID",
    "to": "Number"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold voice:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 voice_not_found, voice_off, outbound_off, bad_number, no_phone_line, whatsapp_calling_off, minutes_used_up, outbound_limit, no_source, budget_exceeded · 429 slow down

voice.start_whatsapp_call

Call someone on WhatsApp with Era — Era calls a person on your computer’s WhatsApp, talks to them about what you asked, hangs up and tells you how it went — summary, outcome, transcript.

Needs voice:write · reaches outside (sends, publishes or charges)

POSThttps://app.getera.io/api/v1/voice_calls/actions/start_whatsapp_call
API key or OAuth token · voice:write
  • Canonical address: POST /api/v1/actions/voice.start_whatsapp_call

Input

FieldTypeRequiredNotes
tostringNumber · Any way it is written: 0532 123 45 67 or +90… · max 40
customerIduuidCustomer · id of customer
namestringName · max 120
goalstringyesWhat to talk about · e.g. “Ask if she can come on Friday at 3 instead of Thursday.” · max 1000
scriptstringPoints to cover · max 2000
exactbooleanExactly this WhatsApp chat · The name is the chat the person picked from Era’s choices.
threadIdstringEra chat · Where Era tells the result when the call ends. · max 200

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
whatsapp_line_offEra must be set up for WhatsApp on a computer.
whatsapp_outbound_offEra must be allowed to make WhatsApp calls.
no_one_to_callA WhatsApp name, a number or a customer is needed.
bad_numberThe number must be callable.
voice_not_foundThe talking Era must have a voice.
voice_offThe voice must be on.
minutes_used_upThe month’s call minutes must not be used up.
outbound_limitThe daily outbound limit must not be reached.
no_sourceSomething must be able to pay for the minutes.
budget_exceededThe AI budget must have room.

Events it publishes: voice.whatsapp_call_requested

What it writes: voice_call (insert) — Queues the call for the computer, with its reservation

curl -X POST https://app.getera.io/api/v1/voice_calls/actions/start_whatsapp_call \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"goal":"What to talk about"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "voice.whatsapp_call_requested"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.voiceCalls.startWhatsappCall({
  goal: "What to talk about"
})
era voice_calls start_whatsapp_call \
  --goal "What to talk about"
tools/call
{
  "name": "era__voice__start_whatsapp_call",
  "arguments": {
    "goal": "What to talk about"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold voice:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 whatsapp_line_off, whatsapp_outbound_off, no_one_to_call, bad_number, voice_not_found, voice_off, minutes_used_up, outbound_limit, no_source, budget_exceeded · 429 slow down

voice.take_over_whatsapp_call

Take the WhatsApp call over from Era — “Devral”: Era stops talking and the call’s sound goes back to your own microphone and speakers on the computer.

Needs voice:write · reaches outside (sends, publishes or charges)

POSThttps://app.getera.io/api/v1/voice_calls/{id}/actions/take_over_whatsapp_call
API key or OAuth token · voice:write
  • Canonical address: POST /api/v1/actions/voice.take_over_whatsapp_call

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Call · id of voice_call

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
call_not_liveOnly a WhatsApp call going on now is taken over, once.

Events it publishes: voice.whatsapp_takeover

What it writes: voice_call (update) — Marks the moment; the computer hands the sound back

curl -X POST https://app.getera.io/api/v1/voice_calls/VOICE_CALL_ID/actions/take_over_whatsapp_call \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "voice.whatsapp_takeover"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.voiceCalls.takeOverWhatsappCall("VOICE_CALL_ID")
era voice_calls take_over_whatsapp_call VOICE_CALL_ID
tools/call
{
  "name": "era__voice__take_over_whatsapp_call",
  "arguments": {
    "id": "VOICE_CALL_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold voice:write · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 call_not_live · 429 slow down

voice.update

Change an Era’s voice — Voice, greeting, language, opening-hours behaviour, transfer number, abilities, knowledge and where it answers.

Needs voice:manage · changes data

POSThttps://app.getera.io/api/v1/voice_agents/{id}/actions/update
API key or OAuth token · voice:manage
  • REST alias: PATCH /api/v1/voice_agents/{id}
  • Canonical address: POST /api/v1/actions/voice.update

Input

FieldTypeRequiredNotes
iduuidyesFilled from the path {id} · Voice · id of voice_agent
inboxIduuidPhone line (Inbox channel) · id of inbox
voiceIdstringVoice · max 120
voiceNamestringVoice name · max 120
languagestringLanguage · max 8
greetingstringGreeting · max 600
personastringManner · max 4000
afterHoursstring (enum)Outside opening hours · Allowed values: answer, take_message, transfer, closed_message
afterHoursMessagestringClosed message · max 600
transferNumberstringTransfer number · max 32
toolsobject / arrayWhat it may do · check_availability, book_appointment, cancel_appointment, order_status, capture_lead, answer_question, take_message, transfer_to_human
approvalToolsobject / arrayAsk me first for
knowledgeBaseIdsobject / arrayKnowledge bases
maxCallMinutesnumberLongest call (minutes) · min 1 · max 60
widgetEnabledbooleanVoice button on my website
widgetSiteIduuidWebsite · id of site
widgetLabelstringButton text · max 60
appEnabledbooleanTalk to it in the app
outboundEnabledbooleanMay make calls
disclosureEnabledbooleanSay it is an AI and the call is recorded
confirmBookingbooleanSend a WhatsApp/SMS confirmation after a booking

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
voice_not_foundThe voice must exist here.
inbox_not_voiceCalls land on an active voice channel.
inbox_takenOne Era answers one line.
unknown_toolEvery ability must be one a voice Era has.
bad_transfer_numberA transfer number is a full international phone number.
transfer_needs_numberPutting calls through needs a transfer number.
unknown_languageThe language must be one the voice speaks.
unknown_knowledge_baseKnowledge bases are picked by id.
site_not_foundThe website must be this workspace’s.

Events it publishes: voice.agent_changed

What it writes: voice_agent (update) — Writes the settings and marks the provider copy for re-sync

curl -X POST https://app.getera.io/api/v1/voice_agents/VOICE_AGENT_ID/actions/update \
  -H "Authorization: Bearer $ERA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"inboxId":"INBOX_ID"}'
Response
{
  "ok": true,
  "result": "…",
  "events": [
    "voice.agent_changed"
  ]
}
import { createEra } from "@getera/sdk"

const era = createEra({ apiKey: process.env.ERA_API_KEY })
const res = await era.voiceAgents.update("VOICE_AGENT_ID", {
  inboxId: "INBOX_ID"
})
era voice_agents update VOICE_AGENT_ID \
  --inbox-id "INBOX_ID"
tools/call
{
  "name": "era__voice__update",
  "arguments": {
    "id": "VOICE_AGENT_ID",
    "inboxId": "INBOX_ID"
  }
}

Errors: 401 no or expired credential · 403 the credential does not hold voice:manage · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 voice_not_found, inbox_not_voice, inbox_taken, unknown_tool, bad_transfer_number, transfer_needs_number, unknown_language, unknown_knowledge_base, site_not_found · 429 slow down

voice.whatsapp_ring

A WhatsApp call is ringing on the computer — Era Desktop reports a ringing WhatsApp call; the line’s rule says whether Era answers it, leaves it to you, or a workflow decides. Machine-only.

Needs voice:handle · reaches outside (sends, publishes or charges)

Run by Era itself (machine-only). Listed so the reference is complete; an API key or a token is refused (403 machine_only).
POSThttps://app.getera.io/api/v1/voice_calls/actions/whatsapp_ring
API key or OAuth token · voice:handle
  • Canonical address: POST /api/v1/actions/voice.whatsapp_ring

Input

FieldTypeRequiredNotes
deviceIduuidComputer
callerNamestringCaller · max 120
callerNumberstringNumber · max 40
knownbooleanA customer
customerIduuidCustomer · id of customer
openNowbooleanOpen now
videobooleanVideo call

Preconditions

The action is refused with 409 and one of these codes:

CodeRefused when
whatsapp_line_offEra must be set to answer WhatsApp calls on a computer.
wrong_computerOnly the chosen computer answers.
voice_not_foundThe talking Era must have a voice.
voice_offThe talking Era’s voice must be on.

Events it publishes: voice.whatsapp_ringing

What it writes: voice_call (insert) — A ringing WhatsApp call with Era’s decision

Errors: 401 no or expired credential · 403 the credential does not hold voice:handle · 404 the record or module is outside what it may reach · 422 invalid input (problems[]) · 409 whatsapp_line_off, wrong_computer, voice_not_found, voice_off · 429 slow down

Data models

VoiceAgent

Table voice_agent · Resource voice_agents

  • GET /api/v1/voice_agents
  • GET /api/v1/voice_agents/{id}
  • PATCH /api/v1/voice_agents/{id} → voice.update
ColumnTypeNullableAllowed valuesReferences
idstring (uuid) · uuid
organization_idstring (uuid) · uuidorganization
workspace_idstring (uuid) · uuidworkspace
agent_idstring (uuid) · uuidai_agent
inbox_idstring (uuid) · uuidyesinbox
is_enabledboolean · bool
providerstring · textelevenlabs, mock
payerstring · text
voice_idstring · textyes
voice_namestring · textyes
languagestring · text
greetingstring · text
personastring · text
after_hoursstring · textanswer, take_message, transfer, closed_message
after_hours_messagestring · textyes
transfer_numberstring · textyes
toolsstring[] · text[]
approval_toolsstring[] · text[]
knowledge_base_idsstring[] · uuid[]
max_call_minutesinteger · int4
widget_enabledboolean · bool
widget_site_idstring (uuid) · uuidyessite
widget_labelstring · textyes
app_enabledboolean · bool
outbound_enabledboolean · bool
external_agent_idstring · textyes
external_phone_idstring · textyes
sync_statusstring · textpending, synced, failed
sync_errorstring · textyes
synced_atstring (date-time) · timestamptzyes
created_bystring (uuid) · uuidyesapp_user
created_atstring (date-time) · timestamptz
updated_atstring (date-time) · timestamptz
whatsapp_inbox_idstring (uuid) · uuidyesinbox
whatsapp_phone_idstring · textyes
whatsapp_statusstring · textoff, pending, on, failed
whatsapp_errorstring · textyes
disclosure_enabledboolean · bool
confirm_bookingboolean · bool

Primary key: id

Checks:

  • CHECK (((after_hours_message IS NULL) OR (length(after_hours_message) <= 600)))
  • CHECK ((approval_tools <@ tools))
  • CHECK ((length(greeting) <= 600))
  • CHECK ((language ~ '^[a-z]{2}(-[A-Z]{2})?$'::text))
  • CHECK (((max_call_minutes >= 1) AND (max_call_minutes <= 60)))
  • CHECK ((payer = 'own_key'::text))
  • CHECK ((length(persona) <= 4000))
  • CHECK (((sync_error IS NULL) OR (length(sync_error) <= 600)))
  • CHECK ((tools <@ ARRAY['check_availability'::text, 'book_appointment'::text, 'cancel_appointment'::text, 'order_status'::text, 'capture_lead'::text, 'answer_question'::text, 'take_message'::text, 'transfer_to_human'::text]))
  • CHECK (((transfer_number IS NULL) OR (transfer_number ~ '^\+[1-9][0-9]{6,14}$'::text)))
  • CHECK (((whatsapp_error IS NULL) OR (length(whatsapp_error) <= 600)))
  • CHECK (((widget_label IS NULL) OR (length(widget_label) <= 60)))

VoiceCall

Table voice_call · Resource voice_calls

  • GET /api/v1/voice_calls
  • GET /api/v1/voice_calls/{id}
ColumnTypeNullableAllowed valuesReferences
idstring (uuid) · uuid
organization_idstring (uuid) · uuidorganization
workspace_idstring (uuid) · uuidworkspace
voice_agent_idstring (uuid) · uuidyesvoice_agent
agent_idstring (uuid) · uuidyesai_agent
inbox_idstring (uuid) · uuidyesinbox
conversation_idstring (uuid) · uuidyesconversation
customer_idstring (uuid) · uuidyescustomer
channelstring · textphone, widget, app, whatsapp
directionstring · textinbound, outbound
statusstring · textqueued, awaiting_permission, in_progress, completed, missed, failed, cancelled
from_numberstring · textyes
to_numberstring · textyes
caller_namestring · textyes
purposestring · textyes
external_idstring · textyes
external_call_sidstring · textyes
started_atstring (date-time) · timestamptzyes
ended_atstring (date-time) · timestamptzyes
duration_secinteger · int4
transcriptobject · jsonb
summarystring · textyes
outcomestring · textyes
actionsobject · jsonb
memoryobject · jsonb
recordingboolean · bool
recording_file_idstring (uuid) · uuidyes
languagestring · textyes
end_reasonstring · textyes
principal_user_idstring (uuid) · uuidyesapp_user
payerstring · textyes
usage_idstring (uuid) · uuidyes
source_kindstring · textyes
cost_usdstring (decimal) · numeric
errorstring · textyes
created_bystring (uuid) · uuidyesapp_user
created_atstring (date-time) · timestamptz
updated_atstring (date-time) · timestamptz
bridgestring · textyes
wa_call_idstring · textyes
device_idstring (uuid) · uuidyes
ring_decisionstring · textyes
ring_reasonstring · textyes
handover_requested_atstring (date-time) · timestamptzyes
handover_bystring (uuid) · uuidyesapp_user

Primary key: id

Checks:

  • CHECK ((jsonb_typeof(actions) = 'array'::text))
  • CHECK (((bridge IS NULL) OR (bridge = ANY (ARRAY['twilio'::text, 'sip'::text, 'elevenlabs'::text, 'whatsapp_sip'::text, 'desktop'::text, 'web'::text]))))
  • CHECK ((duration_sec >= 0))
  • CHECK (((error IS NULL) OR (length(error) <= 600)))
  • CHECK ((jsonb_typeof(memory) = 'object'::text))
  • CHECK (((outcome IS NULL) OR (outcome = ANY (ARRAY['booked'::text, 'cancelled'::text, 'lead'::text, 'message'::text, 'answered'::text, 'transferred'::text, 'no_action'::text, 'failed'::text]))))
  • CHECK (((payer IS NULL) OR (payer = 'own_key'::text))) NOT VALID
  • CHECK (((purpose IS NULL) OR (length(purpose) <= 1000)))
  • CHECK (((ring_decision IS NULL) OR (ring_decision = ANY (ARRAY['answer'::text, 'ignore'::text, 'wait'::text]))))
  • CHECK (((ring_reason IS NULL) OR (length(ring_reason) <= 300)))
  • CHECK (((source_kind IS NULL) OR (source_kind = ANY (ARRAY['native'::text, 'byos'::text, 'byok'::text])))) NOT VALID
  • CHECK ((jsonb_typeof(transcript) = 'array'::text))

VoiceWhatsappLine

Table voice_whatsapp_line · Resource voice_whatsapp_lines

  • GET /api/v1/voice_whatsapp_lines
  • GET /api/v1/voice_whatsapp_lines/{id}
ColumnTypeNullableAllowed valuesReferences
idstring (uuid) · uuid
organization_idstring (uuid) · uuidorganization
workspace_idstring (uuid) · uuidworkspace
voice_agent_idstring (uuid) · uuidvoice_agent
device_idstring (uuid) · uuidyes
is_enabledboolean · bool
answer_rulestring · textall, unknown, contacts, in_hours, after_hours, workflow
ring_secondsinteger · int4
owner_namestring · textyes
outbound_enabledboolean · bool
answer_videoboolean · bool
created_bystring (uuid) · uuidyesapp_user
created_atstring (date-time) · timestamptz
updated_atstring (date-time) · timestamptz

Primary key: id

Checks:

  • CHECK (((owner_name IS NULL) OR (length(owner_name) <= 120)))
  • CHECK (((ring_seconds >= 0) AND (ring_seconds <= 40)))

Events

Workflows and webhooks react to these events.

EventWhat happensPayload
voice.agent_changedAn Era got a voice, or its voice settings changed.id, agentId, enabled
voice.appointment_bookedEra booked an appointment on a call.id, voiceAgentId, customerId, conversationId, appointmentId, channel, service, appointmentDate, startTime, callerName, callerNumber
voice.call_finishedA call ended and was filed in the Inbox with its summary and outcome.id, voiceAgentId, agentId, customerId, conversationId, outcome, channel, direction, durationSec, summary, fromNumber, recipientUserId
voice.call_missedA call did not connect (busy, no answer, failed).id, voiceAgentId, customerId, number, direction, reason, recipientUserId
voice.call_startedA call began — phone, WhatsApp, website button or app.id, voiceAgentId, channel, direction, customerId
voice.lead_capturedEra took a new lead on a call.id, voiceAgentId, customerId, conversationId, leadId
voice.message_takenEra took a message on a call.id, voiceAgentId, customerId, conversationId, taskId, summary, recipientUserId
voice.sync_failedThe voice provider refused an Era’s setup.id, error, recipientUserId
voice.transfer_requestedA caller was put through to a person.id, voiceAgentId, customerId, conversationId
voice.whatsapp_call_finishedA WhatsApp call Era took on the computer ended — caller, transcript, summary, outcome and what it was about.id, voiceAgentId, direction, callerName, callerNumber, customerId, conversationId, transcript, summary, outcome, outcomeLabel, intent, goal, durationSec, recipientUserId
voice.whatsapp_call_requestedSomeone asked Era to call a person on WhatsApp from the computer.id, voiceAgentId, deviceId, to, name, goal, customerId, recipientUserId
voice.whatsapp_ringingA WhatsApp call is ringing on your computer — with who it is and whether Era takes it.id, voiceAgentId, callerName, callerNumber, customerId, known, decision
voice.whatsapp_takeoverA person took a WhatsApp call over from Era.id, byUserId
Was this page helpful?