cURL
curl --request POST \
--url https://api.nekt.ai/api/v1/organization/object-permissions/ \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"assignments": [
{
"users": [],
"groups": [],
"secrets": [],
"live_connections": [],
"tools": [
"<string>"
]
}
],
"notify_members": false,
"message": "<string>"
}
'import requests
url = "https://api.nekt.ai/api/v1/organization/object-permissions/"
payload = {
"assignments": [
{
"users": [],
"groups": [],
"secrets": [],
"live_connections": [],
"tools": ["<string>"]
}
],
"notify_members": False,
"message": "<string>"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
assignments: [
{users: [], groups: [], secrets: [], live_connections: [], tools: ['<string>']}
],
notify_members: false,
message: '<string>'
})
};
fetch('https://api.nekt.ai/api/v1/organization/object-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.nekt.ai/api/v1/organization/object-permissions/",
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([
'assignments' => [
[
'users' => [
],
'groups' => [
],
'secrets' => [
],
'live_connections' => [
],
'tools' => [
'<string>'
]
]
],
'notify_members' => false,
'message' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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.nekt.ai/api/v1/organization/object-permissions/"
payload := strings.NewReader("{\n \"assignments\": [\n {\n \"users\": [],\n \"groups\": [],\n \"secrets\": [],\n \"live_connections\": [],\n \"tools\": [\n \"<string>\"\n ]\n }\n ],\n \"notify_members\": false,\n \"message\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
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://api.nekt.ai/api/v1/organization/object-permissions/")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"assignments\": [\n {\n \"users\": [],\n \"groups\": [],\n \"secrets\": [],\n \"live_connections\": [],\n \"tools\": [\n \"<string>\"\n ]\n }\n ],\n \"notify_members\": false,\n \"message\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.nekt.ai/api/v1/organization/object-permissions/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"assignments\": [\n {\n \"users\": [],\n \"groups\": [],\n \"secrets\": [],\n \"live_connections\": [],\n \"tools\": [\n \"<string>\"\n ]\n }\n ],\n \"notify_members\": false,\n \"message\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"created": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"permission_level": "manager",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"user": "<string>",
"group": "<string>",
"secret": "<string>",
"live_connection": "<string>",
"granted_by": "<string>",
"tool_scope": "<unknown>"
}
],
"updated": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"permission_level": "manager",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"user": "<string>",
"group": "<string>",
"secret": "<string>",
"live_connection": "<string>",
"granted_by": "<string>",
"tool_scope": "<unknown>"
}
],
"revoked": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"permission_level": "manager",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"user": "<string>",
"group": "<string>",
"secret": "<string>",
"live_connection": "<string>",
"granted_by": "<string>",
"tool_scope": "<unknown>"
}
]
}Secrets & live connections
Assign Object Permissions
Grant, change, and revoke access to secrets and live connections in a single call.
POST
/
api
/
v1
/
organization
/
object-permissions
/
cURL
curl --request POST \
--url https://api.nekt.ai/api/v1/organization/object-permissions/ \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"assignments": [
{
"users": [],
"groups": [],
"secrets": [],
"live_connections": [],
"tools": [
"<string>"
]
}
],
"notify_members": false,
"message": "<string>"
}
'import requests
url = "https://api.nekt.ai/api/v1/organization/object-permissions/"
payload = {
"assignments": [
{
"users": [],
"groups": [],
"secrets": [],
"live_connections": [],
"tools": ["<string>"]
}
],
"notify_members": False,
"message": "<string>"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
assignments: [
{users: [], groups: [], secrets: [], live_connections: [], tools: ['<string>']}
],
notify_members: false,
message: '<string>'
})
};
fetch('https://api.nekt.ai/api/v1/organization/object-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.nekt.ai/api/v1/organization/object-permissions/",
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([
'assignments' => [
[
'users' => [
],
'groups' => [
],
'secrets' => [
],
'live_connections' => [
],
'tools' => [
'<string>'
]
]
],
'notify_members' => false,
'message' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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.nekt.ai/api/v1/organization/object-permissions/"
payload := strings.NewReader("{\n \"assignments\": [\n {\n \"users\": [],\n \"groups\": [],\n \"secrets\": [],\n \"live_connections\": [],\n \"tools\": [\n \"<string>\"\n ]\n }\n ],\n \"notify_members\": false,\n \"message\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
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://api.nekt.ai/api/v1/organization/object-permissions/")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"assignments\": [\n {\n \"users\": [],\n \"groups\": [],\n \"secrets\": [],\n \"live_connections\": [],\n \"tools\": [\n \"<string>\"\n ]\n }\n ],\n \"notify_members\": false,\n \"message\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.nekt.ai/api/v1/organization/object-permissions/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"assignments\": [\n {\n \"users\": [],\n \"groups\": [],\n \"secrets\": [],\n \"live_connections\": [],\n \"tools\": [\n \"<string>\"\n ]\n }\n ],\n \"notify_members\": false,\n \"message\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"created": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"permission_level": "manager",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"user": "<string>",
"group": "<string>",
"secret": "<string>",
"live_connection": "<string>",
"granted_by": "<string>",
"tool_scope": "<unknown>"
}
],
"updated": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"permission_level": "manager",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"user": "<string>",
"group": "<string>",
"secret": "<string>",
"live_connection": "<string>",
"granted_by": "<string>",
"tool_scope": "<unknown>"
}
],
"revoked": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"permission_level": "manager",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"user": "<string>",
"group": "<string>",
"secret": "<string>",
"live_connection": "<string>",
"granted_by": "<string>",
"tool_scope": "<unknown>"
}
]
}The same declarative bulk upsert as Assign Permissions, applied to the resources that live outside the Catalog: secrets and live connections. Each assignment is a cross product of recipients and resources, and
Each object in
Three rules govern
permission_level: null revokes.
Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
assignments | array of objects | Yes | One or more assignment blocks. Must not be empty. |
assignments:
| Parameter | Type | Required | Description |
|---|---|---|---|
permission_level | viewer, editor, manager, or null | Yes | The level to apply. null revokes. |
users | array of UUIDs | No | Recipient users. |
groups | array of UUIDs | No | Recipient permission groups. |
secrets | array of UUIDs | No | Target secrets. |
live_connections | array of UUIDs | No | Target live connections. |
tools | array of strings | No | Live connections only. Restrict the grant to a subset of the connection’s available tools. Omit for the full set. |
What the levels mean here
Secrets and live connections do not use the Catalog meaning of the levels.| Level | Secret | Live connection |
|---|---|---|
viewer | See the metadata and reference the secret in Queries and Notebooks. | Use the connection’s tools. |
editor | Also edit the description and rotate the value. | Also edit the description and tags. Nothing else. |
manager | Also manage access and delete the secret. | Also change config, status, slug, tools, and setup links, and delete. |
The value of a secret is never readable through the API at any level, including
manager. Only pipeline runtimes resolve it.Share a secret with a group
curl --request POST \
--url https://api.nekt.ai/api/v1/organization/object-permissions/ \
--header "x-api-key: YOUR_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"assignments": [
{
"permission_level": "viewer",
"groups": ["b8c5e1e3-6d02-4f45-ad20-8f4b6e2d0e13"],
"secrets": ["c9d0e1f2-a3b4-45c6-87d8-e9f0a1b2c3d4"]
}
]
}'
Scope a live connection to specific tools
tools narrows what the recipient may call. It is validated against each connection’s current available set — a name the connection does not expose is rejected with Connection '<slug>' has no available tools named: ….
curl --request POST \
--url https://api.nekt.ai/api/v1/organization/object-permissions/ \
--header "x-api-key: YOUR_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"assignments": [
{
"permission_level": "viewer",
"users": ["3f7c1e88-9a41-4b2d-8e5f-6c0a2d4b9e11"],
"live_connections": ["d1e2f3a4-b5c6-47d8-99e0-f1a2b3c4d5e6"],
"tools": ["search_contacts", "get_contact"]
}
]
}'
tools, and all three return 400 when broken:
- It applies to live connections only. Sending it alongside
secretsis an error. - It cannot be combined with
manager— a manager always holds the full set. - Every name must be currently available on every connection in the same assignment.
Omitting
tools is not the same as listing every tool. Omitted means “whatever is available”, and it keeps tracking the connection as tools are added or removed. An explicit list is a fixed subset.Removing a tool from a live connection’s available set strips it from every grant that named it. Adding the tool back later does not restore those grants — you have to reassign them.
Errors
| Status | When |
|---|---|
400 | A tools rule was broken, a recipient’s membership is deactivated, or a referenced id is not visible to your API key. |
403 | The key’s ceiling does not allow the grant. See Permissions flow. |
Related
- Permissions flow — the end-to-end walkthrough and the ceiling rules.
- List Object Permission Recipients — where recipient ids come from.
- Secrets — what a secret is and how levels behave in the app.
Authorizations
API Key authentication. Format: 'x-api-key: api_key'
Body
application/jsonapplication/x-www-form-urlencodedmultipart/form-data
Was this page helpful?