Calls

Make outbound calls and handle inbound calls with AI agents

Introduction

Calls are the core interaction in Chorus - phone conversations between your AI agents and real people. You can make outbound calls programmatically via the API, or receive inbound calls on your configured phone numbers.

Call Types

Outbound Calls

Outbound calls are initiated by your application through the API. Common use cases:

  • Customer follow-ups
  • Appointment reminders
  • Lead qualification
  • Survey collection
  • Order confirmations
  • Support outreach

Inbound Calls

Inbound calls are received on your configured phone numbers. When someone calls your number:

  1. The call arrives at your telephony provider
  2. Provider routes to Chorus via webhook
  3. Chorus assigns the configured agent
  4. Conversation begins automatically

Making Outbound Calls

Basic Outbound Call

POST /v1/calls
{
  "agentId": "agent-uuid",
  "phoneNumberId": "phone-uuid",
  "to": "+15551234567"
}

With Context Variables

Pass dynamic data to personalize the conversation:

POST /v1/calls
{
  "agentId": "agent-uuid",
  "phoneNumberId": "phone-uuid",
  "to": "+15551234567",
  "contextVariables": {
    "customer_name": "Jane Smith",
    "order_id": "12345",
    "delivery_date": "2024-02-15"
  },
  "metadata": {
    "campaign": "order-followup",
    "source": "shopify"
  }
}

Required Fields

FieldTypeDescription
agentIdUUIDThe agent to handle the call
phoneNumberIdUUIDYour phone number to call from
tostringDestination phone number (E.164 format recommended)

Optional Fields

FieldTypeDescription
contextVariablesobjectDynamic data for the conversation (used in templates)
metadataobjectAdditional data stored with the call (not used by agent)

Context Variables

Context variables allow you to inject dynamic data into your agent's system prompt and greeting. Learn more in the Context Variables guide.

Example system prompt with variables:

You are calling {{customer_name}} about order #{{order_id}}.

Order Details:
- Products: {{products}}
- Total: {{total}}
- Delivery Date: {{delivery_date}}

Ask if they have any questions about their order.

When making the call:

{
  "contextVariables": {
    "customer_name": "John Doe",
    "order_id": "12345",
    "products": "Widget Pro, Gadget Plus",
    "total": "$149.99",
    "delivery_date": "Tomorrow"
  }
}

Test Calls (Browser-Based)

You can test your agents directly from the Chorus dashboard without making real phone calls. This uses browser-based audio for quick iteration on your agent's behavior.

Call Flow

Outbound Call Flow

sequenceDiagram
    participant API as Your App
    participant Platform as Chorus Platform
    participant Provider as Telephony Provider
    participant Phone as Customer Phone
    participant Agent as AI Agent Runtime

    API->>Platform: POST /v1/calls
    Platform->>Provider: Initiate call
    Provider->>Phone: Ring
    Phone->>Provider: Answer
    Provider->>Platform: Call connected webhook
    Platform->>Agent: Start conversation
    Agent-->>Phone: Audio stream
    Phone-->>Agent: Audio stream
    Agent->>Platform: Call ended
    Platform->>API: Webhook: call.completed

Inbound Call Flow

sequenceDiagram
    participant Phone as Caller
    participant Provider as Telephony Provider
    participant Platform as Chorus Platform
    participant Agent as AI Agent Runtime

    Phone->>Provider: Dial number
    Provider->>Platform: Inbound webhook
    Platform->>Platform: Load agent config
    Platform->>Provider: TwiML/Instructions
    Provider->>Agent: Open audio stream
    Agent-->>Phone: Conversation
    Phone-->>Agent: Conversation
    Agent->>Platform: Call ended
    Platform->>Platform: Process post-call

Call Status

Calls progress through several statuses:

StatusDescription
queuedCall created, waiting to be placed
ringingCall is ringing
in_progressCall is active, conversation happening
completedCall ended normally
failedCall failed to connect
no_answerCall was not answered

