> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.agentphone.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.agentphone.ai/_mcp/server.

# Create Outbound Call

POST https://api.agentphone.ai/v1/calls
Content-Type: application/json

Initiate an outbound call.

This endpoint allows you to programmatically make phone calls from your agent
to any phone number. Use `fromNumberId` to pick which of the agent's numbers
to use as caller ID; if omitted, the first assigned number is used.

Flow:
1. Validates the agent belongs to your account and has a phone number
2. Initiates a call from the agent's number to the destination
3. When recipient answers, speaks the initial greeting (if provided)
4. Listens for recipient's speech and sends to your webhook
5. Continues conversation using your webhook responses

Reference: https://docs.agentphone.ai/api-reference/calls/create-outbound-call-v-1-calls-post

## Authentication

- `Authorization` header (bearer token, required) — Bearer authentication of the form `Bearer <token>`, where token is your auth token.

## Request

### Headers

- `X-Sub-Account-Id` (string, optional) — Target a sub-account. Pass a sub-account ID to scope this request. Omit to use the master account.

### Body (application/json)

This endpoint expects a CreateOutboundCallRequest.

- `agentId` (string, required) — Agent ID to make the call from
- `toNumber` (string, required) — Phone number to call (E.164 format)
- `fromNumberId` (string, optional, nullable) — Optional phone number ID to use as caller ID. Must belong to the agent. If omitted, the agent's first assigned number is used.
- `initialGreeting` (string, optional, nullable) — Optional initial greeting to speak when recipient answers. Pass an empty string to have the agent stay silent and wait for the recipient to speak first.
- `voice` (string, optional, nullable) — Voice ID override for this call (uses agent's configured voice if omitted)
- `systemPrompt` (string, optional, nullable) — When provided, uses a built-in LLM for the conversation instead of forwarding to a webhook. The prompt defines the AI's personality and conversation topic.
- `modelTier` (enum, optional) — Optional model tier override for this call's built-in conversation. Only applies when ``systemPrompt`` is provided; defaults to the agent's configured modelTier.
  - Allowed values: `turbo`, `balanced`, `max`
- `variables` (map from string to string, optional, nullable) — Optional per-call dynamic variables. Values are substituted into `{{var_name}}` placeholders in the agent's system prompt and initial greeting at call time. Requires either `systemPrompt` or a hosted-mode agent.
- `callScreeningIdentity` (string, optional, nullable) — For outbound calls that hit an automated call screener (e.g. iOS 26 Call Screening or Android Call Screen): the identity the agent gives when asked who is calling. Overrides the agent's stored default for this call. Both identity and purpose are required to enable screening; if only a purpose is set, the agent's name is used.
- `callScreeningPurpose` (string, optional, nullable) — For outbound calls that hit an automated call screener: the purpose the agent gives when asked why it is calling. Overrides the agent's stored default for this call.
- `disableRecording` (boolean, optional, default: false) — When true, no audio recording is stored for this call. The transcript is still captured and available via the transcript endpoints and the agent.call_ended webhook. Useful for calls where a party has not consented to being recorded (e.g. two-party consent states).

## Response

### 200

Successful Response

- `any`

## Errors

### 422 Unprocessable Entity Error

Validation Error

- `detail` (list of ValidationError, optional)

## Types

### ValidationError

- `loc` (list of ValidationErrorLocItems, required)
- `msg` (string, required)
- `type` (string, required)

### ValidationErrorLocItems

## Examples

**Request**

```json
{
  "agentId": "string",
  "toNumber": "string"
}
```

**SDK Code**

```python
import requests

url = "https://api.agentphone.ai/v1/calls"

payload = {
    "agentId": "string",
    "toNumber": "string"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.agentphone.ai/v1/calls';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"agentId":"string","toNumber":"string"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.agentphone.ai/v1/calls"

	payload := strings.NewReader("{\n  \"agentId\": \"string\",\n  \"toNumber\": \"string\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.agentphone.ai/v1/calls")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"agentId\": \"string\",\n  \"toNumber\": \"string\"\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.agentphone.ai/v1/calls")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"agentId\": \"string\",\n  \"toNumber\": \"string\"\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.agentphone.ai/v1/calls', [
  'body' => '{
  "agentId": "string",
  "toNumber": "string"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.agentphone.ai/v1/calls");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"agentId\": \"string\",\n  \"toNumber\": \"string\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "agentId": "string",
  "toNumber": "string"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.agentphone.ai/v1/calls")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```