curl --request POST \
--url https://app.famulor.io/api/v1/calls/actions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"action": "reanalyze",
"call_ids": [
"c1b2c3d4-0000-4000-8000-000000000010"
]
}
'import requests
url = "https://app.famulor.io/api/v1/calls/actions"
payload = {
"action": "reanalyze",
"call_ids": ["c1b2c3d4-0000-4000-8000-000000000010"]
}
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({action: 'reanalyze', call_ids: ['c1b2c3d4-0000-4000-8000-000000000010']})
};
fetch('https://app.famulor.io/api/v1/calls/actions', 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/actions",
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([
'action' => 'reanalyze',
'call_ids' => [
'c1b2c3d4-0000-4000-8000-000000000010'
]
]),
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/actions"
payload := strings.NewReader("{\n \"action\": \"reanalyze\",\n \"call_ids\": [\n \"c1b2c3d4-0000-4000-8000-000000000010\"\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/actions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"action\": \"reanalyze\",\n \"call_ids\": [\n \"c1b2c3d4-0000-4000-8000-000000000010\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.famulor.io/api/v1/calls/actions")
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 \"action\": \"reanalyze\",\n \"call_ids\": [\n \"c1b2c3d4-0000-4000-8000-000000000010\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": {
"ok": 123,
"failed": 123,
"results": [
{
"call_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"ok": true,
"error": "<string>",
"detail": {}
}
]
}
}{
"error": {
"code": "rate_limited",
"message": "Too many requests. Retry after the indicated delay."
}
}{
"error": {
"code": "internal_error",
"message": "Request protection is temporarily unavailable."
}
}Run call history actions
Re-evaluate post-call analysis, start an enhanced re-transcription from one call recording, resend call.completed webhooks, or add/remove the contact phone from the suppression (blacklist) list. retranscribe requires exactly one call ID and returns the rounded recording minutes and credit quote. Other actions process up to 50 call IDs per request. Required scope: calls:write. Blacklist actions also need suppression:write or campaigns:write (unrestricted keys have full access).
curl --request POST \
--url https://app.famulor.io/api/v1/calls/actions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"action": "reanalyze",
"call_ids": [
"c1b2c3d4-0000-4000-8000-000000000010"
]
}
'import requests
url = "https://app.famulor.io/api/v1/calls/actions"
payload = {
"action": "reanalyze",
"call_ids": ["c1b2c3d4-0000-4000-8000-000000000010"]
}
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({action: 'reanalyze', call_ids: ['c1b2c3d4-0000-4000-8000-000000000010']})
};
fetch('https://app.famulor.io/api/v1/calls/actions', 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/actions",
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([
'action' => 'reanalyze',
'call_ids' => [
'c1b2c3d4-0000-4000-8000-000000000010'
]
]),
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/actions"
payload := strings.NewReader("{\n \"action\": \"reanalyze\",\n \"call_ids\": [\n \"c1b2c3d4-0000-4000-8000-000000000010\"\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/actions")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"action\": \"reanalyze\",\n \"call_ids\": [\n \"c1b2c3d4-0000-4000-8000-000000000010\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.famulor.io/api/v1/calls/actions")
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 \"action\": \"reanalyze\",\n \"call_ids\": [\n \"c1b2c3d4-0000-4000-8000-000000000010\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": {
"ok": 123,
"failed": 123,
"results": [
{
"call_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"ok": true,
"error": "<string>",
"detail": {}
}
]
}
}{
"error": {
"code": "rate_limited",
"message": "Too many requests. Retry after the indicated delay."
}
}{
"error": {
"code": "internal_error",
"message": "Request protection is temporarily unavailable."
}
}Authorizations
API key (fam_..., created under Settings → API Keys) or an OAuth 2.0 access token (fam_at_...). REST operations also require API Access for the credential's workspace. Keys can be restricted to scopes such as assistants:read, calls:write, campaigns:write, automations:read, dashboards:read, dashboards:write, leads:write, segments:write, loop:read, loop:write, phone_numbers:write, sip_trunks:write, knowledge:write, voices:read, billing:read, billing:write, 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 within the workspace's available capabilities.
Body
Response
Per-call results.
Show child attributes
Show child attributes