curl --request POST \
--url https://app.famulor.io/api/v1/calls \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"assistant_id": "a1b2c3d4-0000-4000-8000-000000000001",
"to_number": "+4915123456789",
"lead": {
"name": "Jane Doe",
"company": "Acme Corp"
}
}
'import requests
url = "https://app.famulor.io/api/v1/calls"
payload = {
"assistant_id": "a1b2c3d4-0000-4000-8000-000000000001",
"to_number": "+4915123456789",
"lead": {
"name": "Jane Doe",
"company": "Acme Corp"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
assistant_id: 'a1b2c3d4-0000-4000-8000-000000000001',
to_number: '+4915123456789',
lead: {name: 'Jane Doe', company: 'Acme Corp'}
})
};
fetch('https://app.famulor.io/api/v1/calls', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.famulor.io/api/v1/calls",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'assistant_id' => 'a1b2c3d4-0000-4000-8000-000000000001',
'to_number' => '+4915123456789',
'lead' => [
'name' => 'Jane Doe',
'company' => 'Acme Corp'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.famulor.io/api/v1/calls"
payload := strings.NewReader("{\n \"assistant_id\": \"a1b2c3d4-0000-4000-8000-000000000001\",\n \"to_number\": \"+4915123456789\",\n \"lead\": {\n \"name\": \"Jane Doe\",\n \"company\": \"Acme Corp\"\n }\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(string(body))
}HttpResponse<String> response = Unirest.post("https://app.famulor.io/api/v1/calls")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"assistant_id\": \"a1b2c3d4-0000-4000-8000-000000000001\",\n \"to_number\": \"+4915123456789\",\n \"lead\": {\n \"name\": \"Jane Doe\",\n \"company\": \"Acme Corp\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.famulor.io/api/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 \"assistant_id\": \"a1b2c3d4-0000-4000-8000-000000000001\",\n \"to_number\": \"+4915123456789\",\n \"lead\": {\n \"name\": \"Jane Doe\",\n \"company\": \"Acme Corp\"\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "c1b2c3d4-0000-4000-8000-000000000010",
"assistant_id": "a1b2c3d4-0000-4000-8000-000000000001",
"phone_number_id": "p1b2c3d4-0000-4000-8000-000000000020",
"direction": "outbound",
"from_number": "+4930123456",
"to_number": "+4915123456789",
"status": "queued",
"started_at": null,
"answered_at": null,
"ended_at": null,
"duration_sec": null,
"transcript": null,
"summary": null,
"evaluation": null,
"metadata": {},
"created_at": "2026-07-01T10:00:00Z",
"updated_at": "2026-07-01T10:03:30Z"
}
}{
"error": {
"code": "invalid_request",
"message": "\"to_number\" is required (E.164 format, e.g. +4930123456)."
}
}{
"error": {
"code": "unauthorized",
"message": "Invalid API key."
}
}{
"error": {
"code": "forbidden",
"message": "This API key is missing the required scope \"assistants:write\"."
}
}{
"error": {
"code": "not_found",
"message": "Assistant not found"
}
}{
"error": {
"code": "telephony_configuration_error",
"message": "No outbound-capable number is connected to this assistant or workspace."
}
}{
"error": {
"code": "telephony_unavailable",
"message": "Outbound calling is temporarily unavailable."
}
}Start an outbound call
Places an outbound call: the assistant must be active and needs an outbound-capable phone number (assigned to it, or passed via phone_number_id). Returns the created call immediately (status queued) — poll GET /calls/{id} or use the assistant’s webhook for the result and provider-neutral failure guidance. Required scope: calls:write (keys without scope restrictions have full access).
curl --request POST \
--url https://app.famulor.io/api/v1/calls \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"assistant_id": "a1b2c3d4-0000-4000-8000-000000000001",
"to_number": "+4915123456789",
"lead": {
"name": "Jane Doe",
"company": "Acme Corp"
}
}
'import requests
url = "https://app.famulor.io/api/v1/calls"
payload = {
"assistant_id": "a1b2c3d4-0000-4000-8000-000000000001",
"to_number": "+4915123456789",
"lead": {
"name": "Jane Doe",
"company": "Acme Corp"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
assistant_id: 'a1b2c3d4-0000-4000-8000-000000000001',
to_number: '+4915123456789',
lead: {name: 'Jane Doe', company: 'Acme Corp'}
})
};
fetch('https://app.famulor.io/api/v1/calls', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.famulor.io/api/v1/calls",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'assistant_id' => 'a1b2c3d4-0000-4000-8000-000000000001',
'to_number' => '+4915123456789',
'lead' => [
'name' => 'Jane Doe',
'company' => 'Acme Corp'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.famulor.io/api/v1/calls"
payload := strings.NewReader("{\n \"assistant_id\": \"a1b2c3d4-0000-4000-8000-000000000001\",\n \"to_number\": \"+4915123456789\",\n \"lead\": {\n \"name\": \"Jane Doe\",\n \"company\": \"Acme Corp\"\n }\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(string(body))
}HttpResponse<String> response = Unirest.post("https://app.famulor.io/api/v1/calls")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"assistant_id\": \"a1b2c3d4-0000-4000-8000-000000000001\",\n \"to_number\": \"+4915123456789\",\n \"lead\": {\n \"name\": \"Jane Doe\",\n \"company\": \"Acme Corp\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.famulor.io/api/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 \"assistant_id\": \"a1b2c3d4-0000-4000-8000-000000000001\",\n \"to_number\": \"+4915123456789\",\n \"lead\": {\n \"name\": \"Jane Doe\",\n \"company\": \"Acme Corp\"\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "c1b2c3d4-0000-4000-8000-000000000010",
"assistant_id": "a1b2c3d4-0000-4000-8000-000000000001",
"phone_number_id": "p1b2c3d4-0000-4000-8000-000000000020",
"direction": "outbound",
"from_number": "+4930123456",
"to_number": "+4915123456789",
"status": "queued",
"started_at": null,
"answered_at": null,
"ended_at": null,
"duration_sec": null,
"transcript": null,
"summary": null,
"evaluation": null,
"metadata": {},
"created_at": "2026-07-01T10:00:00Z",
"updated_at": "2026-07-01T10:03:30Z"
}
}{
"error": {
"code": "invalid_request",
"message": "\"to_number\" is required (E.164 format, e.g. +4930123456)."
}
}{
"error": {
"code": "unauthorized",
"message": "Invalid API key."
}
}{
"error": {
"code": "forbidden",
"message": "This API key is missing the required scope \"assistants:write\"."
}
}{
"error": {
"code": "not_found",
"message": "Assistant not found"
}
}{
"error": {
"code": "telephony_configuration_error",
"message": "No outbound-capable number is connected to this assistant or workspace."
}
}{
"error": {
"code": "telephony_unavailable",
"message": "Outbound calling is temporarily unavailable."
}
}Authorizations
API key (fam_..., created under Settings → API Keys) or an OAuth 2.0 access token (fam_at_...). Keys can be restricted to scopes such as assistants:read, calls:write, campaigns:write, automations:read, dashboards:read, dashboards:write, leads:write, segments:write, phone_numbers:write, sip_trunks:write, knowledge:write, voices:read, billing:read, settings:write, platform:read, platform:write; a *:write scope implies the matching *:read. Automation and dashboard endpoints also accept the legacy calls:* scope. Keys without scope restrictions have full access.
Body
Assistant that runs the call. Must be active.
Destination in E.164 format, e.g. +4930123456.
Arbitrary key/value context injected into the conversation (e.g. the callee's name).
Optional explicit caller ID (one of your phone numbers). Defaults to the number assigned to the assistant.
Response
The created call (status queued).
Show child attributes
Show child attributes