curl --request POST \
--url https://app.famulor.io/api/v1/workspaces \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Acme Corp — EU"
}
'import requests
url = "https://app.famulor.io/api/v1/workspaces"
payload = { "name": "Acme Corp — EU" }
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({name: 'Acme Corp — EU'})
};
fetch('https://app.famulor.io/api/v1/workspaces', 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/workspaces",
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([
'name' => 'Acme Corp — EU'
]),
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/workspaces"
payload := strings.NewReader("{\n \"name\": \"Acme Corp — EU\"\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/workspaces")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Acme Corp — EU\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.famulor.io/api/v1/workspaces")
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 \"name\": \"Acme Corp — EU\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "t1b2c3d4-0000-4000-8000-000000000009",
"name": "Acme Corp — EU",
"role": "owner"
}
}{
"error": {
"code": "invalid_request",
"message": "name is required."
}
}{
"error": {
"code": "unauthorized",
"message": "Invalid API key."
}
}{
"error": {
"code": "forbidden",
"message": "Workspace limit reached. Upgrade your plan or contact support to create more workspaces."
},
"meta": {
"used": 3,
"allowed": 3
}
}{
"error": {
"code": "rate_limited",
"message": "Too many requests. Retry after the indicated delay."
}
}{
"error": {
"code": "internal_error",
"message": "Request protection is temporarily unavailable."
}
}Create a workspace
Create an additional workspace owned by the calling credential’s user. Requires a user-owned API key or OAuth token — a service-account key IS a single workspace and cannot own more (403). Limited by the plan’s workspace allowance (unlimited, or unavailable when the plan includes none) plus any Extra workspaces add-on, counted across every workspace this user already owns in this same brand. Required scope: settings:write. Eligible Partner and Whitelabel owners automatically receive Setup mode for newly self-created workspaces in the same brand. Setup uses the configured setup template’s features and limits (Agency by default), plus eligible Loop, AI Safety & Control, Revenue Autopilot and API Access add-ons. Whitelabel, free phone numbers, included minutes and credits, and template minute prices are excluded. An own active plan and paid add-ons take precedence; ordinary usage rates apply. Pending invitations keep setup. Setup ends when an invited member accepts and becomes active, an already active member is added, or ownership changes. That exit is permanent; the workspace then needs its own plan and add-ons. Usage, phone numbers and paid services are billed separately.
curl --request POST \
--url https://app.famulor.io/api/v1/workspaces \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Acme Corp — EU"
}
'import requests
url = "https://app.famulor.io/api/v1/workspaces"
payload = { "name": "Acme Corp — EU" }
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({name: 'Acme Corp — EU'})
};
fetch('https://app.famulor.io/api/v1/workspaces', 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/workspaces",
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([
'name' => 'Acme Corp — EU'
]),
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/workspaces"
payload := strings.NewReader("{\n \"name\": \"Acme Corp — EU\"\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/workspaces")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Acme Corp — EU\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.famulor.io/api/v1/workspaces")
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 \"name\": \"Acme Corp — EU\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "t1b2c3d4-0000-4000-8000-000000000009",
"name": "Acme Corp — EU",
"role": "owner"
}
}{
"error": {
"code": "invalid_request",
"message": "name is required."
}
}{
"error": {
"code": "unauthorized",
"message": "Invalid API key."
}
}{
"error": {
"code": "forbidden",
"message": "Workspace limit reached. Upgrade your plan or contact support to create more workspaces."
},
"meta": {
"used": 3,
"allowed": 3
}
}{
"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
Plain-text display name. Must not contain < > { } [ ] ` \ or line breaks; such names are rejected with 400.
1 - 80Response
The newly created workspace.
A newly created workspace. The creating user is always its owner.
Show child attributes
Show child attributes