mirror of
https://github.com/netbirdio/docs.git
synced 2026-10-09 15:19:04 +02:00
9682 lines
226 KiB
Plaintext
9682 lines
226 KiB
Plaintext
export const title = 'Agent Network'
|
|
|
|
|
|
|
|
## Provision a managed Agent Network gateway {{ tag: 'POST' , label: '/api/integrations/agent-network/managed-proxy' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Starts provisioning of a NetBird-managed Agent Network gateway for the account, allocating its endpoint under the managed zone on the first call. Idempotent — answers 202 when this call started (or, after a failure, restarted) provisioning and 200 when a deployment already exists, reporting current state either way. Returns 409 when the account already has an Agent Network endpoint that managed provisioning does not own, and 503 when endpoint allocation is temporarily exhausted.
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="POST" label="/api/integrations/agent-network/managed-proxy">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X POST https://api.netbird.io/api/integrations/agent-network/managed-proxy \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'post',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/integrations/agent-network/managed-proxy',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/integrations/agent-network/managed-proxy"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("POST", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/integrations/agent-network/managed-proxy"
|
|
method := "POST"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/integrations/agent-network/managed-proxy")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Post.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/integrations/agent-network/managed-proxy")
|
|
.method("POST")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/integrations/agent-network/managed-proxy',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'POST',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"id": "d1m3kebd9pcs0c1pnu7g",
|
|
"state": "ready",
|
|
"endpoint": "brave-otter.gateway.netbird.io",
|
|
"region": "us-east",
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Failure detail reported by the rollout. Only set when state is `failed`."
|
|
}
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"id": "string",
|
|
"state": "string",
|
|
"endpoint": "string",
|
|
"region": "string",
|
|
"message": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Retrieve managed Agent Network gateway status {{ tag: 'GET' , label: '/api/integrations/agent-network/managed-proxy' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Reports the account's managed gateway deployment and its derived state. Returns 404 when the account has no managed deployment.
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="GET" label="/api/integrations/agent-network/managed-proxy">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X GET https://api.netbird.io/api/integrations/agent-network/managed-proxy \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'get',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/integrations/agent-network/managed-proxy',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/integrations/agent-network/managed-proxy"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("GET", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/integrations/agent-network/managed-proxy"
|
|
method := "GET"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/integrations/agent-network/managed-proxy")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Get.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/integrations/agent-network/managed-proxy")
|
|
.method("GET")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/integrations/agent-network/managed-proxy',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'GET',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"id": "d1m3kebd9pcs0c1pnu7g",
|
|
"state": "ready",
|
|
"endpoint": "brave-otter.gateway.netbird.io",
|
|
"region": "us-east",
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Failure detail reported by the rollout. Only set when state is `failed`."
|
|
}
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"id": "string",
|
|
"state": "string",
|
|
"endpoint": "string",
|
|
"region": "string",
|
|
"message": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## List Agent Network access logs {{ tag: 'GET' , label: '/api/agent-network/access-logs' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Returns a paginated, server-side-filtered list of agent-network (LLM) access log entries. Available only when the account has log collection enabled; otherwise entries are not retained. Callers without the account-wide grant are not denied - the response is scoped to their own requests (any user_id or group_id filter is overridden).
|
|
|
|
### Query Parameters
|
|
<Properties>
|
|
|
|
<Property name="page" type="integer" required={false}>
|
|
Page number for pagination (1-indexed).
|
|
</Property>
|
|
|
|
<Property name="page_size" type="integer" required={false}>
|
|
Number of items per page (max 100).
|
|
</Property>
|
|
|
|
<Property name="sort_by" type="string" required={false}>
|
|
Field to sort by.
|
|
</Property>
|
|
|
|
<Property name="sort_order" type="string" required={false}>
|
|
Sort order (ascending or descending).
|
|
</Property>
|
|
|
|
<Property name="search" type="string" required={false}>
|
|
General search across log ID, host, path, model, and user email/name.
|
|
</Property>
|
|
|
|
<Property name="user_id" type="string" required={false}>
|
|
Filter by authenticated user ID.
|
|
</Property>
|
|
|
|
<Property name="session_id" type="string" required={false}>
|
|
Filter to a single conversation / coding session id (groups all requests of one session).
|
|
</Property>
|
|
|
|
<Property name="group_id" type="array" required={false}>
|
|
Filter by authorising group id. Repeat for multiple (matches any).
|
|
</Property>
|
|
|
|
<Property name="provider_id" type="array" required={false}>
|
|
Filter by resolved provider id. Repeat for multiple (matches any).
|
|
</Property>
|
|
|
|
<Property name="model" type="array" required={false}>
|
|
Filter by model. Repeat for multiple (matches any).
|
|
</Property>
|
|
|
|
<Property name="decision" type="string" required={false}>
|
|
Filter by policy decision (e.g. allow, deny).
|
|
</Property>
|
|
|
|
<Property name="path" type="string" required={false}>
|
|
Filter by request path prefix (matches entries whose path starts with this value).
|
|
</Property>
|
|
|
|
<Property name="start_date" type="string" required={false}>
|
|
Filter by timestamp {'>='} start_date (RFC3339 format).
|
|
</Property>
|
|
|
|
<Property name="end_date" type="string" required={false}>
|
|
Filter by timestamp {'<='} end_date (RFC3339 format).
|
|
</Property>
|
|
</Properties>
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="GET" label="/api/agent-network/access-logs">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X GET https://api.netbird.io/api/agent-network/access-logs \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'get',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/access-logs',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/access-logs"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("GET", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/access-logs"
|
|
method := "GET"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/access-logs")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Get.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/access-logs")
|
|
.method("GET")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/access-logs',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'GET',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"data": [
|
|
{
|
|
"id": "ch8i4ug6lnn4g9hqv7m0",
|
|
"service_id": {
|
|
"type": "string",
|
|
"description": "ID of the synthesised agent-network service that handled the request."
|
|
},
|
|
"timestamp": "2026-05-05T12:34:56Z",
|
|
"status_code": 200,
|
|
"duration_ms": 850,
|
|
"user_id": {
|
|
"type": "string",
|
|
"description": "NetBird user id of the authenticated caller, if applicable."
|
|
},
|
|
"source_ip": {
|
|
"type": "string",
|
|
"description": "Source IP of the request. Empty when log collection is disabled."
|
|
},
|
|
"method": "POST",
|
|
"host": {
|
|
"type": "string",
|
|
"description": "Upstream host the request was routed to. Empty when log collection is disabled."
|
|
},
|
|
"path": {
|
|
"type": "string",
|
|
"description": "Request path. Empty when log collection is disabled."
|
|
},
|
|
"provider": "openai",
|
|
"model": "gpt-4o",
|
|
"session_id": "019eeb72-ab7c-7cd2-aa05-6e8eb834afcb",
|
|
"resolved_provider_id": {
|
|
"type": "string",
|
|
"description": "NetBird agent-network provider id that served the request."
|
|
},
|
|
"selected_policy_id": {
|
|
"type": "string",
|
|
"description": "Agent-network policy id that authorised (or denied) the request."
|
|
},
|
|
"decision": "allow",
|
|
"deny_reason": {
|
|
"type": "string",
|
|
"description": "Raw deny reason code when the request was blocked (e.g. llm_policy.token_cap_exceeded)."
|
|
},
|
|
"input_tokens": 1200,
|
|
"output_tokens": 640,
|
|
"total_tokens": 1840,
|
|
"cached_input_tokens": 0,
|
|
"cache_creation_tokens": 30528,
|
|
"cost_usd": 0.0231,
|
|
"input_cost_usd": 0.0048,
|
|
"cached_input_cost_usd": 0.0015,
|
|
"cache_creation_cost_usd": 0.113,
|
|
"output_cost_usd": 0.0038,
|
|
"cache_cost_usd": 0.1145,
|
|
"stream": {
|
|
"type": "boolean",
|
|
"description": "Whether the request was a streaming completion."
|
|
},
|
|
"group_ids": [
|
|
{
|
|
"type": "string"
|
|
}
|
|
],
|
|
"request_prompt": {
|
|
"type": "string",
|
|
"description": "Captured request prompt. Present only when prompt collection is enabled."
|
|
},
|
|
"response_completion": {
|
|
"type": "string",
|
|
"description": "Captured response completion. Present only when prompt collection is enabled."
|
|
}
|
|
}
|
|
],
|
|
"page": 1,
|
|
"page_size": 50,
|
|
"total_records": 523,
|
|
"total_pages": 11
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"data": [
|
|
{
|
|
"id": "string",
|
|
"service_id": "string",
|
|
"timestamp": "string",
|
|
"status_code": "integer",
|
|
"duration_ms": "integer",
|
|
"user_id": "string",
|
|
"source_ip": "string",
|
|
"method": "string",
|
|
"host": "string",
|
|
"path": "string",
|
|
"provider": "string",
|
|
"model": "string",
|
|
"session_id": "string",
|
|
"resolved_provider_id": "string",
|
|
"selected_policy_id": "string",
|
|
"decision": "string",
|
|
"deny_reason": "string",
|
|
"input_tokens": "integer",
|
|
"output_tokens": "integer",
|
|
"total_tokens": "integer",
|
|
"cached_input_tokens": "integer",
|
|
"cache_creation_tokens": "integer",
|
|
"cost_usd": "number",
|
|
"input_cost_usd": "number",
|
|
"cached_input_cost_usd": "number",
|
|
"cache_creation_cost_usd": "number",
|
|
"output_cost_usd": "number",
|
|
"cache_cost_usd": "number",
|
|
"stream": "boolean",
|
|
"group_ids": [
|
|
"string"
|
|
],
|
|
"request_prompt": "string",
|
|
"response_completion": "string"
|
|
}
|
|
],
|
|
"page": "integer",
|
|
"page_size": "integer",
|
|
"total_records": "integer",
|
|
"total_pages": "integer"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## List Agent Network access logs grouped by session {{ tag: 'GET' , label: '/api/agent-network/access-log-sessions' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Returns a paginated, server-side-filtered list of agent-network (LLM) access logs grouped by session. The page unit is a session (total_records counts sessions); each session carries an aggregate summary and its ordered entries. Requests the client sent no session id for each form their own singleton group. Accepts the same filters as the flat access-logs endpoint. Available only when the account has log collection enabled. Callers without the account-wide grant are not denied - the response is scoped to their own requests (any user_id or group_id filter is overridden).
|
|
|
|
### Query Parameters
|
|
<Properties>
|
|
|
|
<Property name="page" type="integer" required={false}>
|
|
Page number for pagination (1-indexed).
|
|
</Property>
|
|
|
|
<Property name="page_size" type="integer" required={false}>
|
|
Number of sessions per page (max 100).
|
|
</Property>
|
|
|
|
<Property name="sort_by" type="string" required={false}>
|
|
Session-level field to sort by. "timestamp" is the session's last activity, "started_at" its first.
|
|
</Property>
|
|
|
|
<Property name="sort_order" type="string" required={false}>
|
|
Sort order (ascending or descending).
|
|
</Property>
|
|
|
|
<Property name="search" type="string" required={false}>
|
|
General search across log ID, host, path, model, and user email/name.
|
|
</Property>
|
|
|
|
<Property name="user_id" type="string" required={false}>
|
|
Filter by authenticated user ID.
|
|
</Property>
|
|
|
|
<Property name="session_id" type="string" required={false}>
|
|
Filter to a single conversation / coding session id.
|
|
</Property>
|
|
|
|
<Property name="group_id" type="array" required={false}>
|
|
Filter by authorising group id. Repeat for multiple (matches any).
|
|
</Property>
|
|
|
|
<Property name="provider_id" type="array" required={false}>
|
|
Filter by resolved provider id. Repeat for multiple (matches any).
|
|
</Property>
|
|
|
|
<Property name="model" type="array" required={false}>
|
|
Filter by model. Repeat for multiple (matches any).
|
|
</Property>
|
|
|
|
<Property name="decision" type="string" required={false}>
|
|
Filter by policy decision (e.g. allow, deny).
|
|
</Property>
|
|
|
|
<Property name="path" type="string" required={false}>
|
|
Filter by request path prefix (matches entries whose path starts with this value).
|
|
</Property>
|
|
|
|
<Property name="start_date" type="string" required={false}>
|
|
Filter by timestamp {'>='} start_date (RFC3339 format).
|
|
</Property>
|
|
|
|
<Property name="end_date" type="string" required={false}>
|
|
Filter by timestamp {'<='} end_date (RFC3339 format).
|
|
</Property>
|
|
</Properties>
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="GET" label="/api/agent-network/access-log-sessions">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X GET https://api.netbird.io/api/agent-network/access-log-sessions \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'get',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/access-log-sessions',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/access-log-sessions"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("GET", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/access-log-sessions"
|
|
method := "GET"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/access-log-sessions")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Get.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/access-log-sessions")
|
|
.method("GET")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/access-log-sessions',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'GET',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"data": [
|
|
{
|
|
"session_id": "019eeb72-ab7c-7cd2-aa05-6e8eb834afcb",
|
|
"user_id": {
|
|
"type": "string",
|
|
"description": "NetBird user id of the session's caller."
|
|
},
|
|
"group_ids": [
|
|
{
|
|
"type": "string"
|
|
}
|
|
],
|
|
"started_at": "2026-05-05T12:30:00Z",
|
|
"ended_at": "2026-05-05T12:34:56Z",
|
|
"request_count": 7,
|
|
"input_tokens": 8400,
|
|
"output_tokens": 4480,
|
|
"total_tokens": 12880,
|
|
"cached_input_tokens": 0,
|
|
"cache_creation_tokens": 30528,
|
|
"cost_usd": 0.1617,
|
|
"input_cost_usd": 0.021,
|
|
"cached_input_cost_usd": 0.0015,
|
|
"cache_creation_cost_usd": 0.113,
|
|
"output_cost_usd": 0.0262,
|
|
"cache_cost_usd": 0.1145,
|
|
"providers": [
|
|
{
|
|
"type": "string"
|
|
}
|
|
],
|
|
"models": [
|
|
{
|
|
"type": "string"
|
|
}
|
|
],
|
|
"decision": "allow",
|
|
"entries": [
|
|
{
|
|
"id": "ch8i4ug6lnn4g9hqv7m0",
|
|
"service_id": {
|
|
"type": "string",
|
|
"description": "ID of the synthesised agent-network service that handled the request."
|
|
},
|
|
"timestamp": "2026-05-05T12:34:56Z",
|
|
"status_code": 200,
|
|
"duration_ms": 850,
|
|
"user_id": {
|
|
"type": "string",
|
|
"description": "NetBird user id of the authenticated caller, if applicable."
|
|
},
|
|
"source_ip": {
|
|
"type": "string",
|
|
"description": "Source IP of the request. Empty when log collection is disabled."
|
|
},
|
|
"method": "POST",
|
|
"host": {
|
|
"type": "string",
|
|
"description": "Upstream host the request was routed to. Empty when log collection is disabled."
|
|
},
|
|
"path": {
|
|
"type": "string",
|
|
"description": "Request path. Empty when log collection is disabled."
|
|
},
|
|
"provider": "openai",
|
|
"model": "gpt-4o",
|
|
"session_id": "019eeb72-ab7c-7cd2-aa05-6e8eb834afcb",
|
|
"resolved_provider_id": {
|
|
"type": "string",
|
|
"description": "NetBird agent-network provider id that served the request."
|
|
},
|
|
"selected_policy_id": {
|
|
"type": "string",
|
|
"description": "Agent-network policy id that authorised (or denied) the request."
|
|
},
|
|
"decision": "allow",
|
|
"deny_reason": {
|
|
"type": "string",
|
|
"description": "Raw deny reason code when the request was blocked (e.g. llm_policy.token_cap_exceeded)."
|
|
},
|
|
"input_tokens": 1200,
|
|
"output_tokens": 640,
|
|
"total_tokens": 1840,
|
|
"cached_input_tokens": 0,
|
|
"cache_creation_tokens": 30528,
|
|
"cost_usd": 0.0231,
|
|
"input_cost_usd": 0.0048,
|
|
"cached_input_cost_usd": 0.0015,
|
|
"cache_creation_cost_usd": 0.113,
|
|
"output_cost_usd": 0.0038,
|
|
"cache_cost_usd": 0.1145,
|
|
"stream": {
|
|
"type": "boolean",
|
|
"description": "Whether the request was a streaming completion."
|
|
},
|
|
"group_ids": [
|
|
{
|
|
"type": "string"
|
|
}
|
|
],
|
|
"request_prompt": {
|
|
"type": "string",
|
|
"description": "Captured request prompt. Present only when prompt collection is enabled."
|
|
},
|
|
"response_completion": {
|
|
"type": "string",
|
|
"description": "Captured response completion. Present only when prompt collection is enabled."
|
|
}
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"page": 1,
|
|
"page_size": 50,
|
|
"total_records": 124,
|
|
"total_pages": 3
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"data": [
|
|
{
|
|
"session_id": "string",
|
|
"user_id": "string",
|
|
"group_ids": [
|
|
"string"
|
|
],
|
|
"started_at": "string",
|
|
"ended_at": "string",
|
|
"request_count": "integer",
|
|
"input_tokens": "integer",
|
|
"output_tokens": "integer",
|
|
"total_tokens": "integer",
|
|
"cached_input_tokens": "integer",
|
|
"cache_creation_tokens": "integer",
|
|
"cost_usd": "number",
|
|
"input_cost_usd": "number",
|
|
"cached_input_cost_usd": "number",
|
|
"cache_creation_cost_usd": "number",
|
|
"output_cost_usd": "number",
|
|
"cache_cost_usd": "number",
|
|
"providers": [
|
|
"string"
|
|
],
|
|
"models": [
|
|
"string"
|
|
],
|
|
"decision": "string",
|
|
"entries": [
|
|
{
|
|
"id": "string",
|
|
"service_id": "string",
|
|
"timestamp": "string",
|
|
"status_code": "integer",
|
|
"duration_ms": "integer",
|
|
"user_id": "string",
|
|
"source_ip": "string",
|
|
"method": "string",
|
|
"host": "string",
|
|
"path": "string",
|
|
"provider": "string",
|
|
"model": "string",
|
|
"session_id": "string",
|
|
"resolved_provider_id": "string",
|
|
"selected_policy_id": "string",
|
|
"decision": "string",
|
|
"deny_reason": "string",
|
|
"input_tokens": "integer",
|
|
"output_tokens": "integer",
|
|
"total_tokens": "integer",
|
|
"cached_input_tokens": "integer",
|
|
"cache_creation_tokens": "integer",
|
|
"cost_usd": "number",
|
|
"input_cost_usd": "number",
|
|
"cached_input_cost_usd": "number",
|
|
"cache_creation_cost_usd": "number",
|
|
"output_cost_usd": "number",
|
|
"cache_cost_usd": "number",
|
|
"stream": "boolean",
|
|
"group_ids": [
|
|
"string"
|
|
],
|
|
"request_prompt": "string",
|
|
"response_completion": "string"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"page": "integer",
|
|
"page_size": "integer",
|
|
"total_records": "integer",
|
|
"total_pages": "integer"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Agent Network usage overview {{ tag: 'GET' , label: '/api/agent-network/usage/overview' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Returns agent-network token and cost usage aggregated into time buckets, server-side filtered. Usage is always collected (independent of log collection). Callers without the account-wide grant are not denied - the response is scoped to their own usage (any user_id or group_id filter is overridden).
|
|
|
|
### Query Parameters
|
|
<Properties>
|
|
|
|
<Property name="granularity" type="string" required={false}>
|
|
Time bucket width. Defaults to day.
|
|
</Property>
|
|
|
|
<Property name="start_date" type="string" required={false}>
|
|
Filter by timestamp {'>='} start_date (RFC3339 format).
|
|
</Property>
|
|
|
|
<Property name="end_date" type="string" required={false}>
|
|
Filter by timestamp {'<='} end_date (RFC3339 format).
|
|
</Property>
|
|
|
|
<Property name="user_id" type="string" required={false}>
|
|
Filter by user ID.
|
|
</Property>
|
|
|
|
<Property name="session_id" type="string" required={false}>
|
|
Filter to a single conversation / coding session id.
|
|
</Property>
|
|
|
|
<Property name="group_id" type="array" required={false}>
|
|
Filter by authorising group id. Repeat for multiple (matches any).
|
|
</Property>
|
|
|
|
<Property name="provider_id" type="array" required={false}>
|
|
Filter by resolved provider id. Repeat for multiple (matches any).
|
|
</Property>
|
|
|
|
<Property name="model" type="array" required={false}>
|
|
Filter by model. Repeat for multiple (matches any).
|
|
</Property>
|
|
</Properties>
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="GET" label="/api/agent-network/usage/overview">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X GET https://api.netbird.io/api/agent-network/usage/overview \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'get',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/usage/overview',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/usage/overview"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("GET", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/usage/overview"
|
|
method := "GET"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/usage/overview")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Get.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/usage/overview")
|
|
.method("GET")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/usage/overview',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'GET',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
[
|
|
{
|
|
"period_start": "2026-05-05",
|
|
"input_tokens": 120000,
|
|
"output_tokens": 64000,
|
|
"total_tokens": 184000,
|
|
"cached_input_tokens": 20000,
|
|
"cache_creation_tokens": 45000,
|
|
"input_cost_usd": 1.12,
|
|
"cached_input_cost_usd": 0.06,
|
|
"cache_creation_cost_usd": 0.36,
|
|
"output_cost_usd": 0.77,
|
|
"cost_usd": 2.31,
|
|
"cache_cost_usd": 0.42
|
|
}
|
|
]
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
[
|
|
{
|
|
"period_start": "string",
|
|
"input_tokens": "integer",
|
|
"output_tokens": "integer",
|
|
"total_tokens": "integer",
|
|
"cached_input_tokens": "integer",
|
|
"cache_creation_tokens": "integer",
|
|
"input_cost_usd": "number",
|
|
"cached_input_cost_usd": "number",
|
|
"cache_creation_cost_usd": "number",
|
|
"output_cost_usd": "number",
|
|
"cost_usd": "number",
|
|
"cache_cost_usd": "number"
|
|
}
|
|
]
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## List Agent Network consumption counters {{ tag: 'GET' , label: '/api/agent-network/consumption' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Returns every per-(dimension, window) consumption counter recorded for the account, ordered window-newest-first. Empty list when nothing has been consumed yet.
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="GET" label="/api/agent-network/consumption">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X GET https://api.netbird.io/api/agent-network/consumption \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'get',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/consumption',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/consumption"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("GET", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/consumption"
|
|
method := "GET"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/consumption")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Get.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/consumption")
|
|
.method("GET")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/consumption',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'GET',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
[
|
|
{
|
|
"dimension_kind": {
|
|
"type": "string",
|
|
"enum": [
|
|
"user",
|
|
"group"
|
|
],
|
|
"description": "Whether this row counts a single end user or a single source group across every member."
|
|
},
|
|
"dimension_id": "grp-engineers",
|
|
"window_seconds": 86400,
|
|
"window_start_utc": "2026-05-05T12:00:00Z",
|
|
"tokens_input": 12000,
|
|
"tokens_output": 6500,
|
|
"cost_usd": 0.4231,
|
|
"updated_at": "2026-05-05T12:34:56Z"
|
|
}
|
|
]
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
[
|
|
{
|
|
"dimension_kind": "string",
|
|
"dimension_id": "string",
|
|
"window_seconds": "integer",
|
|
"window_start_utc": "string",
|
|
"tokens_input": "integer",
|
|
"tokens_output": "integer",
|
|
"cost_usd": "number",
|
|
"updated_at": "string"
|
|
}
|
|
]
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Retrieve the caller's Agent Network agent config {{ tag: 'GET' , label: '/api/agent-network/agent-config' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Returns everything the caller needs to configure a local AI tool and nothing more - the account's Agent Network endpoint plus the providers and models the caller's own policies allow. Available to every authenticated user regardless of role; the response never contains provider credentials, policy or guardrail configuration, or providers the caller cannot reach.
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="GET" label="/api/agent-network/agent-config">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X GET https://api.netbird.io/api/agent-network/agent-config \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'get',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/agent-config',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/agent-config"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("GET", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/agent-config"
|
|
method := "GET"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/agent-config")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Get.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/agent-config")
|
|
.method("GET")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/agent-config',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'GET',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"configured": {
|
|
"type": "boolean",
|
|
"description": "False only when the account has no Agent Network set up. A caller that no policy covers yet still reads as configured, with an empty providers list."
|
|
},
|
|
"endpoint": "https://calm-otter.proxy.example.com",
|
|
"providers": [
|
|
{
|
|
"name": "Bedrock prod",
|
|
"catalog_id": "bedrock_api",
|
|
"api_flavor": "anthropic",
|
|
"all_models_allowed": {
|
|
"type": "boolean",
|
|
"description": "True when no model allowlist restricts this provider for the caller; models then lists the declared or catalog models as a courtesy."
|
|
},
|
|
"models": [
|
|
"anthropic.claude-sonnet-4-5"
|
|
]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"configured": "boolean",
|
|
"endpoint": "string",
|
|
"providers": [
|
|
{
|
|
"name": "string",
|
|
"catalog_id": "string",
|
|
"api_flavor": "string",
|
|
"all_models_allowed": "boolean",
|
|
"models": [
|
|
"string"
|
|
]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Retrieve Agent Network settings {{ tag: 'GET' , label: '/api/agent-network/settings' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Returns the per-account Agent Network gateway settings (endpoint, proxy address, collection toggles). Before the account is bootstrapped via POST, the response carries the default values with an empty endpoint and proxy address.
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="GET" label="/api/agent-network/settings">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X GET https://api.netbird.io/api/agent-network/settings \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'get',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/settings',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/settings"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("GET", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/settings"
|
|
method := "GET"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/settings")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Get.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/settings")
|
|
.method("GET")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/settings',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'GET',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"endpoint": "brave-otter.eu.proxy.netbird.io",
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"dedicated": false,
|
|
"enable_log_collection": false,
|
|
"enable_prompt_collection": false,
|
|
"redact_pii": false,
|
|
"access_log_retention_days": 30,
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"endpoint": "string",
|
|
"proxy_address": "string",
|
|
"dedicated": "boolean",
|
|
"enable_log_collection": "boolean",
|
|
"enable_prompt_collection": "boolean",
|
|
"redact_pii": "boolean",
|
|
"access_log_retention_days": "integer",
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Bootstrap Agent Network settings {{ tag: 'POST' , label: '/api/agent-network/settings' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Creates the per-account Agent Network settings row and allocates the account's endpoint. Exactly one of `proxy_address` (labeled endpoint under that cluster; the server allocates the label) and `endpoint` (self-addressed dedicated endpoint, claimed verbatim) must be provided. The endpoint and proxy address are immutable once assigned. Returns 409 when the account already has a settings row.
|
|
|
|
### Request-Body Parameters
|
|
|
|
<Properties><Property name="proxy_address" type="string" required={false}>
|
|
|
|
Cluster address to allocate a labeled endpoint beneath. Mutually exclusive with `endpoint`.
|
|
|
|
</Property>
|
|
<Property name="endpoint" type="string" required={false}>
|
|
|
|
Hostname to claim as the account's self-addressed (dedicated) endpoint. Mutually exclusive with `proxy_address`. Rejected when another account already holds it.
|
|
|
|
</Property>
|
|
<Property name="enable_log_collection" type="boolean" required={false}>
|
|
|
|
Whether per-request access-log entries are collected for this account's agent-network traffic. Defaults to true.
|
|
|
|
</Property>
|
|
<Property name="enable_prompt_collection" type="boolean" required={false}>
|
|
|
|
Master switch for request/response prompt capture. Defaults to false.
|
|
|
|
</Property>
|
|
<Property name="redact_pii" type="boolean" required={false}>
|
|
|
|
Whether captured prompts have PII redacted. Defaults to false.
|
|
|
|
</Property>
|
|
<Property name="access_log_retention_days" type="integer" required={false}>
|
|
|
|
Days to retain full access-log rows; older rows are swept. 0 or less means keep indefinitely. Defaults to 30.
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="POST" label="/api/agent-network/settings">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X POST https://api.netbird.io/api/agent-network/settings \
|
|
-H 'Accept: application/json' \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Authorization: Token <TOKEN>' \
|
|
--data-raw '{
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"endpoint": "brave-otter.gateway.example.com",
|
|
"enable_log_collection": true,
|
|
"enable_prompt_collection": false,
|
|
"redact_pii": false,
|
|
"access_log_retention_days": 30
|
|
}'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
let data = JSON.stringify({
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"endpoint": "brave-otter.gateway.example.com",
|
|
"enable_log_collection": true,
|
|
"enable_prompt_collection": false,
|
|
"redact_pii": false,
|
|
"access_log_retention_days": 30
|
|
});
|
|
let config = {
|
|
method: 'post',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/settings',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
},
|
|
data : data
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/settings"
|
|
payload = json.dumps({
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"endpoint": "brave-otter.gateway.example.com",
|
|
"enable_log_collection": true,
|
|
"enable_prompt_collection": false,
|
|
"redact_pii": false,
|
|
"access_log_retention_days": 30
|
|
})
|
|
headers = {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("POST", url, headers=headers, data=payload)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/settings"
|
|
method := "POST"
|
|
|
|
payload := strings.NewReader(`{
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"endpoint": "brave-otter.gateway.example.com",
|
|
"enable_log_collection": true,
|
|
"enable_prompt_collection": false,
|
|
"redact_pii": false,
|
|
"access_log_retention_days": 30
|
|
}`)
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, payload)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Content-Type", "application/json")
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/settings")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Post.new(url)
|
|
request["Content-Type"] = "application/json"
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
request.body = JSON.dump({
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"endpoint": "brave-otter.gateway.example.com",
|
|
"enable_log_collection": true,
|
|
"enable_prompt_collection": false,
|
|
"redact_pii": false,
|
|
"access_log_retention_days": 30
|
|
})
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
MediaType mediaType = MediaType.parse("application/json");
|
|
RequestBody body = RequestBody.create(mediaType, '{
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"endpoint": "brave-otter.gateway.example.com",
|
|
"enable_log_collection": true,
|
|
"enable_prompt_collection": false,
|
|
"redact_pii": false,
|
|
"access_log_retention_days": 30
|
|
}');
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/settings")
|
|
.method("POST", body)
|
|
.addHeader("Content-Type", "application/json")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/settings',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'POST',
|
|
CURLOPT_POSTFIELDS => '{
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"endpoint": "brave-otter.gateway.example.com",
|
|
"enable_log_collection": true,
|
|
"enable_prompt_collection": false,
|
|
"redact_pii": false,
|
|
"access_log_retention_days": 30
|
|
}',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Content-Type: application/json',
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"endpoint": "brave-otter.eu.proxy.netbird.io",
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"dedicated": false,
|
|
"enable_log_collection": false,
|
|
"enable_prompt_collection": false,
|
|
"redact_pii": false,
|
|
"access_log_retention_days": 30,
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"endpoint": "string",
|
|
"proxy_address": "string",
|
|
"dedicated": "boolean",
|
|
"enable_log_collection": "boolean",
|
|
"enable_prompt_collection": "boolean",
|
|
"redact_pii": "boolean",
|
|
"access_log_retention_days": "integer",
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Update Agent Network settings {{ tag: 'PUT' , label: '/api/agent-network/settings' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Updates the account-level Agent Network settings; the request carries every field, replacing the mutable ones (collection toggles and retention). Returns 404 when the account has no settings row yet — bootstrap it with POST first. The endpoint and proxy address are assigned at bootstrap and immutable; the request must carry them unchanged, and a request carrying different values is rejected.
|
|
|
|
### Request-Body Parameters
|
|
|
|
<Properties><Property name="endpoint" type="string" required={true}>
|
|
|
|
The account's gateway endpoint hostname. Immutable — must match the assigned value; a different value is rejected.
|
|
|
|
</Property>
|
|
<Property name="proxy_address" type="string" required={true}>
|
|
|
|
Declared cluster address of the proxy serving this account's gateway. Immutable — must match the assigned value; a different value is rejected.
|
|
|
|
</Property>
|
|
<Property name="enable_log_collection" type="boolean" required={true}>
|
|
|
|
Whether per-request access-log entries are collected for this account's agent-network traffic.
|
|
|
|
</Property>
|
|
<Property name="enable_prompt_collection" type="boolean" required={true}>
|
|
|
|
Master switch for request/response prompt capture.
|
|
|
|
</Property>
|
|
<Property name="redact_pii" type="boolean" required={true}>
|
|
|
|
Whether captured prompts have PII redacted.
|
|
|
|
</Property>
|
|
<Property name="access_log_retention_days" type="integer" required={true}>
|
|
|
|
Days to retain full access-log rows; older rows are swept. 0 or less means keep indefinitely.
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="PUT" label="/api/agent-network/settings">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X PUT https://api.netbird.io/api/agent-network/settings \
|
|
-H 'Accept: application/json' \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Authorization: Token <TOKEN>' \
|
|
--data-raw '{
|
|
"endpoint": "brave-otter.eu.proxy.netbird.io",
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"enable_log_collection": true,
|
|
"enable_prompt_collection": true,
|
|
"redact_pii": true,
|
|
"access_log_retention_days": 30
|
|
}'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
let data = JSON.stringify({
|
|
"endpoint": "brave-otter.eu.proxy.netbird.io",
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"enable_log_collection": true,
|
|
"enable_prompt_collection": true,
|
|
"redact_pii": true,
|
|
"access_log_retention_days": 30
|
|
});
|
|
let config = {
|
|
method: 'put',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/settings',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
},
|
|
data : data
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/settings"
|
|
payload = json.dumps({
|
|
"endpoint": "brave-otter.eu.proxy.netbird.io",
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"enable_log_collection": true,
|
|
"enable_prompt_collection": true,
|
|
"redact_pii": true,
|
|
"access_log_retention_days": 30
|
|
})
|
|
headers = {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("PUT", url, headers=headers, data=payload)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/settings"
|
|
method := "PUT"
|
|
|
|
payload := strings.NewReader(`{
|
|
"endpoint": "brave-otter.eu.proxy.netbird.io",
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"enable_log_collection": true,
|
|
"enable_prompt_collection": true,
|
|
"redact_pii": true,
|
|
"access_log_retention_days": 30
|
|
}`)
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, payload)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Content-Type", "application/json")
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/settings")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Put.new(url)
|
|
request["Content-Type"] = "application/json"
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
request.body = JSON.dump({
|
|
"endpoint": "brave-otter.eu.proxy.netbird.io",
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"enable_log_collection": true,
|
|
"enable_prompt_collection": true,
|
|
"redact_pii": true,
|
|
"access_log_retention_days": 30
|
|
})
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
MediaType mediaType = MediaType.parse("application/json");
|
|
RequestBody body = RequestBody.create(mediaType, '{
|
|
"endpoint": "brave-otter.eu.proxy.netbird.io",
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"enable_log_collection": true,
|
|
"enable_prompt_collection": true,
|
|
"redact_pii": true,
|
|
"access_log_retention_days": 30
|
|
}');
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/settings")
|
|
.method("PUT", body)
|
|
.addHeader("Content-Type", "application/json")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/settings',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'PUT',
|
|
CURLOPT_POSTFIELDS => '{
|
|
"endpoint": "brave-otter.eu.proxy.netbird.io",
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"enable_log_collection": true,
|
|
"enable_prompt_collection": true,
|
|
"redact_pii": true,
|
|
"access_log_retention_days": 30
|
|
}',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Content-Type: application/json',
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"endpoint": "brave-otter.eu.proxy.netbird.io",
|
|
"proxy_address": "eu.proxy.netbird.io",
|
|
"dedicated": false,
|
|
"enable_log_collection": false,
|
|
"enable_prompt_collection": false,
|
|
"redact_pii": false,
|
|
"access_log_retention_days": 30,
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"endpoint": "string",
|
|
"proxy_address": "string",
|
|
"dedicated": "boolean",
|
|
"enable_log_collection": "boolean",
|
|
"enable_prompt_collection": "boolean",
|
|
"redact_pii": "boolean",
|
|
"access_log_retention_days": "integer",
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Delete Agent Network settings {{ tag: 'DELETE' , label: '/api/agent-network/settings' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Deletes the account's Agent Network settings row, releasing the endpoint. Guarded — the delete is refused with 412 while any Agent Network provider exists for the account or while a proxy is actively serving the endpoint. Bootstrapping again after a delete allocates a new endpoint; the released hostname is not reserved.
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="DELETE" label="/api/agent-network/settings">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X DELETE https://api.netbird.io/api/agent-network/settings \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'delete',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/settings',
|
|
headers: {
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/settings"
|
|
|
|
headers = {
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("DELETE", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/settings"
|
|
method := "DELETE"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/settings")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Delete.new(url)
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/settings")
|
|
.method("DELETE")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/settings',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'DELETE',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## List all Agent Network budget rules {{ tag: 'GET' , label: '/api/agent-network/budget-rules' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Returns all account-level budget rules.
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="GET" label="/api/agent-network/budget-rules">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X GET https://api.netbird.io/api/agent-network/budget-rules \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'get',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/budget-rules',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/budget-rules"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("GET", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/budget-rules"
|
|
method := "GET"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/budget-rules")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Get.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/budget-rules")
|
|
.method("GET")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/budget-rules',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'GET',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
[
|
|
{
|
|
"id": "ainbud_d1m3kebd9pcs0c1pnu7g",
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
},
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
]
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
[
|
|
{
|
|
"id": "string",
|
|
"name": "string",
|
|
"enabled": "boolean",
|
|
"target_groups": [
|
|
"string"
|
|
],
|
|
"target_users": [
|
|
"string"
|
|
],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": "boolean",
|
|
"group_cap": "integer",
|
|
"user_cap": "integer",
|
|
"window_seconds": "integer"
|
|
},
|
|
"budget_limit": {
|
|
"enabled": "boolean",
|
|
"group_cap_usd": "number",
|
|
"user_cap_usd": "number",
|
|
"window_seconds": "integer"
|
|
}
|
|
},
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
]
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Create an Agent Network budget rule {{ tag: 'POST' , label: '/api/agent-network/budget-rules' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Creates a new account-level budget rule.
|
|
|
|
### Request-Body Parameters
|
|
|
|
<Properties><Property name="name" type="string" required={true}>
|
|
|
|
Display name for the budget rule.
|
|
|
|
</Property>
|
|
<Property name="enabled" type="boolean" required={false}>
|
|
|
|
Whether the rule is enforced. Defaults to true on create.
|
|
|
|
</Property>
|
|
<Property name="target_groups" type="string[]" required={false}>
|
|
|
|
NetBird group ids the rule binds. Empty plus empty target_users means account-wide.
|
|
|
|
</Property>
|
|
<Property name="target_users" type="string[]" required={false}>
|
|
|
|
NetBird user ids the rule binds directly.
|
|
|
|
</Property>
|
|
<Property name="limits" type="object" required={true}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>Token and budget caps attached directly to the policy. These compose with any guardrail-level checks.</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="token_limit" type="object" required={true}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>Per-policy token cap. `group_cap` is applied to each source group independently — every group in the policy's `source_groups` gets its own bucket of this size. `user_cap` is applied independently to each individual user. Caps reset to zero at the start of each window.</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="enabled" type="boolean" required={true}>
|
|
|
|
|
|
|
|
</Property>
|
|
<Property name="group_cap" type="integer" required={true} min={0}>
|
|
|
|
Tokens allowed per source group within the window (each group has its own bucket of this size). 0 means uncapped.
|
|
|
|
</Property>
|
|
<Property name="user_cap" type="integer" required={true} min={0}>
|
|
|
|
Tokens allowed per individual user within the window. 0 means uncapped.
|
|
|
|
</Property>
|
|
<Property name="window_seconds" type="integer" required={true} min={60}>
|
|
|
|
Reset frequency in seconds. The cap counter resets to zero at the start of each window. Minimum 60 (one minute) when the limit is enabled.
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
<Property name="budget_limit" type="object" required={true}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>Per-policy USD spend cap. `group_cap_usd` is applied to each source group independently — every group in the policy's `source_groups` gets its own bucket of this size. `user_cap_usd` is applied independently to each individual user. Caps reset to zero at the start of each window.</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="enabled" type="boolean" required={true}>
|
|
|
|
|
|
|
|
</Property>
|
|
<Property name="group_cap_usd" type="number" required={true} min={0}>
|
|
|
|
USD allowed per source group within the window (each group has its own bucket of this size). 0 means uncapped.
|
|
|
|
</Property>
|
|
<Property name="user_cap_usd" type="number" required={true} min={0}>
|
|
|
|
USD allowed per individual user within the window. 0 means uncapped.
|
|
|
|
</Property>
|
|
<Property name="window_seconds" type="integer" required={true} min={60}>
|
|
|
|
Reset frequency in seconds. Caps reset at the start of each window. Minimum 60 (one minute) when the limit is enabled.
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="POST" label="/api/agent-network/budget-rules">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X POST https://api.netbird.io/api/agent-network/budget-rules \
|
|
-H 'Accept: application/json' \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Authorization: Token <TOKEN>' \
|
|
--data-raw '{
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
}'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
let data = JSON.stringify({
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
});
|
|
let config = {
|
|
method: 'post',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/budget-rules',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
},
|
|
data : data
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/budget-rules"
|
|
payload = json.dumps({
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
})
|
|
headers = {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("POST", url, headers=headers, data=payload)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/budget-rules"
|
|
method := "POST"
|
|
|
|
payload := strings.NewReader(`{
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
}`)
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, payload)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Content-Type", "application/json")
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/budget-rules")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Post.new(url)
|
|
request["Content-Type"] = "application/json"
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
request.body = JSON.dump({
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
})
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
MediaType mediaType = MediaType.parse("application/json");
|
|
RequestBody body = RequestBody.create(mediaType, '{
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
}');
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/budget-rules")
|
|
.method("POST", body)
|
|
.addHeader("Content-Type", "application/json")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/budget-rules',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'POST',
|
|
CURLOPT_POSTFIELDS => '{
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
}',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Content-Type: application/json',
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"id": "ainbud_d1m3kebd9pcs0c1pnu7g",
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
},
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"id": "string",
|
|
"name": "string",
|
|
"enabled": "boolean",
|
|
"target_groups": [
|
|
"string"
|
|
],
|
|
"target_users": [
|
|
"string"
|
|
],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": "boolean",
|
|
"group_cap": "integer",
|
|
"user_cap": "integer",
|
|
"window_seconds": "integer"
|
|
},
|
|
"budget_limit": {
|
|
"enabled": "boolean",
|
|
"group_cap_usd": "number",
|
|
"user_cap_usd": "number",
|
|
"window_seconds": "integer"
|
|
}
|
|
},
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Retrieve an Agent Network budget rule {{ tag: 'GET' , label: '/api/agent-network/budget-rules/{ruleId}' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Get a specific account-level budget rule.
|
|
|
|
### Path Parameters
|
|
<Properties>
|
|
|
|
<Property name="ruleId" type="string" required={true}>
|
|
The unique identifier of a budget rule
|
|
</Property>
|
|
</Properties>
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="GET" label="/api/agent-network/budget-rules/{ruleId}">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X GET https://api.netbird.io/api/agent-network/budget-rules/{ruleId} \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'get',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/budget-rules/{ruleId}',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/budget-rules/{ruleId}"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("GET", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/budget-rules/{ruleId}"
|
|
method := "GET"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/budget-rules/{ruleId}")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Get.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/budget-rules/{ruleId}")
|
|
.method("GET")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/budget-rules/{ruleId}',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'GET',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"id": "ainbud_d1m3kebd9pcs0c1pnu7g",
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
},
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"id": "string",
|
|
"name": "string",
|
|
"enabled": "boolean",
|
|
"target_groups": [
|
|
"string"
|
|
],
|
|
"target_users": [
|
|
"string"
|
|
],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": "boolean",
|
|
"group_cap": "integer",
|
|
"user_cap": "integer",
|
|
"window_seconds": "integer"
|
|
},
|
|
"budget_limit": {
|
|
"enabled": "boolean",
|
|
"group_cap_usd": "number",
|
|
"user_cap_usd": "number",
|
|
"window_seconds": "integer"
|
|
}
|
|
},
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Update an Agent Network budget rule {{ tag: 'PUT' , label: '/api/agent-network/budget-rules/{ruleId}' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Updates an existing account-level budget rule.
|
|
|
|
### Path Parameters
|
|
<Properties>
|
|
|
|
<Property name="ruleId" type="string" required={true}>
|
|
The unique identifier of a budget rule
|
|
</Property>
|
|
</Properties>
|
|
|
|
### Request-Body Parameters
|
|
|
|
<Properties><Property name="name" type="string" required={true}>
|
|
|
|
Display name for the budget rule.
|
|
|
|
</Property>
|
|
<Property name="enabled" type="boolean" required={false}>
|
|
|
|
Whether the rule is enforced. Defaults to true on create.
|
|
|
|
</Property>
|
|
<Property name="target_groups" type="string[]" required={false}>
|
|
|
|
NetBird group ids the rule binds. Empty plus empty target_users means account-wide.
|
|
|
|
</Property>
|
|
<Property name="target_users" type="string[]" required={false}>
|
|
|
|
NetBird user ids the rule binds directly.
|
|
|
|
</Property>
|
|
<Property name="limits" type="object" required={true}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>Token and budget caps attached directly to the policy. These compose with any guardrail-level checks.</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="token_limit" type="object" required={true}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>Per-policy token cap. `group_cap` is applied to each source group independently — every group in the policy's `source_groups` gets its own bucket of this size. `user_cap` is applied independently to each individual user. Caps reset to zero at the start of each window.</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="enabled" type="boolean" required={true}>
|
|
|
|
|
|
|
|
</Property>
|
|
<Property name="group_cap" type="integer" required={true} min={0}>
|
|
|
|
Tokens allowed per source group within the window (each group has its own bucket of this size). 0 means uncapped.
|
|
|
|
</Property>
|
|
<Property name="user_cap" type="integer" required={true} min={0}>
|
|
|
|
Tokens allowed per individual user within the window. 0 means uncapped.
|
|
|
|
</Property>
|
|
<Property name="window_seconds" type="integer" required={true} min={60}>
|
|
|
|
Reset frequency in seconds. The cap counter resets to zero at the start of each window. Minimum 60 (one minute) when the limit is enabled.
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
<Property name="budget_limit" type="object" required={true}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>Per-policy USD spend cap. `group_cap_usd` is applied to each source group independently — every group in the policy's `source_groups` gets its own bucket of this size. `user_cap_usd` is applied independently to each individual user. Caps reset to zero at the start of each window.</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="enabled" type="boolean" required={true}>
|
|
|
|
|
|
|
|
</Property>
|
|
<Property name="group_cap_usd" type="number" required={true} min={0}>
|
|
|
|
USD allowed per source group within the window (each group has its own bucket of this size). 0 means uncapped.
|
|
|
|
</Property>
|
|
<Property name="user_cap_usd" type="number" required={true} min={0}>
|
|
|
|
USD allowed per individual user within the window. 0 means uncapped.
|
|
|
|
</Property>
|
|
<Property name="window_seconds" type="integer" required={true} min={60}>
|
|
|
|
Reset frequency in seconds. Caps reset at the start of each window. Minimum 60 (one minute) when the limit is enabled.
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="PUT" label="/api/agent-network/budget-rules/{ruleId}">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X PUT https://api.netbird.io/api/agent-network/budget-rules/{ruleId} \
|
|
-H 'Accept: application/json' \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Authorization: Token <TOKEN>' \
|
|
--data-raw '{
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
}'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
let data = JSON.stringify({
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
});
|
|
let config = {
|
|
method: 'put',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/budget-rules/{ruleId}',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
},
|
|
data : data
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/budget-rules/{ruleId}"
|
|
payload = json.dumps({
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
})
|
|
headers = {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("PUT", url, headers=headers, data=payload)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/budget-rules/{ruleId}"
|
|
method := "PUT"
|
|
|
|
payload := strings.NewReader(`{
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
}`)
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, payload)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Content-Type", "application/json")
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/budget-rules/{ruleId}")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Put.new(url)
|
|
request["Content-Type"] = "application/json"
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
request.body = JSON.dump({
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
})
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
MediaType mediaType = MediaType.parse("application/json");
|
|
RequestBody body = RequestBody.create(mediaType, '{
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
}');
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/budget-rules/{ruleId}")
|
|
.method("PUT", body)
|
|
.addHeader("Content-Type", "application/json")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/budget-rules/{ruleId}',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'PUT',
|
|
CURLOPT_POSTFIELDS => '{
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
}',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Content-Type: application/json',
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"id": "ainbud_d1m3kebd9pcs0c1pnu7g",
|
|
"name": "Org monthly ceiling",
|
|
"enabled": true,
|
|
"target_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"target_users": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
},
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"id": "string",
|
|
"name": "string",
|
|
"enabled": "boolean",
|
|
"target_groups": [
|
|
"string"
|
|
],
|
|
"target_users": [
|
|
"string"
|
|
],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": "boolean",
|
|
"group_cap": "integer",
|
|
"user_cap": "integer",
|
|
"window_seconds": "integer"
|
|
},
|
|
"budget_limit": {
|
|
"enabled": "boolean",
|
|
"group_cap_usd": "number",
|
|
"user_cap_usd": "number",
|
|
"window_seconds": "integer"
|
|
}
|
|
},
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Delete an Agent Network budget rule {{ tag: 'DELETE' , label: '/api/agent-network/budget-rules/{ruleId}' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Deletes an account-level budget rule.
|
|
|
|
### Path Parameters
|
|
<Properties>
|
|
|
|
<Property name="ruleId" type="string" required={true}>
|
|
The unique identifier of a budget rule
|
|
</Property>
|
|
</Properties>
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="DELETE" label="/api/agent-network/budget-rules/{ruleId}">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X DELETE https://api.netbird.io/api/agent-network/budget-rules/{ruleId} \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'delete',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/budget-rules/{ruleId}',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/budget-rules/{ruleId}"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("DELETE", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/budget-rules/{ruleId}"
|
|
method := "DELETE"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/budget-rules/{ruleId}")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Delete.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/budget-rules/{ruleId}")
|
|
.method("DELETE")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/budget-rules/{ruleId}',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'DELETE',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"type": "object"
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"type": "object"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## List Agent Network catalog providers {{ tag: 'GET' , label: '/api/agent-network/catalog/providers' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Returns the static catalog of supported Agent Network providers (OpenAI, Anthropic, …) along with their default upstream host, auth header template, brand color, and known models.
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="GET" label="/api/agent-network/catalog/providers">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X GET https://api.netbird.io/api/agent-network/catalog/providers \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'get',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/catalog/providers',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/catalog/providers"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("GET", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/catalog/providers"
|
|
method := "GET"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/catalog/providers")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Get.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/catalog/providers")
|
|
.method("GET")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/catalog/providers',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'GET',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
[
|
|
{
|
|
"id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"description": "GPT, Responses API, and Embeddings",
|
|
"default_host": "api.openai.com",
|
|
"auth_header_template": "Bearer ${API_KEY}",
|
|
"default_content_type": "application/json",
|
|
"brand_color": "#10A37F",
|
|
"kind": "provider",
|
|
"extra_headers": [
|
|
{
|
|
"name": "x-portkey-config"
|
|
}
|
|
],
|
|
"identity_injection": {
|
|
"header_pair": {
|
|
"customizable": true,
|
|
"end_user_id_header": "x-bf-dim-netbird_user_id",
|
|
"tags_header": "x-bf-dim-netbird_groups"
|
|
},
|
|
"json_metadata": {
|
|
"customizable": true,
|
|
"header": "cf-aig-metadata",
|
|
"user_key": "netbird_user_id",
|
|
"groups_key": "netbird_groups"
|
|
}
|
|
},
|
|
"pricing_surfaces": [
|
|
"openai"
|
|
],
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o",
|
|
"label": "GPT-4o",
|
|
"input_per_1k": 0.005,
|
|
"output_per_1k": 0.015,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375,
|
|
"context_window": 128000
|
|
}
|
|
]
|
|
}
|
|
]
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
[
|
|
{
|
|
"id": "string",
|
|
"name": "string",
|
|
"description": "string",
|
|
"default_host": "string",
|
|
"auth_header_template": "string",
|
|
"default_content_type": "string",
|
|
"brand_color": "string",
|
|
"kind": "string",
|
|
"extra_headers": [
|
|
{
|
|
"name": "string"
|
|
}
|
|
],
|
|
"identity_injection": {
|
|
"header_pair": {
|
|
"customizable": "boolean",
|
|
"end_user_id_header": "string",
|
|
"tags_header": "string"
|
|
},
|
|
"json_metadata": {
|
|
"customizable": "boolean",
|
|
"header": "string",
|
|
"user_key": "string",
|
|
"groups_key": "string"
|
|
}
|
|
},
|
|
"pricing_surfaces": [
|
|
"string"
|
|
],
|
|
"models": [
|
|
{
|
|
"id": "string",
|
|
"label": "string",
|
|
"input_per_1k": "number",
|
|
"output_per_1k": "number",
|
|
"cached_input_per_1k": "number",
|
|
"cache_read_per_1k": "number",
|
|
"cache_creation_per_1k": "number",
|
|
"context_window": "integer"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Discover the models a provider credential can reach {{ tag: 'POST' , label: '/api/agent-network/catalog/providers/models' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Asks the vendor which models the supplied credential can actually use, so the provider form can offer a live list instead of only the static catalog. The endpoint, auth header and response shape are taken from the catalog entry, never from the request.
|
|
|
|
Supply either an api_key together with the upstream_url being configured (before the provider is saved), or a provider_id of an existing record to reuse its stored credential.
|
|
|
|
Returns 422 for a catalog provider that has no listing endpoint (most gateways); the caller should fall back to the catalog's own model list. A model whose price the shipped table does not know is returned with pricing_known false, and the operator must set rates for it.
|
|
|
|
|
|
### Request-Body Parameters
|
|
|
|
<Properties><Property name="catalog_provider_id" type="string" required={true}>
|
|
|
|
Catalog provider to query (AgentNetworkCatalogProvider.id). Determines the listing endpoint, the auth header and the response shape.
|
|
|
|
</Property>
|
|
<Property name="upstream_url" type="string" required={false}>
|
|
|
|
The upstream being configured. Used to reach vendors that serve their listing from the same host as inference, and to read back the region for those whose host embeds one. Sent alongside provider_id, it overrides the stored upstream, so an edit can be listed against the URL on the form before it is saved.
|
|
|
|
|
|
</Property>
|
|
<Property name="api_key" type="string" required={false}>
|
|
|
|
Credential to query the vendor with, for a provider that has not been saved yet. Mutually exclusive with provider_id.
|
|
|
|
</Property>
|
|
<Property name="provider_id" type="string" required={false}>
|
|
|
|
Existing Agent Network provider record to query with. Its stored credential is used, and its upstream unless upstream_url overrides it, so the form can refresh the list without the client holding the key.
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="POST" label="/api/agent-network/catalog/providers/models">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X POST https://api.netbird.io/api/agent-network/catalog/providers/models \
|
|
-H 'Accept: application/json' \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Authorization: Token <TOKEN>' \
|
|
--data-raw '{
|
|
"catalog_provider_id": "bedrock_api",
|
|
"upstream_url": "https://bedrock-runtime.eu-central-1.amazonaws.com",
|
|
"api_key": "sk-...",
|
|
"provider_id": "ch8i4ug6lnn4g9hqv7m0"
|
|
}'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
let data = JSON.stringify({
|
|
"catalog_provider_id": "bedrock_api",
|
|
"upstream_url": "https://bedrock-runtime.eu-central-1.amazonaws.com",
|
|
"api_key": "sk-...",
|
|
"provider_id": "ch8i4ug6lnn4g9hqv7m0"
|
|
});
|
|
let config = {
|
|
method: 'post',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/catalog/providers/models',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
},
|
|
data : data
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/catalog/providers/models"
|
|
payload = json.dumps({
|
|
"catalog_provider_id": "bedrock_api",
|
|
"upstream_url": "https://bedrock-runtime.eu-central-1.amazonaws.com",
|
|
"api_key": "sk-...",
|
|
"provider_id": "ch8i4ug6lnn4g9hqv7m0"
|
|
})
|
|
headers = {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("POST", url, headers=headers, data=payload)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/catalog/providers/models"
|
|
method := "POST"
|
|
|
|
payload := strings.NewReader(`{
|
|
"catalog_provider_id": "bedrock_api",
|
|
"upstream_url": "https://bedrock-runtime.eu-central-1.amazonaws.com",
|
|
"api_key": "sk-...",
|
|
"provider_id": "ch8i4ug6lnn4g9hqv7m0"
|
|
}`)
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, payload)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Content-Type", "application/json")
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/catalog/providers/models")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Post.new(url)
|
|
request["Content-Type"] = "application/json"
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
request.body = JSON.dump({
|
|
"catalog_provider_id": "bedrock_api",
|
|
"upstream_url": "https://bedrock-runtime.eu-central-1.amazonaws.com",
|
|
"api_key": "sk-...",
|
|
"provider_id": "ch8i4ug6lnn4g9hqv7m0"
|
|
})
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
MediaType mediaType = MediaType.parse("application/json");
|
|
RequestBody body = RequestBody.create(mediaType, '{
|
|
"catalog_provider_id": "bedrock_api",
|
|
"upstream_url": "https://bedrock-runtime.eu-central-1.amazonaws.com",
|
|
"api_key": "sk-...",
|
|
"provider_id": "ch8i4ug6lnn4g9hqv7m0"
|
|
}');
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/catalog/providers/models")
|
|
.method("POST", body)
|
|
.addHeader("Content-Type", "application/json")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/catalog/providers/models',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'POST',
|
|
CURLOPT_POSTFIELDS => '{
|
|
"catalog_provider_id": "bedrock_api",
|
|
"upstream_url": "https://bedrock-runtime.eu-central-1.amazonaws.com",
|
|
"api_key": "sk-...",
|
|
"provider_id": "ch8i4ug6lnn4g9hqv7m0"
|
|
}',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Content-Type: application/json',
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"models": [
|
|
{
|
|
"id": "eu.anthropic.claude-haiku-4-5-20251001-v1:0",
|
|
"label": "EU Anthropic Claude Haiku 4.5",
|
|
"pricing_known": true,
|
|
"input_per_1k": 0.005,
|
|
"output_per_1k": 0.015,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
]
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"models": [
|
|
{
|
|
"id": "string",
|
|
"label": "string",
|
|
"pricing_known": "boolean",
|
|
"input_per_1k": "number",
|
|
"output_per_1k": "number",
|
|
"cached_input_per_1k": "number",
|
|
"cache_read_per_1k": "number",
|
|
"cache_creation_per_1k": "number"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## List all Agent Network Providers {{ tag: 'GET' , label: '/api/agent-network/providers' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Returns a list of all Agent Network AI providers configured for the account.
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="GET" label="/api/agent-network/providers">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X GET https://api.netbird.io/api/agent-network/providers \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'get',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/providers',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/providers"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("GET", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/providers"
|
|
method := "GET"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/providers")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Get.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/providers")
|
|
.method("GET")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/providers',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'GET',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
[
|
|
{
|
|
"id": "ainp_d1m3kebd9pcs0c1pnu7g",
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false,
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
]
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
[
|
|
{
|
|
"id": "string",
|
|
"provider_id": "string",
|
|
"name": "string",
|
|
"upstream_url": "string",
|
|
"models": [
|
|
{
|
|
"id": "string",
|
|
"input_per_1k": "number",
|
|
"output_per_1k": "number",
|
|
"cached_input_per_1k": "number",
|
|
"cache_read_per_1k": "number",
|
|
"cache_creation_per_1k": "number"
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"type": "object",
|
|
"description": "Operator-typed values for catalog-declared extra headers. Keys are wire header names (e.g. `x-portkey-config`); values are the strings the proxy stamps on every upstream request to this provider. Catalog (AgentNetworkCatalogProvider.extra_headers) declares which keys are accepted; values not declared by the catalog are ignored at synth time. Empty / missing values mean no header stamped.\n",
|
|
"additionalProperties": "string",
|
|
"example": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
}
|
|
},
|
|
"identity_header_user_id": "string",
|
|
"identity_header_groups": "string",
|
|
"enabled": "boolean",
|
|
"skip_tls_verification": "boolean",
|
|
"metadata_disabled": "boolean",
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
]
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Create an Agent Network Provider {{ tag: 'POST' , label: '/api/agent-network/providers' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Connects a new Agent Network AI provider for the account.
|
|
|
|
The credential is checked against the vendor's model listing before the provider is stored, so a record the vendor will not accept is refused rather than saved. A rejected credential, a listing endpoint that does not resolve or answer, a vendor outage, and a timeout all block the write and return 422.
|
|
|
|
What that proves about the upstream URL is narrower than the URL itself. Only its host is used: the listing is requested over HTTPS at the path the catalog entry declares, so a configured scheme or path is neither used nor validated here. Where the catalog entry has a listing host of its own — Bedrock, whose listing comes from the control plane — even the host is only resolved, never contacted, so a public host that does not answer is still stored.
|
|
|
|
Only what cannot be checked at all is exempt and stored unverified: a catalog provider with no listing endpoint, one with no host to derive a listing from, an upstream resolving to a private address the management service will not dial, and a provider configured to skip TLS verification.
|
|
|
|
|
|
### Request-Body Parameters
|
|
|
|
<Properties><Property name="provider_id" type="string" required={true}>
|
|
|
|
Catalog identifier for the upstream AI provider (e.g. openai_api, anthropic_api, azure_openai_api, bedrock_api, vertex_ai_api, mistral_api, custom).
|
|
|
|
</Property>
|
|
<Property name="name" type="string" required={true}>
|
|
|
|
Display name for the provider.
|
|
|
|
</Property>
|
|
<Property name="upstream_url" type="string" required={true}>
|
|
|
|
Full upstream URL (with scheme) that NetBird forwards traffic to.
|
|
|
|
</Property>
|
|
<Property name="api_key" type="string" required={false}>
|
|
|
|
Upstream provider API key. Sealed at rest on the management server and never returned in responses. Required on create; optional on update (omit to keep the existing key).
|
|
|
|
</Property>
|
|
<Property name="models" type="object[]" required={false}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>Models exposed through this endpoint, with the operator's per-1k input/output prices. Empty means all catalog models are allowed at catalog prices.</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="id" type="string" required={true}>
|
|
|
|
Model identifier (e.g. "gpt-4o-mini").
|
|
|
|
</Property>
|
|
<Property name="input_per_1k" type="number" required={true}>
|
|
|
|
Cost per 1k input tokens, in USD.
|
|
|
|
</Property>
|
|
<Property name="output_per_1k" type="number" required={true}>
|
|
|
|
Cost per 1k output tokens, in USD.
|
|
|
|
</Property>
|
|
<Property name="cached_input_per_1k" type="number" required={false}>
|
|
|
|
OpenAI-shape cache rate — cost per 1k cached prompt tokens (a subset of input tokens), in USD. Omitted means inherit NetBird's default rate for this model when one exists; 0 means no discount (cached tokens bill at input_per_1k).
|
|
|
|
</Property>
|
|
<Property name="cache_read_per_1k" type="number" required={false}>
|
|
|
|
Anthropic-shape cache rate — cost per 1k cache-read tokens (additive to input tokens), in USD. Omitted means inherit NetBird's default rate for this model when one exists; 0 means cache reads bill at input_per_1k.
|
|
|
|
</Property>
|
|
<Property name="cache_creation_per_1k" type="number" required={false}>
|
|
|
|
Anthropic-shape cache rate — cost per 1k cache-creation tokens (additive to input tokens), in USD. Omitted means inherit NetBird's default rate for this model when one exists; 0 means cache writes bill at input_per_1k.
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
<Property name="extra_values" type="object" required={false}>
|
|
|
|
Operator-typed values for catalog-declared extra headers (see AgentNetworkProvider.extra_values). The request's map replaces the stored values; empty strings drop the corresponding key.
|
|
|
|
|
|
</Property>
|
|
<Property name="identity_header_user_id" type="string" required={false}>
|
|
|
|
Wire header name for the caller's display identity. See AgentNetworkProvider.identity_header_user_id. Empty or omitted disables stamping for this dimension.
|
|
|
|
|
|
</Property>
|
|
<Property name="identity_header_groups" type="string" required={false}>
|
|
|
|
Wire header name for the caller's groups CSV. See AgentNetworkProvider.identity_header_groups. Same semantics as `identity_header_user_id`.
|
|
|
|
|
|
</Property>
|
|
<Property name="enabled" type="boolean" required={false}>
|
|
|
|
Whether the provider is enabled. Defaults to true on create.
|
|
|
|
</Property>
|
|
<Property name="skip_tls_verification" type="boolean" required={false}>
|
|
|
|
Skip upstream TLS certificate verification when the proxy dials this provider's URL. For self-hosted / internal gateways behind a private or self-signed certificate. Defaults to false.
|
|
|
|
</Property>
|
|
<Property name="metadata_disabled" type="boolean" required={false}>
|
|
|
|
Disable identity metadata injection (the caller's user + authorizing group) for this provider. Defaults to false (metadata is injected).
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="POST" label="/api/agent-network/providers">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X POST https://api.netbird.io/api/agent-network/providers \
|
|
-H 'Accept: application/json' \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Authorization: Token <TOKEN>' \
|
|
--data-raw '{
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"api_key": "sk-...",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false
|
|
}'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
let data = JSON.stringify({
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"api_key": "sk-...",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false
|
|
});
|
|
let config = {
|
|
method: 'post',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/providers',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
},
|
|
data : data
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/providers"
|
|
payload = json.dumps({
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"api_key": "sk-...",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false
|
|
})
|
|
headers = {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("POST", url, headers=headers, data=payload)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/providers"
|
|
method := "POST"
|
|
|
|
payload := strings.NewReader(`{
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"api_key": "sk-...",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false
|
|
}`)
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, payload)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Content-Type", "application/json")
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/providers")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Post.new(url)
|
|
request["Content-Type"] = "application/json"
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
request.body = JSON.dump({
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"api_key": "sk-...",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false
|
|
})
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
MediaType mediaType = MediaType.parse("application/json");
|
|
RequestBody body = RequestBody.create(mediaType, '{
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"api_key": "sk-...",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false
|
|
}');
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/providers")
|
|
.method("POST", body)
|
|
.addHeader("Content-Type", "application/json")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/providers',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'POST',
|
|
CURLOPT_POSTFIELDS => '{
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"api_key": "sk-...",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false
|
|
}',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Content-Type: application/json',
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"id": "ainp_d1m3kebd9pcs0c1pnu7g",
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false,
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"id": "string",
|
|
"provider_id": "string",
|
|
"name": "string",
|
|
"upstream_url": "string",
|
|
"models": [
|
|
{
|
|
"id": "string",
|
|
"input_per_1k": "number",
|
|
"output_per_1k": "number",
|
|
"cached_input_per_1k": "number",
|
|
"cache_read_per_1k": "number",
|
|
"cache_creation_per_1k": "number"
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"type": "object",
|
|
"description": "Operator-typed values for catalog-declared extra headers. Keys are wire header names (e.g. `x-portkey-config`); values are the strings the proxy stamps on every upstream request to this provider. Catalog (AgentNetworkCatalogProvider.extra_headers) declares which keys are accepted; values not declared by the catalog are ignored at synth time. Empty / missing values mean no header stamped.\n",
|
|
"additionalProperties": "string",
|
|
"example": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
}
|
|
},
|
|
"identity_header_user_id": "string",
|
|
"identity_header_groups": "string",
|
|
"enabled": "boolean",
|
|
"skip_tls_verification": "boolean",
|
|
"metadata_disabled": "boolean",
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Retrieve an Agent Network Provider {{ tag: 'GET' , label: '/api/agent-network/providers/{providerId}' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Get information about a specific Agent Network AI provider.
|
|
|
|
### Path Parameters
|
|
<Properties>
|
|
|
|
<Property name="providerId" type="string" required={true}>
|
|
The unique identifier of an Agent Network provider
|
|
</Property>
|
|
</Properties>
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="GET" label="/api/agent-network/providers/{providerId}">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X GET https://api.netbird.io/api/agent-network/providers/{providerId} \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'get',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/providers/{providerId}',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/providers/{providerId}"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("GET", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/providers/{providerId}"
|
|
method := "GET"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/providers/{providerId}")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Get.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/providers/{providerId}")
|
|
.method("GET")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/providers/{providerId}',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'GET',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"id": "ainp_d1m3kebd9pcs0c1pnu7g",
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false,
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"id": "string",
|
|
"provider_id": "string",
|
|
"name": "string",
|
|
"upstream_url": "string",
|
|
"models": [
|
|
{
|
|
"id": "string",
|
|
"input_per_1k": "number",
|
|
"output_per_1k": "number",
|
|
"cached_input_per_1k": "number",
|
|
"cache_read_per_1k": "number",
|
|
"cache_creation_per_1k": "number"
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"type": "object",
|
|
"description": "Operator-typed values for catalog-declared extra headers. Keys are wire header names (e.g. `x-portkey-config`); values are the strings the proxy stamps on every upstream request to this provider. Catalog (AgentNetworkCatalogProvider.extra_headers) declares which keys are accepted; values not declared by the catalog are ignored at synth time. Empty / missing values mean no header stamped.\n",
|
|
"additionalProperties": "string",
|
|
"example": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
}
|
|
},
|
|
"identity_header_user_id": "string",
|
|
"identity_header_groups": "string",
|
|
"enabled": "boolean",
|
|
"skip_tls_verification": "boolean",
|
|
"metadata_disabled": "boolean",
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Update an Agent Network Provider {{ tag: 'PUT' , label: '/api/agent-network/providers/{providerId}' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Update an existing Agent Network AI provider.
|
|
|
|
When the upstream URL, the API key or the catalog provider changes, the record is checked against the vendor before the change is stored, and a refusal returns 422 without replacing what was there. Switching TLS verification back on is the fourth trigger: a provider exempt from the check was stored unverified, so the edit that ends the exemption is the first opportunity to check it. Where one of the four does fire, an update that omits the API key is checked against the stored one. Edits touching none of them — a rename, model rows, price edits — are stored without a check, as are the cases the create description lists as unverifiable.
|
|
|
|
|
|
### Path Parameters
|
|
<Properties>
|
|
|
|
<Property name="providerId" type="string" required={true}>
|
|
The unique identifier of an Agent Network provider
|
|
</Property>
|
|
</Properties>
|
|
|
|
### Request-Body Parameters
|
|
|
|
<Properties><Property name="provider_id" type="string" required={true}>
|
|
|
|
Catalog identifier for the upstream AI provider (e.g. openai_api, anthropic_api, azure_openai_api, bedrock_api, vertex_ai_api, mistral_api, custom).
|
|
|
|
</Property>
|
|
<Property name="name" type="string" required={true}>
|
|
|
|
Display name for the provider.
|
|
|
|
</Property>
|
|
<Property name="upstream_url" type="string" required={true}>
|
|
|
|
Full upstream URL (with scheme) that NetBird forwards traffic to.
|
|
|
|
</Property>
|
|
<Property name="api_key" type="string" required={false}>
|
|
|
|
Upstream provider API key. Sealed at rest on the management server and never returned in responses. Required on create; optional on update (omit to keep the existing key).
|
|
|
|
</Property>
|
|
<Property name="models" type="object[]" required={false}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>Models exposed through this endpoint, with the operator's per-1k input/output prices. Empty means all catalog models are allowed at catalog prices.</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="id" type="string" required={true}>
|
|
|
|
Model identifier (e.g. "gpt-4o-mini").
|
|
|
|
</Property>
|
|
<Property name="input_per_1k" type="number" required={true}>
|
|
|
|
Cost per 1k input tokens, in USD.
|
|
|
|
</Property>
|
|
<Property name="output_per_1k" type="number" required={true}>
|
|
|
|
Cost per 1k output tokens, in USD.
|
|
|
|
</Property>
|
|
<Property name="cached_input_per_1k" type="number" required={false}>
|
|
|
|
OpenAI-shape cache rate — cost per 1k cached prompt tokens (a subset of input tokens), in USD. Omitted means inherit NetBird's default rate for this model when one exists; 0 means no discount (cached tokens bill at input_per_1k).
|
|
|
|
</Property>
|
|
<Property name="cache_read_per_1k" type="number" required={false}>
|
|
|
|
Anthropic-shape cache rate — cost per 1k cache-read tokens (additive to input tokens), in USD. Omitted means inherit NetBird's default rate for this model when one exists; 0 means cache reads bill at input_per_1k.
|
|
|
|
</Property>
|
|
<Property name="cache_creation_per_1k" type="number" required={false}>
|
|
|
|
Anthropic-shape cache rate — cost per 1k cache-creation tokens (additive to input tokens), in USD. Omitted means inherit NetBird's default rate for this model when one exists; 0 means cache writes bill at input_per_1k.
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
<Property name="extra_values" type="object" required={false}>
|
|
|
|
Operator-typed values for catalog-declared extra headers (see AgentNetworkProvider.extra_values). The request's map replaces the stored values; empty strings drop the corresponding key.
|
|
|
|
|
|
</Property>
|
|
<Property name="identity_header_user_id" type="string" required={false}>
|
|
|
|
Wire header name for the caller's display identity. See AgentNetworkProvider.identity_header_user_id. Empty or omitted disables stamping for this dimension.
|
|
|
|
|
|
</Property>
|
|
<Property name="identity_header_groups" type="string" required={false}>
|
|
|
|
Wire header name for the caller's groups CSV. See AgentNetworkProvider.identity_header_groups. Same semantics as `identity_header_user_id`.
|
|
|
|
|
|
</Property>
|
|
<Property name="enabled" type="boolean" required={false}>
|
|
|
|
Whether the provider is enabled. Defaults to true on create.
|
|
|
|
</Property>
|
|
<Property name="skip_tls_verification" type="boolean" required={false}>
|
|
|
|
Skip upstream TLS certificate verification when the proxy dials this provider's URL. For self-hosted / internal gateways behind a private or self-signed certificate. Defaults to false.
|
|
|
|
</Property>
|
|
<Property name="metadata_disabled" type="boolean" required={false}>
|
|
|
|
Disable identity metadata injection (the caller's user + authorizing group) for this provider. Defaults to false (metadata is injected).
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="PUT" label="/api/agent-network/providers/{providerId}">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X PUT https://api.netbird.io/api/agent-network/providers/{providerId} \
|
|
-H 'Accept: application/json' \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Authorization: Token <TOKEN>' \
|
|
--data-raw '{
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"api_key": "sk-...",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false
|
|
}'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
let data = JSON.stringify({
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"api_key": "sk-...",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false
|
|
});
|
|
let config = {
|
|
method: 'put',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/providers/{providerId}',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
},
|
|
data : data
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/providers/{providerId}"
|
|
payload = json.dumps({
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"api_key": "sk-...",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false
|
|
})
|
|
headers = {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("PUT", url, headers=headers, data=payload)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/providers/{providerId}"
|
|
method := "PUT"
|
|
|
|
payload := strings.NewReader(`{
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"api_key": "sk-...",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false
|
|
}`)
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, payload)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Content-Type", "application/json")
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/providers/{providerId}")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Put.new(url)
|
|
request["Content-Type"] = "application/json"
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
request.body = JSON.dump({
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"api_key": "sk-...",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false
|
|
})
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
MediaType mediaType = MediaType.parse("application/json");
|
|
RequestBody body = RequestBody.create(mediaType, '{
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"api_key": "sk-...",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false
|
|
}');
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/providers/{providerId}")
|
|
.method("PUT", body)
|
|
.addHeader("Content-Type", "application/json")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/providers/{providerId}',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'PUT',
|
|
CURLOPT_POSTFIELDS => '{
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"api_key": "sk-...",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false
|
|
}',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Content-Type: application/json',
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"id": "ainp_d1m3kebd9pcs0c1pnu7g",
|
|
"provider_id": "openai_api",
|
|
"name": "OpenAI API",
|
|
"upstream_url": "https://api.openai.com",
|
|
"models": [
|
|
{
|
|
"id": "gpt-4o-mini",
|
|
"input_per_1k": 0.00015,
|
|
"output_per_1k": 0.0006,
|
|
"cached_input_per_1k": 0.000075,
|
|
"cache_read_per_1k": 0.0003,
|
|
"cache_creation_per_1k": 0.00375
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
},
|
|
"identity_header_user_id": "x-bf-dim-netbird_user_id",
|
|
"identity_header_groups": "x-bf-dim-netbird_groups",
|
|
"enabled": true,
|
|
"skip_tls_verification": false,
|
|
"metadata_disabled": false,
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"id": "string",
|
|
"provider_id": "string",
|
|
"name": "string",
|
|
"upstream_url": "string",
|
|
"models": [
|
|
{
|
|
"id": "string",
|
|
"input_per_1k": "number",
|
|
"output_per_1k": "number",
|
|
"cached_input_per_1k": "number",
|
|
"cache_read_per_1k": "number",
|
|
"cache_creation_per_1k": "number"
|
|
}
|
|
],
|
|
"extra_values": {
|
|
"type": "object",
|
|
"description": "Operator-typed values for catalog-declared extra headers. Keys are wire header names (e.g. `x-portkey-config`); values are the strings the proxy stamps on every upstream request to this provider. Catalog (AgentNetworkCatalogProvider.extra_headers) declares which keys are accepted; values not declared by the catalog are ignored at synth time. Empty / missing values mean no header stamped.\n",
|
|
"additionalProperties": "string",
|
|
"example": {
|
|
"x-portkey-config": "pc-prod-3f2a"
|
|
}
|
|
},
|
|
"identity_header_user_id": "string",
|
|
"identity_header_groups": "string",
|
|
"enabled": "boolean",
|
|
"skip_tls_verification": "boolean",
|
|
"metadata_disabled": "boolean",
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Delete an Agent Network Provider {{ tag: 'DELETE' , label: '/api/agent-network/providers/{providerId}' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Delete an existing Agent Network AI provider.
|
|
|
|
### Path Parameters
|
|
<Properties>
|
|
|
|
<Property name="providerId" type="string" required={true}>
|
|
The unique identifier of an Agent Network provider
|
|
</Property>
|
|
</Properties>
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="DELETE" label="/api/agent-network/providers/{providerId}">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X DELETE https://api.netbird.io/api/agent-network/providers/{providerId} \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'delete',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/providers/{providerId}',
|
|
headers: {
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/providers/{providerId}"
|
|
|
|
headers = {
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("DELETE", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/providers/{providerId}"
|
|
method := "DELETE"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/providers/{providerId}")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Delete.new(url)
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/providers/{providerId}")
|
|
.method("DELETE")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/providers/{providerId}',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'DELETE',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## List all Agent Network Policies {{ tag: 'GET' , label: '/api/agent-network/policies' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Returns a list of all Agent Network policies for the account.
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="GET" label="/api/agent-network/policies">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X GET https://api.netbird.io/api/agent-network/policies \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'get',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/policies',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/policies"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("GET", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/policies"
|
|
method := "GET"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/policies")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Get.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/policies")
|
|
.method("GET")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/policies',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'GET',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
[
|
|
{
|
|
"id": "ainpol_d1m3kebd9pcs0c1pnu7g",
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
},
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
]
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
[
|
|
{
|
|
"id": "string",
|
|
"name": "string",
|
|
"description": "string",
|
|
"enabled": "boolean",
|
|
"source_groups": [
|
|
"string"
|
|
],
|
|
"destination_provider_ids": [
|
|
"string"
|
|
],
|
|
"guardrail_ids": [
|
|
"string"
|
|
],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": "boolean",
|
|
"group_cap": "integer",
|
|
"user_cap": "integer",
|
|
"window_seconds": "integer"
|
|
},
|
|
"budget_limit": {
|
|
"enabled": "boolean",
|
|
"group_cap_usd": "number",
|
|
"user_cap_usd": "number",
|
|
"window_seconds": "integer"
|
|
}
|
|
},
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
]
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Create an Agent Network Policy {{ tag: 'POST' , label: '/api/agent-network/policies' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Creates a new Agent Network policy binding source groups to destination providers, optionally enforced by guardrails.
|
|
|
|
### Request-Body Parameters
|
|
|
|
<Properties><Property name="name" type="string" required={true}>
|
|
|
|
Display name for the policy.
|
|
|
|
</Property>
|
|
<Property name="description" type="string" required={false}>
|
|
|
|
Optional human-readable description.
|
|
|
|
</Property>
|
|
<Property name="enabled" type="boolean" required={false}>
|
|
|
|
Whether the policy is enabled. Defaults to true on create.
|
|
|
|
</Property>
|
|
<Property name="source_groups" type="string[]" required={true}>
|
|
|
|
NetBird group ids whose members are allowed to call the destination providers.
|
|
|
|
</Property>
|
|
<Property name="destination_provider_ids" type="string[]" required={true}>
|
|
|
|
Agent Network provider ids the source groups can reach.
|
|
|
|
</Property>
|
|
<Property name="guardrail_ids" type="string[]" required={false}>
|
|
|
|
Agent Network guardrail ids to attach to this policy.
|
|
|
|
</Property>
|
|
<Property name="limits" type="object" required={false}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>Token and budget caps attached directly to the policy. These compose with any guardrail-level checks.</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="token_limit" type="object" required={true}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>Per-policy token cap. `group_cap` is applied to each source group independently — every group in the policy's `source_groups` gets its own bucket of this size. `user_cap` is applied independently to each individual user. Caps reset to zero at the start of each window.</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="enabled" type="boolean" required={true}>
|
|
|
|
|
|
|
|
</Property>
|
|
<Property name="group_cap" type="integer" required={true} min={0}>
|
|
|
|
Tokens allowed per source group within the window (each group has its own bucket of this size). 0 means uncapped.
|
|
|
|
</Property>
|
|
<Property name="user_cap" type="integer" required={true} min={0}>
|
|
|
|
Tokens allowed per individual user within the window. 0 means uncapped.
|
|
|
|
</Property>
|
|
<Property name="window_seconds" type="integer" required={true} min={60}>
|
|
|
|
Reset frequency in seconds. The cap counter resets to zero at the start of each window. Minimum 60 (one minute) when the limit is enabled.
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
<Property name="budget_limit" type="object" required={true}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>Per-policy USD spend cap. `group_cap_usd` is applied to each source group independently — every group in the policy's `source_groups` gets its own bucket of this size. `user_cap_usd` is applied independently to each individual user. Caps reset to zero at the start of each window.</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="enabled" type="boolean" required={true}>
|
|
|
|
|
|
|
|
</Property>
|
|
<Property name="group_cap_usd" type="number" required={true} min={0}>
|
|
|
|
USD allowed per source group within the window (each group has its own bucket of this size). 0 means uncapped.
|
|
|
|
</Property>
|
|
<Property name="user_cap_usd" type="number" required={true} min={0}>
|
|
|
|
USD allowed per individual user within the window. 0 means uncapped.
|
|
|
|
</Property>
|
|
<Property name="window_seconds" type="integer" required={true} min={60}>
|
|
|
|
Reset frequency in seconds. Caps reset at the start of each window. Minimum 60 (one minute) when the limit is enabled.
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="POST" label="/api/agent-network/policies">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X POST https://api.netbird.io/api/agent-network/policies \
|
|
-H 'Accept: application/json' \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Authorization: Token <TOKEN>' \
|
|
--data-raw '{
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
}'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
let data = JSON.stringify({
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
});
|
|
let config = {
|
|
method: 'post',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/policies',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
},
|
|
data : data
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/policies"
|
|
payload = json.dumps({
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
})
|
|
headers = {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("POST", url, headers=headers, data=payload)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/policies"
|
|
method := "POST"
|
|
|
|
payload := strings.NewReader(`{
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
}`)
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, payload)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Content-Type", "application/json")
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/policies")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Post.new(url)
|
|
request["Content-Type"] = "application/json"
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
request.body = JSON.dump({
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
})
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
MediaType mediaType = MediaType.parse("application/json");
|
|
RequestBody body = RequestBody.create(mediaType, '{
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
}');
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/policies")
|
|
.method("POST", body)
|
|
.addHeader("Content-Type", "application/json")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/policies',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'POST',
|
|
CURLOPT_POSTFIELDS => '{
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
}',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Content-Type: application/json',
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"id": "ainpol_d1m3kebd9pcs0c1pnu7g",
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
},
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"id": "string",
|
|
"name": "string",
|
|
"description": "string",
|
|
"enabled": "boolean",
|
|
"source_groups": [
|
|
"string"
|
|
],
|
|
"destination_provider_ids": [
|
|
"string"
|
|
],
|
|
"guardrail_ids": [
|
|
"string"
|
|
],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": "boolean",
|
|
"group_cap": "integer",
|
|
"user_cap": "integer",
|
|
"window_seconds": "integer"
|
|
},
|
|
"budget_limit": {
|
|
"enabled": "boolean",
|
|
"group_cap_usd": "number",
|
|
"user_cap_usd": "number",
|
|
"window_seconds": "integer"
|
|
}
|
|
},
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Retrieve an Agent Network Policy {{ tag: 'GET' , label: '/api/agent-network/policies/{policyId}' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Get information about a specific Agent Network policy.
|
|
|
|
### Path Parameters
|
|
<Properties>
|
|
|
|
<Property name="policyId" type="string" required={true}>
|
|
The unique identifier of an Agent Network policy
|
|
</Property>
|
|
</Properties>
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="GET" label="/api/agent-network/policies/{policyId}">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X GET https://api.netbird.io/api/agent-network/policies/{policyId} \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'get',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/policies/{policyId}',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/policies/{policyId}"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("GET", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/policies/{policyId}"
|
|
method := "GET"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/policies/{policyId}")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Get.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/policies/{policyId}")
|
|
.method("GET")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/policies/{policyId}',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'GET',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"id": "ainpol_d1m3kebd9pcs0c1pnu7g",
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
},
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"id": "string",
|
|
"name": "string",
|
|
"description": "string",
|
|
"enabled": "boolean",
|
|
"source_groups": [
|
|
"string"
|
|
],
|
|
"destination_provider_ids": [
|
|
"string"
|
|
],
|
|
"guardrail_ids": [
|
|
"string"
|
|
],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": "boolean",
|
|
"group_cap": "integer",
|
|
"user_cap": "integer",
|
|
"window_seconds": "integer"
|
|
},
|
|
"budget_limit": {
|
|
"enabled": "boolean",
|
|
"group_cap_usd": "number",
|
|
"user_cap_usd": "number",
|
|
"window_seconds": "integer"
|
|
}
|
|
},
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Update an Agent Network Policy {{ tag: 'PUT' , label: '/api/agent-network/policies/{policyId}' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Update an existing Agent Network policy.
|
|
|
|
### Path Parameters
|
|
<Properties>
|
|
|
|
<Property name="policyId" type="string" required={true}>
|
|
The unique identifier of an Agent Network policy
|
|
</Property>
|
|
</Properties>
|
|
|
|
### Request-Body Parameters
|
|
|
|
<Properties><Property name="name" type="string" required={true}>
|
|
|
|
Display name for the policy.
|
|
|
|
</Property>
|
|
<Property name="description" type="string" required={false}>
|
|
|
|
Optional human-readable description.
|
|
|
|
</Property>
|
|
<Property name="enabled" type="boolean" required={false}>
|
|
|
|
Whether the policy is enabled. Defaults to true on create.
|
|
|
|
</Property>
|
|
<Property name="source_groups" type="string[]" required={true}>
|
|
|
|
NetBird group ids whose members are allowed to call the destination providers.
|
|
|
|
</Property>
|
|
<Property name="destination_provider_ids" type="string[]" required={true}>
|
|
|
|
Agent Network provider ids the source groups can reach.
|
|
|
|
</Property>
|
|
<Property name="guardrail_ids" type="string[]" required={false}>
|
|
|
|
Agent Network guardrail ids to attach to this policy.
|
|
|
|
</Property>
|
|
<Property name="limits" type="object" required={false}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>Token and budget caps attached directly to the policy. These compose with any guardrail-level checks.</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="token_limit" type="object" required={true}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>Per-policy token cap. `group_cap` is applied to each source group independently — every group in the policy's `source_groups` gets its own bucket of this size. `user_cap` is applied independently to each individual user. Caps reset to zero at the start of each window.</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="enabled" type="boolean" required={true}>
|
|
|
|
|
|
|
|
</Property>
|
|
<Property name="group_cap" type="integer" required={true} min={0}>
|
|
|
|
Tokens allowed per source group within the window (each group has its own bucket of this size). 0 means uncapped.
|
|
|
|
</Property>
|
|
<Property name="user_cap" type="integer" required={true} min={0}>
|
|
|
|
Tokens allowed per individual user within the window. 0 means uncapped.
|
|
|
|
</Property>
|
|
<Property name="window_seconds" type="integer" required={true} min={60}>
|
|
|
|
Reset frequency in seconds. The cap counter resets to zero at the start of each window. Minimum 60 (one minute) when the limit is enabled.
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
<Property name="budget_limit" type="object" required={true}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>Per-policy USD spend cap. `group_cap_usd` is applied to each source group independently — every group in the policy's `source_groups` gets its own bucket of this size. `user_cap_usd` is applied independently to each individual user. Caps reset to zero at the start of each window.</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="enabled" type="boolean" required={true}>
|
|
|
|
|
|
|
|
</Property>
|
|
<Property name="group_cap_usd" type="number" required={true} min={0}>
|
|
|
|
USD allowed per source group within the window (each group has its own bucket of this size). 0 means uncapped.
|
|
|
|
</Property>
|
|
<Property name="user_cap_usd" type="number" required={true} min={0}>
|
|
|
|
USD allowed per individual user within the window. 0 means uncapped.
|
|
|
|
</Property>
|
|
<Property name="window_seconds" type="integer" required={true} min={60}>
|
|
|
|
Reset frequency in seconds. Caps reset at the start of each window. Minimum 60 (one minute) when the limit is enabled.
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="PUT" label="/api/agent-network/policies/{policyId}">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X PUT https://api.netbird.io/api/agent-network/policies/{policyId} \
|
|
-H 'Accept: application/json' \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Authorization: Token <TOKEN>' \
|
|
--data-raw '{
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
}'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
let data = JSON.stringify({
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
});
|
|
let config = {
|
|
method: 'put',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/policies/{policyId}',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
},
|
|
data : data
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/policies/{policyId}"
|
|
payload = json.dumps({
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
})
|
|
headers = {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("PUT", url, headers=headers, data=payload)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/policies/{policyId}"
|
|
method := "PUT"
|
|
|
|
payload := strings.NewReader(`{
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
}`)
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, payload)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Content-Type", "application/json")
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/policies/{policyId}")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Put.new(url)
|
|
request["Content-Type"] = "application/json"
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
request.body = JSON.dump({
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
})
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
MediaType mediaType = MediaType.parse("application/json");
|
|
RequestBody body = RequestBody.create(mediaType, '{
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
}');
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/policies/{policyId}")
|
|
.method("PUT", body)
|
|
.addHeader("Content-Type", "application/json")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/policies/{policyId}',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'PUT',
|
|
CURLOPT_POSTFIELDS => '{
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
}
|
|
}',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Content-Type: application/json',
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"id": "ainpol_d1m3kebd9pcs0c1pnu7g",
|
|
"name": "Engineering → OpenAI",
|
|
"description": "Engineers can call OpenAI under production guardrails.",
|
|
"enabled": true,
|
|
"source_groups": [
|
|
"ch8vp3o6lnna9hg0sd8g"
|
|
],
|
|
"destination_provider_ids": [
|
|
"ainp_d1m3kebd9pcs0c1pnu7g"
|
|
],
|
|
"guardrail_ids": [],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": true,
|
|
"group_cap": 10000000,
|
|
"user_cap": 1000000,
|
|
"window_seconds": 2592000
|
|
},
|
|
"budget_limit": {
|
|
"enabled": true,
|
|
"group_cap_usd": 1000,
|
|
"user_cap_usd": 100,
|
|
"window_seconds": 2592000
|
|
}
|
|
},
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"id": "string",
|
|
"name": "string",
|
|
"description": "string",
|
|
"enabled": "boolean",
|
|
"source_groups": [
|
|
"string"
|
|
],
|
|
"destination_provider_ids": [
|
|
"string"
|
|
],
|
|
"guardrail_ids": [
|
|
"string"
|
|
],
|
|
"limits": {
|
|
"token_limit": {
|
|
"enabled": "boolean",
|
|
"group_cap": "integer",
|
|
"user_cap": "integer",
|
|
"window_seconds": "integer"
|
|
},
|
|
"budget_limit": {
|
|
"enabled": "boolean",
|
|
"group_cap_usd": "number",
|
|
"user_cap_usd": "number",
|
|
"window_seconds": "integer"
|
|
}
|
|
},
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Delete an Agent Network Policy {{ tag: 'DELETE' , label: '/api/agent-network/policies/{policyId}' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Delete an existing Agent Network policy.
|
|
|
|
### Path Parameters
|
|
<Properties>
|
|
|
|
<Property name="policyId" type="string" required={true}>
|
|
The unique identifier of an Agent Network policy
|
|
</Property>
|
|
</Properties>
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="DELETE" label="/api/agent-network/policies/{policyId}">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X DELETE https://api.netbird.io/api/agent-network/policies/{policyId} \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'delete',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/policies/{policyId}',
|
|
headers: {
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/policies/{policyId}"
|
|
|
|
headers = {
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("DELETE", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/policies/{policyId}"
|
|
method := "DELETE"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/policies/{policyId}")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Delete.new(url)
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/policies/{policyId}")
|
|
.method("DELETE")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/policies/{policyId}',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'DELETE',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## List all Agent Network Guardrails {{ tag: 'GET' , label: '/api/agent-network/guardrails' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Returns a list of all Agent Network guardrails for the account.
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="GET" label="/api/agent-network/guardrails">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X GET https://api.netbird.io/api/agent-network/guardrails \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'get',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/guardrails',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/guardrails"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("GET", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/guardrails"
|
|
method := "GET"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/guardrails")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Get.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/guardrails")
|
|
.method("GET")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/guardrails',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'GET',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
[
|
|
{
|
|
"id": "ainguard_d1m3kebd9pcs0c1pnu7g",
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
},
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
]
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
[
|
|
{
|
|
"id": "string",
|
|
"name": "string",
|
|
"description": "string",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": "boolean",
|
|
"models": [
|
|
"string"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": "boolean",
|
|
"redact_pii": "boolean"
|
|
}
|
|
},
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
]
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Create an Agent Network Guardrail {{ tag: 'POST' , label: '/api/agent-network/guardrails' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Creates a new Agent Network guardrail that can be attached to one or more policies.
|
|
|
|
### Request-Body Parameters
|
|
|
|
<Properties><Property name="name" type="string" required={true}>
|
|
|
|
Display name for the guardrail.
|
|
|
|
</Property>
|
|
<Property name="description" type="string" required={false}>
|
|
|
|
Optional human-readable description.
|
|
|
|
</Property>
|
|
<Property name="checks" type="object" required={true}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>Guardrail check parameters. Each entry has an `enabled` flag plus per-check configuration; disabled entries are inert.</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="model_allowlist" type="object" required={true}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>More Information</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="enabled" type="boolean" required={true}>
|
|
|
|
|
|
|
|
</Property>
|
|
<Property name="models" type="string[]" required={true}>
|
|
|
|
Allowed catalog model ids. Requests for any other model are denied.
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
<Property name="prompt_capture" type="object" required={true}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>More Information</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="enabled" type="boolean" required={true}>
|
|
|
|
|
|
|
|
</Property>
|
|
<Property name="redact_pii" type="boolean" required={true}>
|
|
|
|
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="POST" label="/api/agent-network/guardrails">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X POST https://api.netbird.io/api/agent-network/guardrails \
|
|
-H 'Accept: application/json' \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Authorization: Token <TOKEN>' \
|
|
--data-raw '{
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
}
|
|
}'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
let data = JSON.stringify({
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
}
|
|
});
|
|
let config = {
|
|
method: 'post',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/guardrails',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
},
|
|
data : data
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/guardrails"
|
|
payload = json.dumps({
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
}
|
|
})
|
|
headers = {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("POST", url, headers=headers, data=payload)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/guardrails"
|
|
method := "POST"
|
|
|
|
payload := strings.NewReader(`{
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
}
|
|
}`)
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, payload)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Content-Type", "application/json")
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/guardrails")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Post.new(url)
|
|
request["Content-Type"] = "application/json"
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
request.body = JSON.dump({
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
}
|
|
})
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
MediaType mediaType = MediaType.parse("application/json");
|
|
RequestBody body = RequestBody.create(mediaType, '{
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
}
|
|
}');
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/guardrails")
|
|
.method("POST", body)
|
|
.addHeader("Content-Type", "application/json")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/guardrails',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'POST',
|
|
CURLOPT_POSTFIELDS => '{
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
}
|
|
}',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Content-Type: application/json',
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"id": "ainguard_d1m3kebd9pcs0c1pnu7g",
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
},
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"id": "string",
|
|
"name": "string",
|
|
"description": "string",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": "boolean",
|
|
"models": [
|
|
"string"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": "boolean",
|
|
"redact_pii": "boolean"
|
|
}
|
|
},
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Retrieve an Agent Network Guardrail {{ tag: 'GET' , label: '/api/agent-network/guardrails/{guardrailId}' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Get information about a specific Agent Network guardrail.
|
|
|
|
### Path Parameters
|
|
<Properties>
|
|
|
|
<Property name="guardrailId" type="string" required={true}>
|
|
The unique identifier of an Agent Network guardrail
|
|
</Property>
|
|
</Properties>
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="GET" label="/api/agent-network/guardrails/{guardrailId}">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X GET https://api.netbird.io/api/agent-network/guardrails/{guardrailId} \
|
|
-H 'Accept: application/json' \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'get',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/guardrails/{guardrailId}',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/guardrails/{guardrailId}"
|
|
|
|
headers = {
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("GET", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/guardrails/{guardrailId}"
|
|
method := "GET"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/guardrails/{guardrailId}")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Get.new(url)
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/guardrails/{guardrailId}")
|
|
.method("GET")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/guardrails/{guardrailId}',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'GET',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"id": "ainguard_d1m3kebd9pcs0c1pnu7g",
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
},
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"id": "string",
|
|
"name": "string",
|
|
"description": "string",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": "boolean",
|
|
"models": [
|
|
"string"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": "boolean",
|
|
"redact_pii": "boolean"
|
|
}
|
|
},
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Update an Agent Network Guardrail {{ tag: 'PUT' , label: '/api/agent-network/guardrails/{guardrailId}' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Update an existing Agent Network guardrail.
|
|
|
|
### Path Parameters
|
|
<Properties>
|
|
|
|
<Property name="guardrailId" type="string" required={true}>
|
|
The unique identifier of an Agent Network guardrail
|
|
</Property>
|
|
</Properties>
|
|
|
|
### Request-Body Parameters
|
|
|
|
<Properties><Property name="name" type="string" required={true}>
|
|
|
|
Display name for the guardrail.
|
|
|
|
</Property>
|
|
<Property name="description" type="string" required={false}>
|
|
|
|
Optional human-readable description.
|
|
|
|
</Property>
|
|
<Property name="checks" type="object" required={true}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>Guardrail check parameters. Each entry has an `enabled` flag plus per-check configuration; disabled entries are inert.</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="model_allowlist" type="object" required={true}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>More Information</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="enabled" type="boolean" required={true}>
|
|
|
|
|
|
|
|
</Property>
|
|
<Property name="models" type="string[]" required={true}>
|
|
|
|
Allowed catalog model ids. Requests for any other model are denied.
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
<Property name="prompt_capture" type="object" required={true}>
|
|
|
|
<details className="custom-details" open>
|
|
<summary>More Information</summary>
|
|
<Properties>
|
|
|
|
<Properties><Property name="enabled" type="boolean" required={true}>
|
|
|
|
|
|
|
|
</Property>
|
|
<Property name="redact_pii" type="boolean" required={true}>
|
|
|
|
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
</Properties>
|
|
</details>
|
|
|
|
</Property>
|
|
</Properties>
|
|
|
|
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="PUT" label="/api/agent-network/guardrails/{guardrailId}">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X PUT https://api.netbird.io/api/agent-network/guardrails/{guardrailId} \
|
|
-H 'Accept: application/json' \
|
|
-H 'Content-Type: application/json' \
|
|
-H 'Authorization: Token <TOKEN>' \
|
|
--data-raw '{
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
}
|
|
}'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
let data = JSON.stringify({
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
}
|
|
});
|
|
let config = {
|
|
method: 'put',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/guardrails/{guardrailId}',
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Content-Type': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
},
|
|
data : data
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/guardrails/{guardrailId}"
|
|
payload = json.dumps({
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
}
|
|
})
|
|
headers = {
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json',
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("PUT", url, headers=headers, data=payload)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/guardrails/{guardrailId}"
|
|
method := "PUT"
|
|
|
|
payload := strings.NewReader(`{
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
}
|
|
}`)
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, payload)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Content-Type", "application/json")
|
|
req.Header.Add("Accept", "application/json")
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/guardrails/{guardrailId}")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Put.new(url)
|
|
request["Content-Type"] = "application/json"
|
|
request["Accept"] = "application/json"
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
request.body = JSON.dump({
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
}
|
|
})
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
MediaType mediaType = MediaType.parse("application/json");
|
|
RequestBody body = RequestBody.create(mediaType, '{
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
}
|
|
}');
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/guardrails/{guardrailId}")
|
|
.method("PUT", body)
|
|
.addHeader("Content-Type", "application/json")
|
|
.addHeader("Accept", "application/json")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/guardrails/{guardrailId}',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'PUT',
|
|
CURLOPT_POSTFIELDS => '{
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
}
|
|
}',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Content-Type: application/json',
|
|
'Accept: application/json',
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
<CodeGroup title="Response">
|
|
```json {{ title: 'Example' }}
|
|
{
|
|
"id": "ainguard_d1m3kebd9pcs0c1pnu7g",
|
|
"name": "Strict — Production",
|
|
"description": "Tight model allowlist, PII redaction, hard monthly budget.",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": true,
|
|
"models": [
|
|
"gpt-4o-mini",
|
|
"claude-haiku-4-5"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": true,
|
|
"redact_pii": true
|
|
}
|
|
},
|
|
"created_at": "2026-04-26T10:30:00Z",
|
|
"updated_at": "2026-04-26T10:30:00Z"
|
|
}
|
|
```
|
|
```json {{ title: 'Schema' }}
|
|
{
|
|
"id": "string",
|
|
"name": "string",
|
|
"description": "string",
|
|
"checks": {
|
|
"model_allowlist": {
|
|
"enabled": "boolean",
|
|
"models": [
|
|
"string"
|
|
]
|
|
},
|
|
"prompt_capture": {
|
|
"enabled": "boolean",
|
|
"redact_pii": "boolean"
|
|
}
|
|
},
|
|
"created_at": "string",
|
|
"updated_at": "string"
|
|
}
|
|
```
|
|
</CodeGroup>
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|
|
|
|
|
|
## Delete an Agent Network Guardrail {{ tag: 'DELETE' , label: '/api/agent-network/guardrails/{guardrailId}' }}
|
|
|
|
<Row>
|
|
<Col>
|
|
Delete an existing Agent Network guardrail.
|
|
|
|
### Path Parameters
|
|
<Properties>
|
|
|
|
<Property name="guardrailId" type="string" required={true}>
|
|
The unique identifier of an Agent Network guardrail
|
|
</Property>
|
|
</Properties>
|
|
</Col>
|
|
|
|
<Col sticky>
|
|
<CodeGroup title="Request" tag="DELETE" label="/api/agent-network/guardrails/{guardrailId}">
|
|
```bash {{ title: 'cURL' }}
|
|
curl -X DELETE https://api.netbird.io/api/agent-network/guardrails/{guardrailId} \
|
|
-H 'Authorization: Token <TOKEN>'
|
|
```
|
|
|
|
```js
|
|
const axios = require('axios');
|
|
|
|
let config = {
|
|
method: 'delete',
|
|
maxBodyLength: Infinity,
|
|
url: '/api/agent-network/guardrails/{guardrailId}',
|
|
headers: {
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
};
|
|
|
|
axios(config)
|
|
.then((response) => {
|
|
console.log(JSON.stringify(response.data));
|
|
})
|
|
.catch((error) => {
|
|
console.log(error);
|
|
});
|
|
```
|
|
|
|
```python
|
|
import requests
|
|
import json
|
|
|
|
url = "https://api.netbird.io/api/agent-network/guardrails/{guardrailId}"
|
|
|
|
headers = {
|
|
'Authorization': 'Token <TOKEN>'
|
|
}
|
|
|
|
response = requests.request("DELETE", url, headers=headers)
|
|
|
|
print(response.text)
|
|
```
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"net/http"
|
|
"io/ioutil"
|
|
)
|
|
|
|
func main() {
|
|
|
|
url := "https://api.netbird.io/api/agent-network/guardrails/{guardrailId}"
|
|
method := "DELETE"
|
|
|
|
client := &http.Client {
|
|
}
|
|
req, err := http.NewRequest(method, url, nil)
|
|
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
|
|
req.Header.Add("Authorization", "Token <TOKEN>")
|
|
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
fmt.Println(string(body))
|
|
}
|
|
```
|
|
|
|
```ruby
|
|
require "uri"
|
|
require "json"
|
|
require "net/http"
|
|
|
|
url = URI("https://api.netbird.io/api/agent-network/guardrails/{guardrailId}")
|
|
|
|
https = Net::HTTP.new(url.host, url.port)
|
|
https.use_ssl = true
|
|
|
|
request = Net::HTTP::Delete.new(url)
|
|
request["Authorization"] = "Token <TOKEN>"
|
|
|
|
response = https.request(request)
|
|
puts response.read_body
|
|
```
|
|
|
|
```java
|
|
OkHttpClient client = new OkHttpClient().newBuilder()
|
|
.build();
|
|
|
|
Request request = new Request.Builder()
|
|
.url("https://api.netbird.io/api/agent-network/guardrails/{guardrailId}")
|
|
.method("DELETE")
|
|
.addHeader("Authorization: Token <TOKEN>")
|
|
.build();
|
|
Response response = client.newCall(request).execute();
|
|
```
|
|
|
|
```php
|
|
<?php
|
|
|
|
$curl = curl_init();
|
|
|
|
curl_setopt_array($curl, array(
|
|
CURLOPT_URL => 'https://api.netbird.io/api/agent-network/guardrails/{guardrailId}',
|
|
CURLOPT_RETURNTRANSFER => true,
|
|
CURLOPT_ENCODING => '',
|
|
CURLOPT_MAXREDIRS => 10,
|
|
CURLOPT_TIMEOUT => 0,
|
|
CURLOPT_FOLLOWLOCATION => true,
|
|
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
|
CURLOPT_CUSTOMREQUEST => 'DELETE',
|
|
CURLOPT_HTTPHEADER => array(
|
|
'Authorization: Token <TOKEN>'
|
|
),
|
|
));
|
|
|
|
$response = curl_exec($curl);
|
|
|
|
curl_close($curl);
|
|
echo $response;
|
|
```
|
|
|
|
</CodeGroup>
|
|
|
|
|
|
|
|
</Col>
|
|
</Row>
|
|
|
|
---
|