Update user settings
curl --request PATCH \
--url https://app.autocalls.ai/api/white-label/users/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"email": "<string>",
"permissions": {
"platform_admin": true,
"settings_access": true,
"billing_access": true,
"revenue_reports_access": true,
"impersonate_owner": true
},
"custom_minute_rate": 123,
"limits": {},
"appearance": {
"hide_pages": [
"<string>"
],
"hide_features": [
"<string>"
],
"visible_plans": [
123
]
}
}
'import requests
url = "https://app.autocalls.ai/api/white-label/users/{id}"
payload = {
"name": "<string>",
"email": "<string>",
"permissions": {
"platform_admin": True,
"settings_access": True,
"billing_access": True,
"revenue_reports_access": True,
"impersonate_owner": True
},
"custom_minute_rate": 123,
"limits": {},
"appearance": {
"hide_pages": ["<string>"],
"hide_features": ["<string>"],
"visible_plans": [123]
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
email: '<string>',
permissions: {
platform_admin: true,
settings_access: true,
billing_access: true,
revenue_reports_access: true,
impersonate_owner: true
},
custom_minute_rate: 123,
limits: {},
appearance: {hide_pages: ['<string>'], hide_features: ['<string>'], visible_plans: [123]}
})
};
fetch('https://app.autocalls.ai/api/white-label/users/{id}', 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.autocalls.ai/api/white-label/users/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'email' => '<string>',
'permissions' => [
'platform_admin' => true,
'settings_access' => true,
'billing_access' => true,
'revenue_reports_access' => true,
'impersonate_owner' => true
],
'custom_minute_rate' => 123,
'limits' => [
],
'appearance' => [
'hide_pages' => [
'<string>'
],
'hide_features' => [
'<string>'
],
'visible_plans' => [
123
]
]
]),
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.autocalls.ai/api/white-label/users/{id}"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"email\": \"<string>\",\n \"permissions\": {\n \"platform_admin\": true,\n \"settings_access\": true,\n \"billing_access\": true,\n \"revenue_reports_access\": true,\n \"impersonate_owner\": true\n },\n \"custom_minute_rate\": 123,\n \"limits\": {},\n \"appearance\": {\n \"hide_pages\": [\n \"<string>\"\n ],\n \"hide_features\": [\n \"<string>\"\n ],\n \"visible_plans\": [\n 123\n ]\n }\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://app.autocalls.ai/api/white-label/users/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"email\": \"<string>\",\n \"permissions\": {\n \"platform_admin\": true,\n \"settings_access\": true,\n \"billing_access\": true,\n \"revenue_reports_access\": true,\n \"impersonate_owner\": true\n },\n \"custom_minute_rate\": 123,\n \"limits\": {},\n \"appearance\": {\n \"hide_pages\": [\n \"<string>\"\n ],\n \"hide_features\": [\n \"<string>\"\n ],\n \"visible_plans\": [\n 123\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.autocalls.ai/api/white-label/users/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"email\": \"<string>\",\n \"permissions\": {\n \"platform_admin\": true,\n \"settings_access\": true,\n \"billing_access\": true,\n \"revenue_reports_access\": true,\n \"impersonate_owner\": true\n },\n \"custom_minute_rate\": 123,\n \"limits\": {},\n \"appearance\": {\n \"hide_pages\": [\n \"<string>\"\n ],\n \"hide_features\": [\n \"<string>\"\n ],\n \"visible_plans\": [\n 123\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"message": "User updated.",
"data": {
"id": 123,
"name": "Jane Doe",
"email": "[email protected]",
"permissions": {
"platform_admin": false,
"settings_access": false,
"billing_access": false,
"revenue_reports_access": false,
"impersonate_owner": false
},
"custom_minute_rate": 0.12,
"effective_minute_rate": 0.12,
"limits": {
"assistants": { "custom": 3, "effective": 3 },
"campaigns": { "custom": null, "effective": 1 },
"cloned_voices": { "custom": null, "effective": 0 },
"knowledgebases": { "custom": null, "effective": 1 },
"mid_call_tools": { "custom": null, "effective": 1 },
"parallel_calls": { "custom": null, "effective": 3 },
"automation_runs": { "custom": null, "effective": 500 },
"own_numbers": { "custom": null, "effective": 1 },
"web_widget": { "custom": false, "effective": false },
"secondary_languages": { "custom": null, "effective": true },
"automation_platform": { "custom": null, "effective": true },
"custom_dashboards": { "custom": null, "effective": false },
"ai_prompt_editor": { "custom": null, "effective": true },
"flow_builder": { "custom": null, "effective": true },
"ai_connector": { "custom": null, "effective": true }
},
"appearance": {
"custom": true,
"hide_pages": ["hide_blacklist_page"],
"hide_features": ["hide_carrier_costs"],
"visible_plans": [12]
}
}
}
{
"message": "Unauthenticated."
}
{
"message": "You are not an administrator."
}
{
"message": "Only the account owner can change permissions."
}
{
"message": "User not found."
}
{
"message": "The custom minute rate field must be at least 0.09.",
"errors": {
"custom_minute_rate": ["The custom minute rate field must be at least 0.09."]
}
}
{
"message": "The appearance.visible_plans field contains a plan that does not exist.",
"errors": {
"appearance.visible_plans": ["The appearance.visible_plans field contains a plan that does not exist."]
}
}
{
"message": "The email has already been taken.",
"errors": {
"email": ["The email has already been taken."]
}
}
{
"message": "The balance field is not supported.",
"errors": {
"balance": ["The balance field is not supported."]
}
}
{
"message": "Too Many Attempts."
}
White Label
Update user settings
Update the permissions, minute rate, limits and appearance of one of your users
PATCH
/
white-label
/
users
/
{id}
Update user settings
curl --request PATCH \
--url https://app.autocalls.ai/api/white-label/users/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "<string>",
"email": "<string>",
"permissions": {
"platform_admin": true,
"settings_access": true,
"billing_access": true,
"revenue_reports_access": true,
"impersonate_owner": true
},
"custom_minute_rate": 123,
"limits": {},
"appearance": {
"hide_pages": [
"<string>"
],
"hide_features": [
"<string>"
],
"visible_plans": [
123
]
}
}
'import requests
url = "https://app.autocalls.ai/api/white-label/users/{id}"
payload = {
"name": "<string>",
"email": "<string>",
"permissions": {
"platform_admin": True,
"settings_access": True,
"billing_access": True,
"revenue_reports_access": True,
"impersonate_owner": True
},
"custom_minute_rate": 123,
"limits": {},
"appearance": {
"hide_pages": ["<string>"],
"hide_features": ["<string>"],
"visible_plans": [123]
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
email: '<string>',
permissions: {
platform_admin: true,
settings_access: true,
billing_access: true,
revenue_reports_access: true,
impersonate_owner: true
},
custom_minute_rate: 123,
limits: {},
appearance: {hide_pages: ['<string>'], hide_features: ['<string>'], visible_plans: [123]}
})
};
fetch('https://app.autocalls.ai/api/white-label/users/{id}', 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.autocalls.ai/api/white-label/users/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'email' => '<string>',
'permissions' => [
'platform_admin' => true,
'settings_access' => true,
'billing_access' => true,
'revenue_reports_access' => true,
'impersonate_owner' => true
],
'custom_minute_rate' => 123,
'limits' => [
],
'appearance' => [
'hide_pages' => [
'<string>'
],
'hide_features' => [
'<string>'
],
'visible_plans' => [
123
]
]
]),
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.autocalls.ai/api/white-label/users/{id}"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"email\": \"<string>\",\n \"permissions\": {\n \"platform_admin\": true,\n \"settings_access\": true,\n \"billing_access\": true,\n \"revenue_reports_access\": true,\n \"impersonate_owner\": true\n },\n \"custom_minute_rate\": 123,\n \"limits\": {},\n \"appearance\": {\n \"hide_pages\": [\n \"<string>\"\n ],\n \"hide_features\": [\n \"<string>\"\n ],\n \"visible_plans\": [\n 123\n ]\n }\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://app.autocalls.ai/api/white-label/users/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"email\": \"<string>\",\n \"permissions\": {\n \"platform_admin\": true,\n \"settings_access\": true,\n \"billing_access\": true,\n \"revenue_reports_access\": true,\n \"impersonate_owner\": true\n },\n \"custom_minute_rate\": 123,\n \"limits\": {},\n \"appearance\": {\n \"hide_pages\": [\n \"<string>\"\n ],\n \"hide_features\": [\n \"<string>\"\n ],\n \"visible_plans\": [\n 123\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.autocalls.ai/api/white-label/users/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"email\": \"<string>\",\n \"permissions\": {\n \"platform_admin\": true,\n \"settings_access\": true,\n \"billing_access\": true,\n \"revenue_reports_access\": true,\n \"impersonate_owner\": true\n },\n \"custom_minute_rate\": 123,\n \"limits\": {},\n \"appearance\": {\n \"hide_pages\": [\n \"<string>\"\n ],\n \"hide_features\": [\n \"<string>\"\n ],\n \"visible_plans\": [\n 123\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"message": "User updated.",
"data": {
"id": 123,
"name": "Jane Doe",
"email": "[email protected]",
"permissions": {
"platform_admin": false,
"settings_access": false,
"billing_access": false,
"revenue_reports_access": false,
"impersonate_owner": false
},
"custom_minute_rate": 0.12,
"effective_minute_rate": 0.12,
"limits": {
"assistants": { "custom": 3, "effective": 3 },
"campaigns": { "custom": null, "effective": 1 },
"cloned_voices": { "custom": null, "effective": 0 },
"knowledgebases": { "custom": null, "effective": 1 },
"mid_call_tools": { "custom": null, "effective": 1 },
"parallel_calls": { "custom": null, "effective": 3 },
"automation_runs": { "custom": null, "effective": 500 },
"own_numbers": { "custom": null, "effective": 1 },
"web_widget": { "custom": false, "effective": false },
"secondary_languages": { "custom": null, "effective": true },
"automation_platform": { "custom": null, "effective": true },
"custom_dashboards": { "custom": null, "effective": false },
"ai_prompt_editor": { "custom": null, "effective": true },
"flow_builder": { "custom": null, "effective": true },
"ai_connector": { "custom": null, "effective": true }
},
"appearance": {
"custom": true,
"hide_pages": ["hide_blacklist_page"],
"hide_features": ["hide_carrier_costs"],
"visible_plans": [12]
}
}
}
{
"message": "Unauthenticated."
}
{
"message": "You are not an administrator."
}
{
"message": "Only the account owner can change permissions."
}
{
"message": "User not found."
}
{
"message": "The custom minute rate field must be at least 0.09.",
"errors": {
"custom_minute_rate": ["The custom minute rate field must be at least 0.09."]
}
}
{
"message": "The appearance.visible_plans field contains a plan that does not exist.",
"errors": {
"appearance.visible_plans": ["The appearance.visible_plans field contains a plan that does not exist."]
}
}
{
"message": "The email has already been taken.",
"errors": {
"email": ["The email has already been taken."]
}
}
{
"message": "The balance field is not supported.",
"errors": {
"balance": ["The balance field is not supported."]
}
}
{
"message": "Too Many Attempts."
}
This endpoint changes the settings of one of your platform users: their name and email, their permissions, their minute rate, their limits and what they see on your platform. Send only the keys you want to change: everything you leave out stays as it is. The response returns all the user’s settings after the change, in the same format as Get user settings.
This endpoint is available to the account owner (with an active plan) and to team members who can open the administration panel, meaning they have Platform Admin, Settings Access or Billing Access. Only the owner can change
permissions. Team members can change everything else, on their own account too, as in the administration panel. Only users of your platform can be changed: any other ID, including the owner account, returns 404.Path Parameters
integer
required
The ID of the user. Administrators can list user IDs with Get platform users.
Request Body
string
The user’s name, up to 255 characters. It cannot contain
<, >, links or domain names.string
The user’s email address. It must be a valid email address that is not already used by another user of your platform or by the owner account.
object
The user’s permissions in your administration panel. Only the account owner can send this key; for anyone else the request returns 403 and nothing is saved. Permissions you leave out stay unchanged. See Permissions for what each one allows.
number
The rate per minute this user is charged, in your currency, instead of the rate of their plan or your default rate. Up to 4 decimals, and at least your own cost per minute.
minimum_minute_cost in Get default limits is that cost rounded up to the cent, so it is always accepted. null removes the custom rate, and the user goes back to the rate of their plan or your default rate.object
The user’s own limits, which take priority over their plan and your default limits. The keys are those of default limits except
calendar_integrations: assistants, campaigns, cloned_voices, knowledgebases, mid_call_tools, parallel_calls, automation_runs and own_numbers are count limits, and web_widget, secondary_languages, automation_platform, custom_dashboards, ai_prompt_editor, flow_builder and ai_connector are boolean limits.Count limits take an integer from -1 to 100000 (-1 means unlimited, 0 means none). Boolean limits take true or false. null on a key removes that limit from the user, who then gets the limit of their plan or your default limit again. Limits you leave out stay unchanged. limits: null removes all of the user’s own limits.object
What the user sees on your platform. For each page and feature, the user sees your platform-wide setting unless you give them a different one, and the pages and features you leave matching your platform-wide appearance keep following it when you change it later. A list you send replaces the current list for this user, and a value sent twice is saved once.
appearance: null returns the user to your platform-wide appearance and clears visible_plans.Show appearance properties
Show appearance properties
string[]
Every page to hide for this user. Values from Pages you can hide
string[]
Every feature to hide for this user. Values from Features you can hide, except
hide_auto_generated_plan_features and hide_platform_tour, which only exist platform-wideinteger[]
IDs of the plans this user sees on the plans page, from List plans. They must be your own plans, and inactive plans are allowed, so you can offer a plan to this user only. Up to 100 IDs. Send
[] to show all your active plansResponse
string
Success message
object
All the user’s settings after the change, in the same format as Get user settings.
permissions is returned only to the account owner{
"message": "User updated.",
"data": {
"id": 123,
"name": "Jane Doe",
"email": "[email protected]",
"permissions": {
"platform_admin": false,
"settings_access": false,
"billing_access": false,
"revenue_reports_access": false,
"impersonate_owner": false
},
"custom_minute_rate": 0.12,
"effective_minute_rate": 0.12,
"limits": {
"assistants": { "custom": 3, "effective": 3 },
"campaigns": { "custom": null, "effective": 1 },
"cloned_voices": { "custom": null, "effective": 0 },
"knowledgebases": { "custom": null, "effective": 1 },
"mid_call_tools": { "custom": null, "effective": 1 },
"parallel_calls": { "custom": null, "effective": 3 },
"automation_runs": { "custom": null, "effective": 500 },
"own_numbers": { "custom": null, "effective": 1 },
"web_widget": { "custom": false, "effective": false },
"secondary_languages": { "custom": null, "effective": true },
"automation_platform": { "custom": null, "effective": true },
"custom_dashboards": { "custom": null, "effective": false },
"ai_prompt_editor": { "custom": null, "effective": true },
"flow_builder": { "custom": null, "effective": true },
"ai_connector": { "custom": null, "effective": true }
},
"appearance": {
"custom": true,
"hide_pages": ["hide_blacklist_page"],
"hide_features": ["hide_carrier_costs"],
"visible_plans": [12]
}
}
}
{
"message": "Unauthenticated."
}
{
"message": "You are not an administrator."
}
{
"message": "Only the account owner can change permissions."
}
{
"message": "User not found."
}
{
"message": "The custom minute rate field must be at least 0.09.",
"errors": {
"custom_minute_rate": ["The custom minute rate field must be at least 0.09."]
}
}
{
"message": "The appearance.visible_plans field contains a plan that does not exist.",
"errors": {
"appearance.visible_plans": ["The appearance.visible_plans field contains a plan that does not exist."]
}
}
{
"message": "The email has already been taken.",
"errors": {
"email": ["The email has already been taken."]
}
}
{
"message": "The balance field is not supported.",
"errors": {
"balance": ["The balance field is not supported."]
}
}
{
"message": "Too Many Attempts."
}
Permissions
The first three permissions let a team member open your administration panel, where every administrator can manage your users. They can then use these user settings endpoints, and the other endpoints their permissions allow.| Key | Permission | What it allows |
|---|---|---|
platform_admin | Platform Admin | Opens the administration panel, including Data Migration. Pages and features hidden by appearance settings stay visible to this user |
settings_access | Settings Access | Opens the administration panel and allows changing your platform settings, including through Update platform settings. The checkout settings also need Billing Access |
billing_access | Billing Access | Opens the administration panel and allows managing billing: plans, pricing, trials, default limits and checkout settings |
revenue_reports_access | Revenue Reports Access | Shows revenue figures (MRR, ARPU, plan prices) on the administration dashboard and user pages. Does not open the panel on its own |
impersonate_owner | Allow impersonate owner | Allows opening the owner account (User view and Admin view) from the users list. Does not open the panel on its own |
Partial updates
- Keys you leave out stay unchanged. Inside
permissionsandlimits, only the keys you send change. - A list you send (
hide_pages,hide_featuresorvisible_plans) replaces that list for the user. Anappearanceobject without one of these lists keeps the user’s current value for it. - An unknown top-level field returns 422 with “The X field is not supported.”, and an unknown key inside
permissions,limitsorappearancereturns 422 with “The X field must be an object with only the supported keys.”. In both cases nothing is saved, not even the valid parts of the request. - Leading and trailing spaces are removed from text values.
- Send only the keys you want to change.
Rate limit
The platform settings, default limits, user settings and plan endpoints share a limit of 60 requests per minute for each account. Above it they return429, and the Retry-After response header tells you how many seconds to wait.
Example: Change a user’s rate, limits and appearance
curl -X PATCH https://app.autocalls.ai/api/white-label/users/123 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"custom_minute_rate": 0.12,
"limits": {
"assistants": 3,
"web_widget": false,
"parallel_calls": null
},
"appearance": {
"hide_pages": ["hide_blacklist_page"],
"visible_plans": [12]
}
}'
Example: Give a team member Settings Access (owner only)
curl -X PATCH https://app.autocalls.ai/api/white-label/users/124 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"permissions": {
"settings_access": true
}
}'
Example: Return a user to your defaults
curl -X PATCH https://app.autocalls.ai/api/white-label/users/123 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"custom_minute_rate": null,
"limits": null,
"appearance": null
}'

