> ## Documentation Index
> Fetch the complete documentation index at: https://docs.topcalls.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Making Calls

> Learn how to make AI phone calls via the TopCalls API. From simple reminders to complex conversations with function calling.

## Making Your First Call

The simplest way to make a call is with a `task`:

```bash theme={null}
curl -X POST https://api.topcalls.ai/v1/calls \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "+14155551234",
    "from_number": "+18005551234",
    "task": "You are calling to confirm John's dental appointment tomorrow at 3 PM. Be friendly and professional.",
    "voice": "alloy"
  }'
```

## Simple vs Advanced Configuration

### Simple Mode (Task)

For straightforward calls:

```json theme={null}
{
  "phone_number": "+14155551234",
  "task": "Call to confirm appointment...",
  "voice": "alloy"
}
```

### Advanced Mode (Instructions)

For complex conversations with full control:

```json theme={null}
{
  "phone_number": "+14155551234",
  "instructions": "You are Rachel, a senior scheduler...",
  "first_sentence": "Hi, this is Rachel from Bright Dental...",
  "voice": "alloy",
  "temperature": 0.7,
  "max_duration": 10
}
```

## Required Parameters

| Parameter                | Type   | Description                                       |
| ------------------------ | ------ | ------------------------------------------------- |
| `phone_number`           | string | Destination number (E.164 format: `+14155551234`) |
| `task` OR `instructions` | string | What the AI should do (one is required)           |

## Optional Parameters

### Voice & Mode

```json theme={null}
{
  "voice": "alloy",
  "mode": "realtime"
}
```

Check available voices via `GET /v1/voices/builtin` and available models via `GET /v1/models`.

<Note>
  **Realtime Mode** provides the lowest latency (\~200-500ms) and most natural conversations. **Legacy Mode** gives you full control over voice selection and language/dialect settings. Check model and voice availability via the API.
</Note>

### Call Control

```json theme={null}
{
  "from_number": "+18005551234",
  "max_duration": 10,
  "first_sentence": "Hi, this is Rachel...",
  "background_audio": "office",
  "background_audio_gain": "medium"
}
```

### Context & Personalization

```json theme={null}
{
  "lead_context": {
    "patient_name": "John Smith",
    "appointment_date": "2025-12-24"
  },
  "campaign_id": "0c4f4b9e-8b0a-4f57-9d3e-2f1a7c9d1234"
}
```

`lead_context` values fill `{{variable}}` placeholders in your instructions and first sentence. Pass `lead_id` instead and the gateway builds the context from the stored lead record. `campaign_id` gives the agent the campaign's attached knowledge base.

### Webhooks

```json theme={null}
{
  "webhook_url": "https://your-app.com/webhooks/call-complete"
}
```

The URL receives one payload when the call completes, fails, or is cancelled. To limit which outcomes fire it, pass `webhook_call_status_filter` with the statuses you care about (for example `["completed", "failed"]`); leave it out to receive every outcome. For account-wide or disposition-filtered delivery, use [webhook subscriptions](/guides/webhooks).

### Custom Call Summaries

Every finished call includes an AI-written summary in the webhook payload and call record. Pass `summary_prompt` to control what it covers:

```json theme={null}
{
  "summary_prompt": "List the objections raised and the agreed callback time."
}
```

When omitted, the default summary style applies.

### More Options

`POST /v1/calls` also accepts `max_duration` (minutes, up to 60), `background_audio` and `background_audio_gain`, `bot_protection_enabled`, `analysis_schema` for structured extraction, STT and TTS tuning knobs for legacy mode, and an `Idempotency-Key` header for safe retries. See the [API reference](/api-reference/introduction) for every field.

## Complete Example: Appointment Reminder

```json theme={null}
{
  "phone_number": "+14155551234",
  "from_number": "+18005551234",
  "instructions": "You are Rachel, a friendly appointment coordinator at Bright Dental. Your goal is to confirm {{patient_name}}'s appointment on {{appointment_date}} at {{appointment_time}}. Be warm, professional, and concise.",
  "first_sentence": "Hi {{patient_name}}, this is Rachel from Bright Dental. I'm calling to confirm your appointment tomorrow at {{appointment_time}}.",
  "voice": "alloy",
  "mode": "realtime",
  "temperature": 0.7,
  "max_duration": 5,
  "lead_context": {
    "patient_name": "John Smith",
    "appointment_date": "2025-12-24",
    "appointment_time": "3:00 PM"
  },
  "webhook_url": "https://your-app.com/webhooks/call-complete"
}
```

## Response

```json theme={null}
{
  "call_id": "564d4fd4-03bc-400a-abe0-05540fbeff88",
  "status": "queued"
}
```

## Checking Call Status

Use the `call_id` to check status:

```bash theme={null}
curl https://api.topcalls.ai/v1/calls/564d4fd4-03bc-400a-abe0-05540fbeff88 \
  -H "Authorization: Bearer YOUR_API_KEY"
```

## Call Statuses

| Status        | Description                          |
| ------------- | ------------------------------------ |
| `pending`     | Call created, not yet queued         |
| `queued`      | Call waiting to be dispatched        |
| `in_progress` | Call is active                       |
| `completed`   | Call finished successfully           |
| `failed`      | Call failed (busy, no answer, error) |
| `cancelled`   | Call was cancelled                   |

## Call Ending Behavior

The AI agent can end calls gracefully when the conversation is complete. This happens automatically when:

* The user says goodbye or thanks you
* All questions have been answered
* The user explicitly asks to end the call
* The conversation naturally concludes

The AI will speak a contextual farewell message before hanging up.

<Tip>
  You can influence this behavior in your instructions: "Always confirm the next steps before ending the call" or "Ask if there's anything else before saying goodbye."
</Tip>

## Common Patterns

### Pattern 1: Simple Reminder

```json theme={null}
{
  "phone_number": "+14155551234",
  "task": "Remind the user about their appointment tomorrow at 3 PM. Be brief and friendly.",
  "voice": "alloy"
}
```

### Pattern 2: Multi-Language Call

```json theme={null}
{
  "phone_number": "+14155551234",
  "instructions": "Habla solo en español. Eres un asistente de servicio al cliente...",
  "mode": "legacy",
  "stt_language": "es-ES",
  "voice": "your-spanish-voice-id"
}
```

## Error Handling

### Invalid Phone Number

```json theme={null}
{
  "status": 400,
  "title": "Invalid request body",
  "errors": [
    {
      "path": "phone_number",
      "message": "Phone number must be in E.164 format (e.g., +14155551234)"
    }
  ]
}
```

### Insufficient Quota

```json theme={null}
{
  "status": 402,
  "title": "Insufficient Quota",
  "detail": "You need 5 minutes but have 3.5 remaining"
}
```

## Best Practices

### Do This

* **Validate phone numbers**: Use E.164 format (`+14155551234`)
* **Set first\_sentence**: Control how the call starts
* **Use lead\_context**: Personalize with variables
* **Configure webhooks**: Get notified when calls complete
* **Test first**: Try with your own number before production

### Avoid This

* **Invalid formats**: Always use E.164 format
* **Missing instructions**: Provide clear task or instructions
* **Too long**: Keep instructions focused (200-500 words)
* **Ignore errors**: Handle API errors gracefully

## Next Steps

<CardGroup cols={2}>
  <Card title="Function Calling" icon="screwdriver-wrench" href="/guides/function-calling">
    Give your AI tools to interact with your systems.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/guides/webhooks">
    Receive real-time notifications when calls complete.
  </Card>
</CardGroup>
