curl --request POST \
--url https://app.famulor.io/api/v1/phone-numbers \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"number": "+4930123456",
"country": "DE",
"type": "local",
"purchase_token": "eyJ2IjoxLCJvZmZlciI6IntcIn...",
"assistant_id": "a1b2c3d4-0000-4000-8000-000000000001"
}
'import requests
url = "https://app.famulor.io/api/v1/phone-numbers"
payload = {
"number": "+4930123456",
"country": "DE",
"type": "local",
"purchase_token": "eyJ2IjoxLCJvZmZlciI6IntcIn...",
"assistant_id": "a1b2c3d4-0000-4000-8000-000000000001"
}
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({
number: '+4930123456',
country: 'DE',
type: 'local',
purchase_token: 'eyJ2IjoxLCJvZmZlciI6IntcIn...',
assistant_id: 'a1b2c3d4-0000-4000-8000-000000000001'
})
};
fetch('https://app.famulor.io/api/v1/phone-numbers', 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/phone-numbers",
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([
'number' => '+4930123456',
'country' => 'DE',
'type' => 'local',
'purchase_token' => 'eyJ2IjoxLCJvZmZlciI6IntcIn...',
'assistant_id' => 'a1b2c3d4-0000-4000-8000-000000000001'
]),
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/phone-numbers"
payload := strings.NewReader("{\n \"number\": \"+4930123456\",\n \"country\": \"DE\",\n \"type\": \"local\",\n \"purchase_token\": \"eyJ2IjoxLCJvZmZlciI6IntcIn...\",\n \"assistant_id\": \"a1b2c3d4-0000-4000-8000-000000000001\"\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/phone-numbers")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"number\": \"+4930123456\",\n \"country\": \"DE\",\n \"type\": \"local\",\n \"purchase_token\": \"eyJ2IjoxLCJvZmZlciI6IntcIn...\",\n \"assistant_id\": \"a1b2c3d4-0000-4000-8000-000000000001\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.famulor.io/api/v1/phone-numbers")
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 \"number\": \"+4930123456\",\n \"country\": \"DE\",\n \"type\": \"local\",\n \"purchase_token\": \"eyJ2IjoxLCJvZmZlciI6IntcIn...\",\n \"assistant_id\": \"a1b2c3d4-0000-4000-8000-000000000001\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "p1b2c3d4-0000-4000-8000-000000000020",
"number": "+4930123456",
"assistant_id": "a1b2c3d4-0000-4000-8000-000000000001",
"sip_trunk_id": null,
"direction_inbound": false,
"direction_outbound": false,
"source": "platform",
"country_iso": "DE",
"number_type": "local",
"monthly_price_cents": 500,
"status": "pending",
"purchased_by": "u1b2c3d4-0000-4000-8000-000000000003",
"released_at": null,
"created_at": "2026-06-15T12:00:00Z",
"updated_at": "2026-07-01T09:00:00Z",
"checkout_url": "https://checkout.stripe.com/c/pay/cs_live_example"
}
}Buy a phone number
Starts a payment-confirmed marketplace purchase. The response is pending and includes checkout_url. Open this URL to review and confirm payment; it may open an authenticated in-app checkout or a hosted payment page. Routing and call access are provisioned only after verified payment. Failed, expired, or unpaid purchases release the held number. Requires a user-scoped API key. Pick a number from GET /phone-numbers/available first and pass its short-lived purchase_token unchanged. Required scope: phone_numbers:write.
curl --request POST \
--url https://app.famulor.io/api/v1/phone-numbers \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"number": "+4930123456",
"country": "DE",
"type": "local",
"purchase_token": "eyJ2IjoxLCJvZmZlciI6IntcIn...",
"assistant_id": "a1b2c3d4-0000-4000-8000-000000000001"
}
'import requests
url = "https://app.famulor.io/api/v1/phone-numbers"
payload = {
"number": "+4930123456",
"country": "DE",
"type": "local",
"purchase_token": "eyJ2IjoxLCJvZmZlciI6IntcIn...",
"assistant_id": "a1b2c3d4-0000-4000-8000-000000000001"
}
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({
number: '+4930123456',
country: 'DE',
type: 'local',
purchase_token: 'eyJ2IjoxLCJvZmZlciI6IntcIn...',
assistant_id: 'a1b2c3d4-0000-4000-8000-000000000001'
})
};
fetch('https://app.famulor.io/api/v1/phone-numbers', 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/phone-numbers",
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([
'number' => '+4930123456',
'country' => 'DE',
'type' => 'local',
'purchase_token' => 'eyJ2IjoxLCJvZmZlciI6IntcIn...',
'assistant_id' => 'a1b2c3d4-0000-4000-8000-000000000001'
]),
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/phone-numbers"
payload := strings.NewReader("{\n \"number\": \"+4930123456\",\n \"country\": \"DE\",\n \"type\": \"local\",\n \"purchase_token\": \"eyJ2IjoxLCJvZmZlciI6IntcIn...\",\n \"assistant_id\": \"a1b2c3d4-0000-4000-8000-000000000001\"\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/phone-numbers")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"number\": \"+4930123456\",\n \"country\": \"DE\",\n \"type\": \"local\",\n \"purchase_token\": \"eyJ2IjoxLCJvZmZlciI6IntcIn...\",\n \"assistant_id\": \"a1b2c3d4-0000-4000-8000-000000000001\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.famulor.io/api/v1/phone-numbers")
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 \"number\": \"+4930123456\",\n \"country\": \"DE\",\n \"type\": \"local\",\n \"purchase_token\": \"eyJ2IjoxLCJvZmZlciI6IntcIn...\",\n \"assistant_id\": \"a1b2c3d4-0000-4000-8000-000000000001\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "p1b2c3d4-0000-4000-8000-000000000020",
"number": "+4930123456",
"assistant_id": "a1b2c3d4-0000-4000-8000-000000000001",
"sip_trunk_id": null,
"direction_inbound": false,
"direction_outbound": false,
"source": "platform",
"country_iso": "DE",
"number_type": "local",
"monthly_price_cents": 500,
"status": "pending",
"purchased_by": "u1b2c3d4-0000-4000-8000-000000000003",
"released_at": null,
"created_at": "2026-06-15T12:00:00Z",
"updated_at": "2026-07-01T09:00:00Z",
"checkout_url": "https://checkout.stripe.com/c/pay/cs_live_example"
}
}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
The exact E.164 number returned by GET /phone-numbers/available.
ISO-2 country code, e.g. DE.
Number type of the offer. Pass the type returned with the number by GET /phone-numbers/available; defaults to local when omitted.
local, mobile, national The short-lived token returned with the exact number by GET /phone-numbers/available; pass it unchanged. Required for workspaces that buy numbers from a reseller. Otherwise optional, but when sent it must match the number, country and type.
Optionally assign an assistant that does not already have an inbound phone number. Pending number reservations also count. An existing assignment returns HTTP 409; omit this field or set it to null to assign an assistant later.
Response
A pending phone number and the checkout URL required to activate it.
Show child attributes
Show child attributes