curl --request PATCH \
--url https://api.notion.com/admin/v1/spaces/{space_id}/agents/{agent_id}/permissions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Notion-Version: <notion-version>' \
--data '
{
"remove": [
{
"group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "<string>"
}
],
"set": [
{
"principal": {
"group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "<string>"
}
}
]
}
'import requests
url = "https://api.notion.com/admin/v1/spaces/{space_id}/agents/{agent_id}/permissions"
payload = {
"remove": [
{
"group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "<string>"
}
],
"set": [{ "principal": {
"group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "<string>"
} }]
}
headers = {
"Notion-Version": "<notion-version>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {
'Notion-Version': '<notion-version>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
remove: [{group_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a', type: '<string>'}],
set: [
{
principal: {group_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a', type: '<string>'}
}
]
})
};
fetch('https://api.notion.com/admin/v1/spaces/{space_id}/agents/{agent_id}/permissions', 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.notion.com/admin/v1/spaces/{space_id}/agents/{agent_id}/permissions",
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([
'remove' => [
[
'group_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'type' => '<string>'
]
],
'set' => [
[
'principal' => [
'group_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'type' => '<string>'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Notion-Version: <notion-version>"
],
]);
$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.notion.com/admin/v1/spaces/{space_id}/agents/{agent_id}/permissions"
payload := strings.NewReader("{\n \"remove\": [\n {\n \"group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"type\": \"<string>\"\n }\n ],\n \"set\": [\n {\n \"principal\": {\n \"group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"type\": \"<string>\"\n }\n }\n ]\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Notion-Version", "<notion-version>")
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://api.notion.com/admin/v1/spaces/{space_id}/agents/{agent_id}/permissions")
.header("Notion-Version", "<notion-version>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"remove\": [\n {\n \"group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"type\": \"<string>\"\n }\n ],\n \"set\": [\n {\n \"principal\": {\n \"group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"type\": \"<string>\"\n }\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.notion.com/admin/v1/spaces/{space_id}/agents/{agent_id}/permissions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Notion-Version"] = '<notion-version>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"remove\": [\n {\n \"group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"type\": \"<string>\"\n }\n ],\n \"set\": [\n {\n \"principal\": {\n \"group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"type\": \"<string>\"\n }\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"permissions": [
{
"principal": {
"group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "<string>"
}
}
]
}{
"type": "error",
"code": "validation_error",
"status": 400,
"message": "The request body is invalid."
}{
"type": "error",
"code": "unauthorized",
"status": 401,
"message": "Unauthorized."
}{
"type": "error",
"code": "forbidden",
"status": 403,
"message": "Forbidden."
}{
"type": "error",
"code": "not_found",
"status": 404,
"message": "Not found."
}{
"type": "error",
"code": "rate_limited",
"status": 429,
"message": "Rate limited."
}{
"type": "error",
"code": "internal_server_error",
"status": 500,
"message": "An unexpected error occurred."
}Update a custom agent's sharing permissions
Update a custom agent’s sharing permissions.
curl --request PATCH \
--url https://api.notion.com/admin/v1/spaces/{space_id}/agents/{agent_id}/permissions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Notion-Version: <notion-version>' \
--data '
{
"remove": [
{
"group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "<string>"
}
],
"set": [
{
"principal": {
"group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "<string>"
}
}
]
}
'import requests
url = "https://api.notion.com/admin/v1/spaces/{space_id}/agents/{agent_id}/permissions"
payload = {
"remove": [
{
"group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "<string>"
}
],
"set": [{ "principal": {
"group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "<string>"
} }]
}
headers = {
"Notion-Version": "<notion-version>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {
'Notion-Version': '<notion-version>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
remove: [{group_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a', type: '<string>'}],
set: [
{
principal: {group_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a', type: '<string>'}
}
]
})
};
fetch('https://api.notion.com/admin/v1/spaces/{space_id}/agents/{agent_id}/permissions', 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.notion.com/admin/v1/spaces/{space_id}/agents/{agent_id}/permissions",
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([
'remove' => [
[
'group_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'type' => '<string>'
]
],
'set' => [
[
'principal' => [
'group_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'type' => '<string>'
]
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"Notion-Version: <notion-version>"
],
]);
$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.notion.com/admin/v1/spaces/{space_id}/agents/{agent_id}/permissions"
payload := strings.NewReader("{\n \"remove\": [\n {\n \"group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"type\": \"<string>\"\n }\n ],\n \"set\": [\n {\n \"principal\": {\n \"group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"type\": \"<string>\"\n }\n }\n ]\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Notion-Version", "<notion-version>")
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://api.notion.com/admin/v1/spaces/{space_id}/agents/{agent_id}/permissions")
.header("Notion-Version", "<notion-version>")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"remove\": [\n {\n \"group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"type\": \"<string>\"\n }\n ],\n \"set\": [\n {\n \"principal\": {\n \"group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"type\": \"<string>\"\n }\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.notion.com/admin/v1/spaces/{space_id}/agents/{agent_id}/permissions")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Notion-Version"] = '<notion-version>'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"remove\": [\n {\n \"group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"type\": \"<string>\"\n }\n ],\n \"set\": [\n {\n \"principal\": {\n \"group_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"type\": \"<string>\"\n }\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"permissions": [
{
"principal": {
"group_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"type": "<string>"
}
}
]
}{
"type": "error",
"code": "validation_error",
"status": 400,
"message": "The request body is invalid."
}{
"type": "error",
"code": "unauthorized",
"status": 401,
"message": "Unauthorized."
}{
"type": "error",
"code": "forbidden",
"status": 403,
"message": "Forbidden."
}{
"type": "error",
"code": "not_found",
"status": 404,
"message": "Not found."
}{
"type": "error",
"code": "rate_limited",
"status": 429,
"message": "Rate limited."
}{
"type": "error",
"code": "internal_server_error",
"status": 500,
"message": "An unexpected error occurred."
}workflows:write
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Headers
The Admin API version to use for this request.
2026-06-01 Body
'set' upserts (grants or updates the level for) each principal; 'remove' revokes access for each principal. A single request may do both, applied atomically — invalid batches write nothing. At most 100 combined 'set' + 'remove' entries per request, and a principal must not appear in both lists.
Principals to revoke permissions for.
A recipient of a permission grant. 'workspace' maps to a space-wide permission granting all workspace members the given role; guests are never covered by it.
- Option 1
- Option 2
- Option 3
Show child attributes
Show child attributes
Principals to grant permissions to, or update the level for.
Show child attributes
Show child attributes
Response
The updated permission list, in the same shape as the read endpoint. This is a pre-commit projection truncated at 250 entries with no cursor; treat the paginated read endpoint as the source of truth.
Show child attributes
Show child attributes