https://retellai.com/?utm_source=discord&utm_medium=seo logo
can yo uadvise in some campaign data sending recei...
# ❓・ai-evy-support
c
@AI Evy can yo uadvise in some campaign data sending receiving?
a
Thanks for tagging me @Client Nexus. I'll look through relevant sources and get back to you shortly.
### Answer For SMS campaign setup with Retell, here's what you need to know: ## Prerequisites SMS capabilities are available for Retell Twilio numbers and your own Twilio numbers. [(1) ]() Current SMS capabilities are limited to US numbers only. ## Approval Process To enable SMS, you need to complete these steps: 1. Get approved for a business profile (free) 2. Get approved for a brand based on business profile: - **Low-volume**: $4 one-time fee, fewer than 6,000 message segments/day to US - **Standard**: $45 one-time fee, 6,000–400,000 message segments/day to US 3. Get approved for an SMS campaign ($15 one-time fee) The entire application can take around 2-3 weeks as it's a manual review process. ## Campaign Application Tips When applying for a campaign, you'll fill out the use case and sample messages. There are strict rules on SMS—if your actual traffic doesn't match the sample messages, your number/telephony subaccount might be suspended. ## Changing Use Case If you need to send different SMS messages later, you can delete the SMS capability on the number (this won't delete your approved business profile, brand, and campaign) , then create a new SMS application with a new campaign while reusing the business profile and brand. Is there a specific part of the campaign setup you'd like more detail on?
​ To learn more, see the sources I considered: [[1] Send & receive SMS](https://docs.retellai.com/deploy/enable-sms) ​
Feel free to tag @AI Evy with additional questions. I also appreciate feedback, it helps me improve.
c
@AI Evy 1. Goal Status (goal_status) Current implementation: We check calls.goal_status === 'achieved' to count "Goal Achieved" metrics Data source: I searched and found NO code in the webhook that sets goal_status on the calls table Query result: SELECT DISTINCT goal_status FROM calls WHERE goal_status IS NOT NULL returned empty (no rows) Question: Does Retell AI send a goal_status field in their webhook payloads? If so: What event contains it (call_ended, call_analyzed, or elsewhere)? What are the possible values? Or do we need to call mark_goal_achieved tool from the agent's script and handle it ourselves? 2. "Completed" Status Definition Current implementation: status === 'completed' on campaign_leads Issue: I see we update status to contacted, no_answer, failed, etc., but I don't see when it becomes completed Question: What should trigger a lead to become "completed"? After successful call conversation? After appointment booked? After reaching end of campaign sequence? 3. "Replied" Metric Current implementation: replied === true OR status === 'replied' on campaign_leads Issue: For call campaigns, what constitutes a "reply"? Question: For AI call campaigns, should "replied" mean: The contact answered the call? (same as answered?) The contact spoke back during the call? Or is this SMS-specific (contact replied to a text)? 4. Campaign "Active" vs "Completed/Finished" Status You mentioned campaigns show "Active" even when all leads have been contacted Question: When should a campaign status change from "Active" to "Completed"? When all leads have been contacted at least once? When all leads reach final status (answered/failed/no_answer)? When all campaign sequence steps are done? Manual trigger only?
a
Thanks for the follow-up, @Client Nexus. I'll get back to you soon.
### Answer Based on the available sources, I can provide partial answers: ## 1. Goal Status (
goal_status
) The sources don't explicitly mention a
goal_status
field in webhook payloads. However, the
call_analyzed
event includes a
call_analysis
object for post-call analysis data. [(1) ]() What is documented in the webhook payload: -
call_ended
event contains all fields from the call object except
call_analysis
-
call_analyzed
event contains the full call data including the
call_analysis
object The
call_analysis
object is where custom post-call analysis data lives. You can define custom extraction fields (like goal achievement) using
post_call_analysis_data
when configuring your agent. [(2) ]() So you'd likely need to: - Define a custom analysis field for goal tracking - Or use a custom function/tool during the call to mark goals achieved ## 2-4. "Completed" Status, "Replied" Metric, Campaign Status I don't have documentation on these specific campaign management concepts in the available sources. These appear to be your application's business logic rather than fields Retell AI provides directly. What Retell provides in webhooks: -
disconnection_reason
(e.g.,
user_hangup
,
agent_hangup
,
dial_no_answer
,
dial_failed
, etc.) [(3) ]() -
call_status
(
registered
,
ongoing
,
ended
,
error
) -
transcript
and
call_analysis
data [(1) ]() For campaign workflow logic (when to mark leads as "completed," what constitutes "replied," when campaigns finish) , you'd typically implement this in your automation layer based on the raw call data Retell sends. The video example shows using Make.com/n8n to tra
ck call outcomes and update statuses in CRMs. [(4) ](

▾

) Check out these potentially useful sources: - [Webhook Overview]() - [Get Call API]() Would you like a general answer on how to structure these campaign metrics based on the available webhook data?
​ To learn more, see the sources I considered: [[1] Webhook Overview](https://docs.retellai.com/features/webhook-overview) [[2] List Chat Agents](https://docs.retellai.com/api-references/list-chat-agents) [[3] Register Phone Call](https://docs.retellai.com/api-references/register-phone-call) [[4] Speed to Lead: Driving Results with Outbound Facebook Campaigns](

https://www.youtube.com/watch?v=9fgelfy6kQA▾

) ​
Feel free to tag @AI Evy with additional questions. I also appreciate feedback, it helps me improve.
c
@AI Evy How do you want to store Retell API keys? - Currently the column is retell_api_key (plaintext), but the code expects retell_api_key_encrypted. Should we: Add an encrypted column and use vault encryption? Or update the code to use the plaintext column? Per-workspace vs shared Retell account? - Looking at the retell_workspaces table, some have account_id = null. Is each agency getting their own Retell workspace, or sharing one? Voice provisioning flow - Are default voices automatically available in all Retell workspaces, or do they need to be provisioned?
a
Thanks for the follow-up, @Client Nexus. I'll get back to you soon.
### Answer ### Answer These questions relate to your application's database design rather than Retell AI's platform itself. However, here's what the Retell documentation covers: ## API Key Storage Retell's guidance is to keep API keys secure and never share them publicly or in client-side code. [(1) ]() If a key is compromised, delete it immediately and create a new one. [(2) ]() The decision between encrypted vs plaintext storage is your application architecture choice—Retell doesn't prescribe a specific storage method. ## Per-Workspace vs Shared Account Each Retell workspace can have multiple API keys, all sharing the same permission level within that workspace. [(1) ]() Workspaces are separate environments—when you create an account, a default workspace is automatically created, and you can create additional workspaces as needed. [(3) ]() A common production pattern mentioned in community discussions is using separate workspaces (and separate API keys) per client. [(4) ]() ## Voice Provisioning I don't have documentation on whether default voices are automatically available across workspaces or require provisioning. Check out these potentially useful sources: - [API Key Overview]() - [Workspace]() - [Manage API Keys]() Would you like a general answer on best practices for API key encryption?
​ To learn more, see the sources I considered: [[1] API Key Overview](https://docs.retellai.com/accounts/api-keys-overview) [[2] Manage API Keys](https://docs.retellai.com/accounts/manage-api-keys) [[3] Workspace](https://docs.retellai.com/accounts/workspace) [[4] Discord message from @jayzpio on 2025-01-23](https://discord.com/channels/1186424376300679209/1294891368505937952/1331854421415694418) ​
Feel free to tag @AI Evy with additional questions. I also appreciate feedback, it helps me improve.
c
@AI Evy can we get the reason of the failed call from batch call campaigns?
a
Thanks for the follow-up, @Client Nexus. I'll get back to you soon.
### Answer Yes, you can get the reason for failed calls from batch call campaigns. Each call includes a
disconnection_reason
field that indicates why the call ended or failed to connect. [(1) ]() Common failure reasons include: | Reason | Description | |--------|-------------| |
dial_busy
| The number dialed is busy | |
dial_failed
| Dialing failed with no or unknown SIP error code | |
dial_no_answer
| The number dialed did not answer | |
invalid_destination
| The number dialed is invalid | |
marked_as_spam
| The number dialed is marked as spam | |
user_declined
| User declined the call | |
telephony_provider_permission_denied
| SIP trunk credentials not authenticated | |
telephony_provider_unavailable
| Telephony provider is unavailable | How to retrieve this data: 1. **Dashboard**: Go to Call History, filter by your batch call, and view the disconnection reason for each call 2. **API**: Use the [List Calls]() endpoint to retrieve calls with their
disconnection_reason
field [(2) ]() 3. **Export**: Filter failed calls from Call History and export to CSV to re-upload only those contacts for retry [(3) ]() The
call_status
will show
not_connected
for calls that failed to connect, and
error
for system-level failures. [(1) ]()
Feel free to tag @AI Evy with additional questions. I also appreciate feedback, it helps me improve.
​ To learn more, see the sources I considered: [[1] Debug call disconnection](https://docs.retellai.com/reliability/debug-call-disconnect) [[2] List Calls](https://docs.retellai.com/api-references/list-calls) [[3] Batch call](https://discord.com/channels/1186424376300679209/1357080050343743508) ​
c
@AI Evy For failed/unsuccessful calls, what fields are available to get the failure reason? (e.g., disconnection_reason, call_unsuccessful_reason, error_message, etc.) What field contains the call duration? Is it call_duration_seconds, call_duration_ms, or calculated from start_timestamp and end_timestamp? For batch calls, what API endpoint should we use to fetch individual call details and results? (e.g., GET /v2/get-call/{call_id}, POST /v2/list-calls) What are all the possible values for call_status and disconnection_reason fields? For batch call campaigns, does the batch call response include aggregated metrics (total calls, completed, failed counts) or do we need to fetch each call individually? What webhook events are sent for call completion, and what fields are included in the payload?
a
Thanks for the follow-up, @Client Nexus. I'll get back to you soon.
### Answer ## 1. Failure Reason Fields The primary field for failure reasons is
disconnection_reason
. [(1) ]() Possible values include:
user_hangup
,
agent_hangup
,
call_transfer
,
voicemail_reached
,
inactivity
,
max_duration_reached
,
concurrency_limit_reached
,
no_valid_payment
,
scam_detected
,
dial_busy
,
dial_failed
,
dial_no_answer
,
invalid_destination
,
telephony_provider_permission_denied
,
telephony_provider_unavailable
,
sip_routing_error
,
marked_as_spam
,
user_declined
,
error_llm_websocket_open
,
error_llm_websocket_lost_connection
,
error_llm_websocket_runtime
,
error_llm_websocket_corrupt_payload
,
error_no_audio_received
,
error_asr
,
error_retell
,
error_unknown
,
error_user_not_joined
,
registered_call_timeout
## 2. Call Duration Field The field is
duration_ms
(duration in milliseconds) . You also have
start_timestamp
and
end_timestamp
(both in milliseconds since epoch) available after the call ends. ## 3. API Endpoints for Call Details - **Get single call**:
GET /v2/get-call/{call_id}
[(2) ]() - **List/filter calls**:
POST /v2/list-calls
[(1) ]() ## 4. Call Status Values
call_status
possible values:
registered
,
not_connected
,
ongoing
,
ended
,
error
## 5. Batch Call Aggregated Metrics I don't have documentation on whether batch call responses include aggregated metrics. You would likely need to fetch calls individually using the List Calls endpoint with filter criteria. ## 6. Webhook Events for Call Completion | Event | Description | Payload | |-------|-------------|---------| |
call_started
| Triggered when a new call begins | Basic call information | |
call_ended
| Triggered when a call completes, transfers, or encounter
s an error | All fields from the call object except
call_analysis
| |
call_analyzed
| Triggered when call analysis is complete | Full call data including
call_analysis
object | [(3) ]() Note: If the call did not connect (e.g.,
dial_failed
,
dial_no_answer
,
dial_busy
) , the
call_started
webhook will not be triggered, but
call_ended
and
call_analyzed
will still fire.
​ To learn more, see the sources I considered: [[1] List Calls](https://docs.retellai.com/api-references/list-calls) [[2] Get Call](https://docs.retellai.com/api-references/get-call) [[3] Webhook Overview](https://docs.retellai.com/features/webhook-overview) ​
Feel free to tag @AI Evy with additional questions. I also appreciate feedback, it helps me improve.
c
@AI Evy For calls that were NOT picked up (e.g., dial_no_answer, dial_busy, dial_failed), does Retell still provide a call_id? Or is call_id only available when the call connects? For calls that go to voicemail (voicemail_reached), is there a call_id and recording_url for the voicemail message left? In the batch call task response, which fields are always present vs. conditionally present based on call outcome? call_id - always or only on connection? start_timestamp / end_timestamp - always or only on connection? recording_url - available on task or only via GET /v2/get-call/{call_id}? For failed dial attempts (never connected), what data is available to show the user that an attempt was made? (timestamp, error code, duration of ring time, etc.)
a
Thanks for the follow-up, @Client Nexus. I'll get back to you soon.
### Answer ## 1. Call ID for Non-Connected Calls Yes, a
call_id
is provided even for calls that don't connect. The
call_status
field will show
not_connected
for outbound calls that failed to establish a connection, and the
disconnection_reason
will indicate why (e.g.,
dial_no_answer
,
dial_busy
,
dial_failed
) . [(1) ]() [(2) ]() ## 2. Voicemail Calls When
disconnection_reason
is
voicemail_reached
, there is a
call_id
and
recording_url
available after the call ends. [(1) ]() ## 3. Field Availability Based on Call Outcome Based on the Get Call API response documentation: | Field | Availability | |-------|-------------| |
call_id
| Always present (required field) | |
start_timestamp
| "Available after call starts" | |
end_timestamp
| "Available after call ends" | |
duration_ms
| "Available after call ends" | |
recording_url
| "Available after call ends" | For calls with status
not_connected
, the
start_timestamp
would not be populated since the call never started. ## 4. Data Available for Failed Dial Attempts For calls that never connected, the following data is available: -
call_id
- unique identifier for the attempt -
call_status
- will be
not_connected
-
disconnection_reason
- e.g.,
dial_busy
,
dial_no_answer
,
dial_failed
,
invalid_destination
,
marked_as_spam
[(2) ]() - The detailed log in the dashboard contains the SIP error code and error message for troubleshooting I don't have documentation on whether ring duration or exact attempt timestamps are provided for non-connected calls. Check out these potentially useful sources: - [Get Call](
et-call) - [Debug outbound connection issues]()
​ To learn more, see the sources I considered: [[1] Get Call](https://docs.retellai.com/api-references/get-call) [[2] Debug outbound connection issues](https://docs.retellai.com/reliability/debug-outbound-call) ​
Feel free to tag @AI Evy with additional questions. I also appreciate feedback, it helps me improve.
c
@AI Evy We're building a voice import feature where users can add ElevenLabs voices to their Retell workspace. 1. When calling Retell's "add voice" API endpoint, what exact parameters are required? - We're currently sending: voice_name, provider (elevenlabs), provider_voice_id (elevenlabs voice_id), and provider_voice_owner_id (public_owner_id from ElevenLabs) - Is this correct, or are we missing something? 2. For the provider_voice_owner_id field: - Must this always be the ElevenLabs public_owner_id? - What happens if the voice is a private voice (no public_owner_id)? 3. Is there a way to import/add a Retell built-in voice to a workspace without going through ElevenLabs? 4. What is the exact error response format when add-voice fails? We want to display helpful error messages to users.
a
Thanks for the follow-up, @Client Nexus. I'll get back to you soon.
​ To learn more, see the sources I considered: [[1] Add Voice](https://docs.retellai.com/api-references/add-voice) ​
### Answer ## 1. Required Parameters for Add Voice API The required parameters for the
POST /add-community-voice
endpoint are: [(1) ]() -
provider_voice_id
(string, required) — Voice id assigned by the provider -
voice_name
(string, required) — A custom name for the voice (1-200 characters) Optional parameters: -
voice_provider
(enum) — Available options:
elevenlabs
,
cartesia
,
minimax
-
public_user_id
(string) — Required for ElevenLabs only. User id of the voice owner. So your current approach is close, but note the field name is
public_user_id
(not
provider_voice_owner_id
) .
Copy code
javascript
import Retell from 'retell-sdk';
const client = new Retell({
  apiKey: 'YOUR_RETELL_API_KEY',
}) ;
const voiceResponse = await client.voice.addResource({
  provider_voice_id: 'provider_voice_id',
  voice_name: 'x',
}) ;
console.log(voiceResponse.provider) ;
## 2. public_user_id for ElevenLabs The documentation states this field is "Required for ElevenLabs only. User id of the voice owner." I don't have documentation on what happens if the voice is private (no public_owner_id) . ## 3. Adding Retell Built-in Voices I don't have documentation on whether Retell built-in voices can be added to a workspace without going through ElevenLabs. ## 4. Error Response Format The API returns these HTTP status codes: -
200
— Success -
400
— Bad request -
401
— Unauthorized -
429
— Rate limited -
500
— Server error I don't have documentation on the exact error response body format. Check out these potentially useful sources: - [Add Voice]() - [Search Voice]()
Feel free to tag @AI Evy with additional questions. I also appreciate feedback, it helps me improve.
c
@AI Evy "When using the add-community-voice endpoint with voice_provider: 'elevenlabs', does Retell fetch the voice directly from ElevenLabs public library using the public_user_id I provide? Or does it try to access the voice through my connected ElevenLabs API key?" "If I have an ElevenLabs voice_id and public_user_id from a public library voice that is NOT in my personal ElevenLabs library, can I still successfully add it to my Retell workspace via add-community-voice?" "What is the minimum required payload for add-community-voice with an ElevenLabs voice? Is it just voice_provider, provider_voice_id, public_user_id, and voice_name?"
a
Thanks for the follow-up, @Client Nexus. I'll get back to you soon.
Feel free to tag @AI Evy with additional questions. I also appreciate feedback, it helps me improve.
### Answer ## 1. How Retell Fetches ElevenLabs Voices I don't have documentation on whether Retell fetches the voice directly from ElevenLabs' public library using the
public_user_id
or through your connected ElevenLabs API key. ## 2. Adding Public Library Voices Not in Your Personal ElevenLabs Library I don't have documentation confirming whether you can add a public ElevenLabs voice that isn't in your personal library. A Discord discussion mentions that adding custom/private ElevenLabs voices (not community voices) was not supported at the time, with a request to add it to the backlog. [(1) ]() ## 3. Minimum Required Payload for ElevenLabs Voice Based on the API documentation, the minimum required fields are: [(2) ]() -
provider_voice_id
(string, required) — Voice id assigned by the provider -
voice_name
(string, required) — A custom name for the voice (1-200 characters) For ElevenLabs specifically,
public_user_id
is also required: > "Required for ElevenLabs only. User id of the voice owner." The
voice_provider
field is optional (enum:
elevenlabs
,
cartesia
,
minimax
) . So the minimum payload for ElevenLabs would be: -
provider_voice_id
-
voice_name
-
public_user_id
Check out these potentially useful sources: - [Add Voice]() - [Get Voice]() Would you like a general answer on typical patterns for third-party voice provider integrations?
​ To learn more, see the sources I considered: [[1] Add custom voice from 11labs via ID](https://discord.com/channels/1186424376300679209/1314742972113485875) [[2] Add Voice](https://docs.retellai.com/api-references/add-voice) ​
c
@AI Evy Does Retell populate the agent_id field in your webhook/callback when a call is made by an AI agent? Is there also an agent_name field in the metadata, or do we need to look up the agent name from the agents table using the agent_id?
a
Thanks for the follow-up, @Client Nexus. I'll get back to you soon.
### Answer ## 1.
agent_id
in Webhook Payload Yes, Retell populates the
agent_id
field in webhook payloads. [(1) ]() Based on the sample webhook payload:
Copy code
json
{
  "event": "call_ended",
  "call": {
    "call_type": "phone_call",
    "from_number": "+12137771234",
    "to_number": "+12137771235",
    "direction": "inbound",
    "call_id": "Jabr9TXYYJHfvl6Syypi88rdAHYHmcq6",
    "agent_id": "oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
    "call_status": "registered",
    "metadata": {},
    "retell_llm_dynamic_variables": {
      "customer_name": "John Doe"
    },
    "start_timestamp": 1714608475945,
    "end_timestamp": 1714608491736,
    "disconnection_reason": "user_hangup",
    "transcript": "...",
    "transcript_object": [ "[Object]", "[Object]", "[Object]", "[Object]" ],
    "transcript_with_tool_calls": [ "[Object]", "[Object]", "[Object]", "[Object]" ],
    "opt_out_sensitive_data_storage": false
  }
}
## 2.
agent_name
in Webhook Payload The
agent_name
field is not included in the webhook payload based on the documented sample. You would need to look up the agent name using the
agent_id
via the Get Agent or List Agents API endpoints. The agent object includes
agent_name
as a field. [(2) ]()
Copy code
javascript
import Retell from 'retell-sdk';
const client = new Retell({
  apiKey: 'YOUR_RETELL_API_KEY',
}) ;
const agentResponses = await client.agent.list() ;
console.log(agentResponses) ;
​ To learn more, see the sources I considered: [[1] Webhook Overview](https://docs.retellai.com/features/webhook-overview) [[2] List Voice Agents](https://docs.retellai.com/api-references/list-agents) ​
Feel free to tag @AI Evy with additional questions. I also appreciate feedback, it helps me improve.
Thanks for the follow-up, @Client Nexus. I'll get back to you soon.
c
@AI Evy
a
​ To learn more, see the sources I considered: [[1] Get Voice Agent](https://docs.retellai.com/api-references/get-agent) [[2] Get Call](https://docs.retellai.com/api-references/get-call) ​
### Answer It looks like you tagged me without a specific question. Based on your previous questions in this thread, here's a quick summary of what we've covered: - **Webhook data**:
agent_id
is included in webhook payloads, but
agent_name
is not—you need to look it up via the Get Agent API [(1) ]() - **Call data fields**:
disconnection_reason
,
duration_ms
,
start_timestamp
,
end_timestamp
,
recording_url
are available via Get Call API [(2) ]() - **Voice import**: The Add Voice endpoint requires
provider_voice_id
,
voice_name
, and
public_user_id
(for ElevenLabs) - **API endpoints**: Use
GET /v2/get-call/{call_id}
for single calls,
POST /v2/list-calls
for filtering Is there something specific you'd like to follow up on, or do you have a new question?
Feel free to tag @AI Evy with additional questions. I also appreciate feedback, it helps me improve.
c
@AI Evy For the main calls table (inbox filter): Does your webhook handler store the agent_id from Retell's payload into the calls table? The calls table structure may differ from agent_demo_calls. Call status updates: When Retell sends the call_ended webhook, does it update the agent_demo_calls record status from 'pending' to 'completed'?
a
Thanks for the follow-up, @Client Nexus. I'll get back to you soon.
### Answer These questions relate to your application's database design and webhook handler implementation, not Retell AI's platform behavior. However, here's what Retell provides: ## What Retell Sends in Webhooks Yes,
agent_id
is included in the webhook payload. The sample
call_ended
payload shows: [(1) ]()
Copy code
json
{
  "event": "call_ended",
  "call": {
    "call_type": "phone_call",
    "from_number": "+12137771234",
    "to_number": "+12137771235",
    "direction": "inbound",
    "call_id": "Jabr9TXYYJHfvl6Syypi88rdAHYHmcq6",
    "agent_id": "oBeDLoLOeuAbiuaMFXRtDOLriTJ5tSxD",
    "call_status": "registered",
    "metadata": {},
    "retell_llm_dynamic_variables": {
      "customer_name": "John Doe"
    },
    "start_timestamp": 1714608475945,
    "end_timestamp": 1714608491736,
    "disconnection_reason": "user_hangup",
    "transcript": "..."
  }
}
## What Retell Does NOT Do Retell does not update your database tables. Retell sends webhook events (
call_started
,
call_ended
,
call_analyzed
) to your endpoint—**your webhook handler** is responsible for: - Storing
agent_id
in your
calls
table - Updating record statuses from 'pending' to 'completed' - Any other database operations Whether your
calls
table vs
agent_demo_calls
table gets updated depends entirely on how you've implemented your webhook handler logic.
​ To learn more, see the sources I considered: [[1] Webhook Overview](https://docs.retellai.com/features/webhook-overview) ​
Feel free to tag @AI Evy with additional questions. I also appreciate feedback, it helps me improve.