curl --request PUT \
--url https://api.atako.ai/organization/agents/{id}/manager \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"manager": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
}
'import requests
url = "https://api.atako.ai/organization/agents/{id}/manager"
payload = { "manager": { "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a" } }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({manager: {id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'}})
};
fetch('https://api.atako.ai/organization/agents/{id}/manager', 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.atako.ai/organization/agents/{id}/manager",
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([
'manager' => [
'id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a'
]
]),
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://api.atako.ai/organization/agents/{id}/manager"
payload := strings.NewReader("{\n \"manager\": {\n \"id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n}")
req, _ := http.NewRequest("PUT", 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.put("https://api.atako.ai/organization/agents/{id}/manager")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"manager\": {\n \"id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.atako.ai/organization/agents/{id}/manager")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"manager\": {\n \"id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n}"
response = http.request(request)
puts response.read_body{
"rootHumanId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"tree": {
"roots": [
{
"key": "<string>",
"kind": "human",
"id": "<string>",
"name": "<string>",
"role": "<string>",
"children": "<array>",
"teamId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"memberCount": 123
}
],
"loose": [
{
"key": "<string>",
"kind": "human",
"id": "<string>",
"name": "<string>",
"role": "<string>",
"children": "<array>",
"teamId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"memberCount": 123
}
]
},
"issues": [
{
"kind": "team-lead",
"id": "<string>"
}
],
"teams": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"parentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"lead": {
"kind": "human",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
}
],
"agents": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"role": "<string>",
"teamId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"manager": {
"kind": "human",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
}
],
"humans": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"title": "<string>",
"teamId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"managerUserId": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
],
"canEdit": true
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}Give an agent its own manager
The exception, not the ordinary case: it pulls the agent out of its team’s line. manager: null puts it back into that line (inheritance). Refused when it would close a loop (ORG_CYCLE) or when nobody human would end up above the agent (ORG_NO_HUMAN_MANAGER) — an agent under an agent is allowed; an agent under an agent under nobody is what the rule forbids.
curl --request PUT \
--url https://api.atako.ai/organization/agents/{id}/manager \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"manager": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
}
'import requests
url = "https://api.atako.ai/organization/agents/{id}/manager"
payload = { "manager": { "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a" } }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({manager: {id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'}})
};
fetch('https://api.atako.ai/organization/agents/{id}/manager', 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.atako.ai/organization/agents/{id}/manager",
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([
'manager' => [
'id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a'
]
]),
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://api.atako.ai/organization/agents/{id}/manager"
payload := strings.NewReader("{\n \"manager\": {\n \"id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n}")
req, _ := http.NewRequest("PUT", 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.put("https://api.atako.ai/organization/agents/{id}/manager")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"manager\": {\n \"id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.atako.ai/organization/agents/{id}/manager")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"manager\": {\n \"id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n }\n}"
response = http.request(request)
puts response.read_body{
"rootHumanId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"tree": {
"roots": [
{
"key": "<string>",
"kind": "human",
"id": "<string>",
"name": "<string>",
"role": "<string>",
"children": "<array>",
"teamId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"memberCount": 123
}
],
"loose": [
{
"key": "<string>",
"kind": "human",
"id": "<string>",
"name": "<string>",
"role": "<string>",
"children": "<array>",
"teamId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"memberCount": 123
}
]
},
"issues": [
{
"kind": "team-lead",
"id": "<string>"
}
],
"teams": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"parentId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"lead": {
"kind": "human",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
}
],
"agents": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"role": "<string>",
"teamId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"manager": {
"kind": "human",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
}
],
"humans": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"title": "<string>",
"teamId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"managerUserId": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
],
"canEdit": true
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}{
"error": "<string>",
"code": "<string>"
}Authorizations
An aik_… programmatic API key (app.atako.ai → Settings → API keys) or a Supabase session JWT.
Path Parameters
Agent id
Body
A reference to a member of the organisation, whatever its nature. Humans and agents are the same kind of node in this chart.
Show child attributes
Show child attributes
Response
The recomputed chart — identical shape to GET /organization/chart.
The whole chart, and the single payload of every /organization operation — reads AND writes. A hierarchy change moves people who were not named in the request, so a write answers with the recomputed chart rather than an acknowledgement: the client never has to make a second call, nor guess. It carries both the derived SHAPE (tree) and the raw CHOICES (teams/agents/humans, with their explicit lead/manager), which is what an editor needs to show what was decided instead of what was inferred from it.
DERIVED, never stored: the oldest admin member. Null when the company has no admin at all — the only case where the chart has nothing to hang on.
The chart as a forest. roots are the people nobody stands above (normally one). loose collects what the structure left dangling — a team whose lead is gone stays on the chart, to be repaired rather than to vanish quietly.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
True when the caller is a company admin, i.e. when the write operations below are open to them. Told here so the client never has to deduce a permission from a 403 it provoked.