curl --request PUT \
--url https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/agents/{agentId}/access \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'cloudchat-instance: <cloudchat-instance>' \
--data '
{
"access": {
"claudia_projects": [
"acme_support"
],
"eddie_workspaces": [
"ws_42"
]
}
}
'import requests
url = "https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/agents/{agentId}/access"
payload = { "access": {
"claudia_projects": ["acme_support"],
"eddie_workspaces": ["ws_42"]
} }
headers = {
"cloudchat-instance": "<cloudchat-instance>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {
'cloudchat-instance': '<cloudchat-instance>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({access: {claudia_projects: ['acme_support'], eddie_workspaces: ['ws_42']}})
};
fetch('https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/agents/{agentId}/access', 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://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/agents/{agentId}/access",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'access' => [
'claudia_projects' => [
'acme_support'
],
'eddie_workspaces' => [
'ws_42'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"cloudchat-instance: <cloudchat-instance>"
],
]);
$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://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/agents/{agentId}/access"
payload := strings.NewReader("{\n \"access\": {\n \"claudia_projects\": [\n \"acme_support\"\n ],\n \"eddie_workspaces\": [\n \"ws_42\"\n ]\n }\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("cloudchat-instance", "<cloudchat-instance>")
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.put("https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/agents/{agentId}/access")
.header("cloudchat-instance", "<cloudchat-instance>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"access\": {\n \"claudia_projects\": [\n \"acme_support\"\n ],\n \"eddie_workspaces\": [\n \"ws_42\"\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/agents/{agentId}/access")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["cloudchat-instance"] = '<cloudchat-instance>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"access\": {\n \"claudia_projects\": [\n \"acme_support\"\n ],\n \"eddie_workspaces\": [\n \"ws_42\"\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"agent_access": {
"claudia_projects": [
"acme_support"
],
"eddie_workspaces": [
"ws_42"
]
},
"manageable": {
"claudia_projects": [
"acme_support"
],
"eddie_workspaces": [
"ws_42"
]
}
}{
"error": {
"code": "bad_request",
"message": "Provide `access` with at least one of: claudia_projects, eddie_workspaces."
}
}{
"error": {
"code": "unauthorized",
"message": "Authentication is required. Send a valid Bearer token in the Authorization header."
}
}{
"error": {
"code": "forbidden",
"message": "You are not allowed to perform this action."
}
}{
"error": {
"code": "not_found",
"message": "Resource could not be found."
}
}{
"error": {
"code": "validation_failed",
"message": "The request payload is invalid.",
"details": [
{
"field": "claudia_projects",
"code": "outside_ceiling",
"message": "acme_internal is outside your manageable Claudia projects."
}
]
}
}{
"message": "API rate limit exceeded"
}{
"error": {
"code": "internal_error",
"message": "An unexpected error occurred. Please try again later."
}
}Set agent access
Grant or revoke this agent’s access to Claudia projects and Eddie workspaces. Administrator only. Each dimension — claudia_projects and eddie_workspaces — is optional and independently declarative: send it as the full set you want that dimension to hold, drawn from your own manageable ceiling (see getAgentAccess) — items you leave out of a dimension you send are revoked, items you add are granted; a dimension you omit from the request entirely is left untouched. You can only grant or revoke within your own ceiling: items the target already holds outside it are preserved, never touched by your request. Naming an item outside your ceiling is refused with 422 (outside_ceiling, field names the offending dimension). The target’s CloudChat role must be administrator or cx_engineer, or the whole request is refused with 422 (ineligible_role, field agent). An all-empty request (revoking everything) is accepted regardless of the target’s role — it is the cleanup path for an agent demoted after receiving access. A target that has no hub user yet is provisioned automatically by this operation when the grant is non-empty. A grant only takes effect at the target agent’s next login — that is when the new claims are provisioned — so an agent already signed in keeps its old access until it logs in again. This operation never removes the agent from the CloudChat account itself.
curl --request PUT \
--url https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/agents/{agentId}/access \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'cloudchat-instance: <cloudchat-instance>' \
--data '
{
"access": {
"claudia_projects": [
"acme_support"
],
"eddie_workspaces": [
"ws_42"
]
}
}
'import requests
url = "https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/agents/{agentId}/access"
payload = { "access": {
"claudia_projects": ["acme_support"],
"eddie_workspaces": ["ws_42"]
} }
headers = {
"cloudchat-instance": "<cloudchat-instance>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {
'cloudchat-instance': '<cloudchat-instance>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({access: {claudia_projects: ['acme_support'], eddie_workspaces: ['ws_42']}})
};
fetch('https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/agents/{agentId}/access', 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://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/agents/{agentId}/access",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'access' => [
'claudia_projects' => [
'acme_support'
],
'eddie_workspaces' => [
'ws_42'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"cloudchat-instance: <cloudchat-instance>"
],
]);
$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://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/agents/{agentId}/access"
payload := strings.NewReader("{\n \"access\": {\n \"claudia_projects\": [\n \"acme_support\"\n ],\n \"eddie_workspaces\": [\n \"ws_42\"\n ]\n }\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("cloudchat-instance", "<cloudchat-instance>")
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.put("https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/agents/{agentId}/access")
.header("cloudchat-instance", "<cloudchat-instance>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"access\": {\n \"claudia_projects\": [\n \"acme_support\"\n ],\n \"eddie_workspaces\": [\n \"ws_42\"\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloudhumans.com/cloudchat/v1/accounts/{accountId}/agents/{agentId}/access")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["cloudchat-instance"] = '<cloudchat-instance>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"access\": {\n \"claudia_projects\": [\n \"acme_support\"\n ],\n \"eddie_workspaces\": [\n \"ws_42\"\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"agent_access": {
"claudia_projects": [
"acme_support"
],
"eddie_workspaces": [
"ws_42"
]
},
"manageable": {
"claudia_projects": [
"acme_support"
],
"eddie_workspaces": [
"ws_42"
]
}
}{
"error": {
"code": "bad_request",
"message": "Provide `access` with at least one of: claudia_projects, eddie_workspaces."
}
}{
"error": {
"code": "unauthorized",
"message": "Authentication is required. Send a valid Bearer token in the Authorization header."
}
}{
"error": {
"code": "forbidden",
"message": "You are not allowed to perform this action."
}
}{
"error": {
"code": "not_found",
"message": "Resource could not be found."
}
}{
"error": {
"code": "validation_failed",
"message": "The request payload is invalid.",
"details": [
{
"field": "claudia_projects",
"code": "outside_ceiling",
"message": "acme_internal is outside your manageable Claudia projects."
}
]
}
}{
"message": "API rate limit exceeded"
}{
"error": {
"code": "internal_error",
"message": "An unexpected error occurred. Please try again later."
}
}Authorizations
The id_token from POST /auth/v1/signin, sent as Authorization: Bearer <id_token>. Not the access_token — that one does not carry the identity Cloud Chat authorizes on.
Headers
Your Cloud Chat instance ID — an integer, fixed for your company, told at onboarding. The API overview explains how instances work, how to find yours, and the errors a wrong or missing value produces.
1
Path Parameters
Your Cloud Chat account. It has to be an account your token grants membership on, and it has to live on the instance in the cloudchat-instance header — the two travel together. Account numbers are only unique within an instance, so the same number is a different company on another instance. Usually a mismatched pair fails closed with a 401, because your user does not exist on the other instance — but if your identity happens to exist on both, the call succeeds against the other company's data, silently. Read it and you are looking at the wrong help center; write it and you have stored into the wrong account. Send the two values that were given to you together, and never try a number to see what answers.
1
The agent's user id, as returned when the agent was listed. A hidden admin's id answers 404 here, the same as an id that does not exist.
7
Body
Wrapper the endpoint expects — the dimensions to change go under access.
The two dimensions of hub access to change. Each is optional and independent — present it to declare that dimension's full desired state (grants and revokes, within your own ceiling), or leave it out to leave that dimension untouched. At least one of the two must be present.
Show child attributes
Show child attributes
Response
The agent's hub access as stored — agent_access reflects every dimension you sent, unchanged for any dimension you omitted; manageable is unchanged, it is your own ceiling and this operation never alters it.
An agent's hub access, alongside the caller's own ceiling for granting or revoking it.