Call Details

After a call completes, retrieve full details:

GET /v1/calls/{call-id}

{
  "data": {
    "id": "call-uuid",
    "organizationId": "org-uuid",
    "agentId": "agent-uuid",
    "phoneNumberId": "phone-uuid",
    "status": "completed",
    "direction": "outbound",
    "customerNumber": "+15551234567",
    "durationSeconds": 245,
    "cost": 0.25,
    "turnCount": 12,
    "recordingUrl": "https://...",
    "transcript": [
      { "role": "assistant", "content": "Hello, how can I help you today?" },
      { "role": "user", "content": "I'd like to check on my order." }
    ],
    "analysis": {
      "summary": "Customer inquired about order status...",
      "extractions": {
        "customer_interest": "premium plan",
        "follow_up_needed": true
      }
    },
    "endedReason": "agent_ended",
    "contextVariables": { "customer_name": "John" },
    "metadata": { "campaign": "order-followup" },
    "startedAt": "2024-01-15T10:30:00Z",
    "endedAt": "2024-01-15T10:34:05Z",
    "createdAt": "2024-01-15T10:29:45Z"
  }
}

Recordings and Transcripts

Completed calls include:

  • Recording URL (recordingUrl): Audio recording of the conversation
  • Transcript (transcript): Full conversation transcript as an array of {role, content} objects
  • Analysis (analysis): Post-call analysis with summary and extractions fields

These are included in the call detail response (GET /v1/calls/{id}) and webhook payloads. Note that transcripts and analysis are only included in single-call detail responses, not in list responses.

Post-Call Data

Extracted Data

If your agent has a postCallExtractionSchema configured, structured data is extracted and available in the analysis field:

{
  "analysis": {
    "summary": "Customer called about order status...",
    "extractions": {
      "customer_satisfaction": "satisfied",
      "issue_resolved": true,
      "follow_up_date": "2024-02-01",
      "product_interest": "premium"
    }
  }
}

Webhooks

Receive notifications when calls complete. See the Webhooks guide for details.

POST https://your-app.com/webhook
{
  "event": "call.completed",
  "callId": "call-uuid",
  "status": "completed",
  "duration": 245,
  "extractedData": {...},
  "summary": "Customer inquiry about...",
  "recordingUrl": "https://..."
}

Call Duration Limits

Agents can be configured with maximum call duration (30-3600 seconds). Calls automatically end when this limit is reached.

Default: 600 seconds (10 minutes)

Cost Tracking

Calls include cost tracking if your organization is on a paid plan. Costs include:

  • Telephony provider charges (Twilio/SIP)
  • AI inference costs
  • Text-to-speech costs
  • Speech-to-text costs

View costs in the call details and dashboard.

Best Practices

Outbound Calls

  1. Use Context Variables: Personalize conversations with customer data
  2. Set Metadata: Track campaigns, sources, and custom identifiers
  3. Handle Failures: Implement retry logic for failed calls
  4. Respect Time Zones: Consider the recipient's local time
  5. Compliance: Follow TCPA and local regulations

All Calls

  1. Configure Webhooks: Get real-time notifications
  2. Monitor Durations: Set appropriate max duration limits
  3. Review Transcripts: Continuously improve agent performance
  4. Extract Data: Use extraction schemas for structured data
  5. Test Thoroughly: Use test calls before production

Troubleshooting

Call Not Connecting

Check:

  • Phone number format (use E.164: +15551234567)
  • Phone number configuration is correct
  • Agent is active
  • Organization has sufficient balance

Poor Audio Quality

Possible causes:

  • Network connectivity issues
  • SIP configuration problems
  • Provider issues

Solutions:

  • Test from different networks
  • Verify SIP settings
  • Check provider status

Agent Not Responding

Check:

  • Agent is active and properly configured
  • System prompt is clear and actionable
  • Model and voice are correctly set
  • No API errors in logs

API Reference

Next Steps

Last updated on