Escape MDX-specific characters in API templates and refine Navigation… (#638)

* Escape MDX-specific characters in API templates and refine NavigationAPI links

* Update API pages with v0.66.0

---------

Co-authored-by: netbirddev <dev@netbird.io>
This commit is contained in:
Maycon Santos
2026-02-26 16:28:00 +01:00
committed by GitHub
parent 8b7b458569
commit b35de5b477
32 changed files with 18602 additions and 110 deletions

View File

@@ -7,6 +7,15 @@ import * as yaml from 'js-yaml';
import { merge } from 'allof-merge'
import RequestBodyObject = OpenAPIV3_1.RequestBodyObject;
function escapeMdx(text: string): string {
if (!text) return text;
return text
.replace(/<=/g, "{'<='}")
.replace(/>=/g, "{'>='}")
.replace(/^- /gm, '\\- ')
.replace(/\n- /g, '\n\\- ');
}
// Pre-processes the spec to fix allOf with conflicting enums by merging them
function fixConflictingEnumAllOf(obj: any): any {
if (obj === null || typeof obj !== 'object') {
@@ -123,7 +132,10 @@ async function gen_v3(spec: OpenAPIV3.Document, dest: string) {
Object.entries(spec.paths).forEach(([key, val]) => {
const fullPath = `${server}${key}`
toArrayWithKey(val!, 'operation').forEach((o) => {
const httpMethods = ['get', 'post', 'put', 'delete', 'patch', 'options', 'head', 'trace']
toArrayWithKey(val!, 'operation')
.filter((o) => httpMethods.includes(o.operation))
.forEach((o) => {
const operation = o as v3OperationWithPath
var request = null
@@ -135,7 +147,7 @@ async function gen_v3(spec: OpenAPIV3.Document, dest: string) {
}
var response = null
if(operation.responses["200"] != undefined && operation.responses["200"]["content"] != undefined && operation.responses["200"]["content"]["application/json"] != undefined) {
if(operation.responses && operation.responses["200"] != undefined && operation.responses["200"]["content"] != undefined && operation.responses["200"]["content"]["application/json"] != undefined) {
response = {
example: extractInfo(operation.responses["200"]["content"]["application/json"].schema, 'example'),
schema: extractInfo(operation.responses["200"]["content"]["application/json"].schema, 'type')
@@ -158,7 +170,10 @@ async function gen_v3(spec: OpenAPIV3.Document, dest: string) {
})
})
const excludedTags = ['Checkout', 'AWS Marketplace', 'Plans', 'Subscription', 'Portal']
tagGroups.forEach((value: enrichedOperation[], key: string) => {
if (excludedTags.includes(key)) return
const operations = value
@@ -176,11 +191,12 @@ async function gen_v3(spec: OpenAPIV3.Document, dest: string) {
tag: key,
sections,
operations,
escapeMdx,
// components,
})
// Write to disk
let outputFile = dest + "/" + key.toLowerCase().replace(" ", "-") + ".mdx"
let outputFile = dest + "/" + key.toLowerCase().replace(/ /g, "-") + ".mdx"
writeToDisk(outputFile, content)
// console.log('Saved: ', outputFile)

View File

@@ -1,5 +1,4 @@
const template = `
export const title = '<%- tag %>'
<% operations.forEach(function(operation){ %>
@@ -8,13 +7,13 @@ export const title = '<%- tag %>'
<Row>
<Col>
<%- operation.description %>
<%- escapeMdx(operation.description) %>
<% if(operation.parameters && operation.parameters.filter((parameter) => parameter.in === 'path').length > 0){ %>
### Path Parameters
<Properties>
<% operation.parameters.filter((parameter) => parameter.in === 'path').forEach(function(parameter){ %>
<Property name="<%- parameter.name %>" type="string" required=\{true\}>
<%- parameter.description %>
<%- escapeMdx(parameter.description) %>
</Property>
<% }); -%>
</Properties>
@@ -24,7 +23,7 @@ export const title = '<%- tag %>'
<Properties>
<% operation.parameters.filter((parameter) => parameter.in === 'query').forEach(function(parameter){ %>
<Property name="<%- parameter.name %>" type="<%- parameter.schema.type %>" required=\{false\}>
<%- parameter.description %>
<%- escapeMdx(parameter.description) %>
</Property>
<% }); -%>
</Properties>
@@ -76,7 +75,7 @@ function renderProperties(properties, required = [], depth = 0) {
</Properties>
</details>
<% } else { %>
<% if(value.description) { %><%- value.description %><% } %>
<% if(value.description) { %><%- escapeMdx(value.description) %><% } %>
<% } %>
</Property>
<% });

View File

@@ -15,7 +15,6 @@ export const apiNavigation = [
{ title: 'Quickstart', href: '/api/guides/quickstart' },
{ title: 'Authentication', href: '/api/guides/authentication' },
{ title: 'Errors', href: '/api/guides/errors' },
// { title: 'Events', href: '/accounts' },
],
},
{
@@ -25,22 +24,39 @@ export const apiNavigation = [
{ title: 'Users', href: '/api/resources/users' },
{ title: 'Tokens', href: '/api/resources/tokens' },
{ title: 'Peers', href: '/api/resources/peers' },
{ title: 'Ingress Ports', href: '/api/resources/ingress-ports' },
{ title: 'Setup Keys', href: '/api/resources/setup-keys' },
{ title: 'Groups', href: '/api/resources/groups' },
{ title: 'Policies', href: '/api/resources/policies' },
{ title: 'Posture-Checks', href: '/api/resources/posture-checks' },
{ title: 'Geo-Locations', href: '/api/resources/geo-locations' },
{ title: 'Posture Checks', href: '/api/resources/posture-checks' },
{ title: 'Geo Locations', href: '/api/resources/geo-locations' },
{ title: 'Routes (deprecated)', href: '/api/resources/routes' },
{ title: 'Networks', href: '/api/resources/networks' },
{ title: 'DNS', href: '/api/resources/dns' },
{ title: 'DNS Zones', href: '/api/resources/dns-zones' },
{ title: 'Services', href: '/api/resources/services' },
{ title: 'Events', href: '/api/resources/events' },
{ title: 'Event Streaming', href: '/api/resources/event-streaming-integrations' },
{ title: 'Jobs', href: '/api/resources/jobs' },
{ title: 'Identity Providers', href: '/api/resources/identity-providers' },
{ title: 'Instance', href: '/api/resources/instance' },
],
},
{
title: 'Cloud Resources',
links: [
{ title: 'Ingress Ports', href: '/api/resources/ingress-ports' },
{ title: 'IDP (SCIM)', href: '/api/resources/idp' },
{ title: 'Event Streaming', href: '/api/resources/event-streaming-integrations' },
{ title: 'EDR Peers', href: '/api/resources/edr-peers' },
{ title: 'EDR Falcon', href: '/api/resources/edr-falcon-integrations' },
{ title: 'EDR Huntress', href: '/api/resources/edr-huntress-integrations' },
{ title: 'EDR Intune', href: '/api/resources/edr-intune-integrations' },
{ title: 'EDR SentinelOne', href: '/api/resources/edr-sentinelone-integrations' },
{ title: 'MSP', href: '/api/resources/msp' },
{ title: 'Invoice', href: '/api/resources/invoice' },
{ title: 'Usage', href: '/api/resources/usage' },
],
},
]
export function NavigationAPI({tableOfContents, className}) {

View File

@@ -178,6 +178,10 @@ echo $response;
"routing_peer_dns_resolution_enabled": true,
"dns_domain": "my-organization.org",
"network_range": "100.64.0.0/16",
"peer_expose_enabled": false,
"peer_expose_groups": [
"ch8i4ug6lnn4g9hqv7m0"
],
"extra": {
"peer_approval_enabled": true,
"user_approval_required": false,
@@ -189,7 +193,8 @@ echo $response;
},
"lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
"embedded_idp_enabled": false,
"local_auth_disabled": false
},
"domain": "netbird.io",
"domain_category": "private",
@@ -221,6 +226,10 @@ echo $response;
"routing_peer_dns_resolution_enabled": "boolean",
"dns_domain": "string",
"network_range": "string",
"peer_expose_enabled": "boolean",
"peer_expose_groups": [
"string"
],
"extra": {
"peer_approval_enabled": "boolean",
"user_approval_required": "boolean",
@@ -232,7 +241,8 @@ echo $response;
},
"lazy_connection_enabled": "boolean",
"auto_update_version": "string",
"embedded_idp_enabled": "boolean"
"embedded_idp_enabled": "boolean",
"local_auth_disabled": "boolean"
},
"domain": "string",
"domain_category": "string",
@@ -499,6 +509,16 @@ echo $response;
Allows to define a custom network range for the account in CIDR format
</Property>
<Property name="peer_expose_enabled" type="boolean" required={true}>
Enables or disables peer expose. If enabled, peers can expose local services through the reverse proxy using the CLI.
</Property>
<Property name="peer_expose_groups" type="string[]" required={true}>
Limits which peer groups are allowed to expose services. If empty, all peers are allowed when peer expose is enabled.
</Property>
<Property name="extra" type="object" required={false}>
@@ -551,6 +571,11 @@ echo $response;
Indicates whether the embedded identity provider (Dex) is enabled for this account. This is a read-only field.
</Property>
<Property name="local_auth_disabled" type="boolean" required={false}>
Indicates whether local (email/password) authentication is disabled. When true, users can only authenticate via external identity providers. This is a read-only field.
</Property>
</Properties>
@@ -608,6 +633,10 @@ curl -X PUT https://api.netbird.io/api/accounts/{accountId} \
"routing_peer_dns_resolution_enabled": true,
"dns_domain": "my-organization.org",
"network_range": "100.64.0.0/16",
"peer_expose_enabled": false,
"peer_expose_groups": [
"ch8i4ug6lnn4g9hqv7m0"
],
"extra": {
"peer_approval_enabled": true,
"user_approval_required": false,
@@ -619,7 +648,8 @@ curl -X PUT https://api.netbird.io/api/accounts/{accountId} \
},
"lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
"embedded_idp_enabled": false,
"local_auth_disabled": false
},
"onboarding": {
"signup_form_pending": true,
@@ -646,6 +676,10 @@ let data = JSON.stringify({
"routing_peer_dns_resolution_enabled": true,
"dns_domain": "my-organization.org",
"network_range": "100.64.0.0/16",
"peer_expose_enabled": false,
"peer_expose_groups": [
"ch8i4ug6lnn4g9hqv7m0"
],
"extra": {
"peer_approval_enabled": true,
"user_approval_required": false,
@@ -657,7 +691,8 @@ let data = JSON.stringify({
},
"lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
"embedded_idp_enabled": false,
"local_auth_disabled": false
},
"onboarding": {
"signup_form_pending": true,
@@ -706,6 +741,10 @@ payload = json.dumps({
"routing_peer_dns_resolution_enabled": true,
"dns_domain": "my-organization.org",
"network_range": "100.64.0.0/16",
"peer_expose_enabled": false,
"peer_expose_groups": [
"ch8i4ug6lnn4g9hqv7m0"
],
"extra": {
"peer_approval_enabled": true,
"user_approval_required": false,
@@ -717,7 +756,8 @@ payload = json.dumps({
},
"lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
"embedded_idp_enabled": false,
"local_auth_disabled": false
},
"onboarding": {
"signup_form_pending": true,
@@ -766,6 +806,10 @@ func main() {
"routing_peer_dns_resolution_enabled": true,
"dns_domain": "my-organization.org",
"network_range": "100.64.0.0/16",
"peer_expose_enabled": false,
"peer_expose_groups": [
"ch8i4ug6lnn4g9hqv7m0"
],
"extra": {
"peer_approval_enabled": true,
"user_approval_required": false,
@@ -777,7 +821,8 @@ func main() {
},
"lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
"embedded_idp_enabled": false,
"local_auth_disabled": false
},
"onboarding": {
"signup_form_pending": true,
@@ -844,6 +889,10 @@ request.body = JSON.dump({
"routing_peer_dns_resolution_enabled": true,
"dns_domain": "my-organization.org",
"network_range": "100.64.0.0/16",
"peer_expose_enabled": false,
"peer_expose_groups": [
"ch8i4ug6lnn4g9hqv7m0"
],
"extra": {
"peer_approval_enabled": true,
"user_approval_required": false,
@@ -855,7 +904,8 @@ request.body = JSON.dump({
},
"lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
"embedded_idp_enabled": false,
"local_auth_disabled": false
},
"onboarding": {
"signup_form_pending": true,
@@ -886,6 +936,10 @@ RequestBody body = RequestBody.create(mediaType, '{
"routing_peer_dns_resolution_enabled": true,
"dns_domain": "my-organization.org",
"network_range": "100.64.0.0/16",
"peer_expose_enabled": false,
"peer_expose_groups": [
"ch8i4ug6lnn4g9hqv7m0"
],
"extra": {
"peer_approval_enabled": true,
"user_approval_required": false,
@@ -897,7 +951,8 @@ RequestBody body = RequestBody.create(mediaType, '{
},
"lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
"embedded_idp_enabled": false,
"local_auth_disabled": false
},
"onboarding": {
"signup_form_pending": true,
@@ -944,6 +999,10 @@ curl_setopt_array($curl, array(
"routing_peer_dns_resolution_enabled": true,
"dns_domain": "my-organization.org",
"network_range": "100.64.0.0/16",
"peer_expose_enabled": false,
"peer_expose_groups": [
"ch8i4ug6lnn4g9hqv7m0"
],
"extra": {
"peer_approval_enabled": true,
"user_approval_required": false,
@@ -955,7 +1014,8 @@ curl_setopt_array($curl, array(
},
"lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
"embedded_idp_enabled": false,
"local_auth_disabled": false
},
"onboarding": {
"signup_form_pending": true,
@@ -997,6 +1057,10 @@ echo $response;
"routing_peer_dns_resolution_enabled": true,
"dns_domain": "my-organization.org",
"network_range": "100.64.0.0/16",
"peer_expose_enabled": false,
"peer_expose_groups": [
"ch8i4ug6lnn4g9hqv7m0"
],
"extra": {
"peer_approval_enabled": true,
"user_approval_required": false,
@@ -1008,7 +1072,8 @@ echo $response;
},
"lazy_connection_enabled": true,
"auto_update_version": "0.51.2",
"embedded_idp_enabled": false
"embedded_idp_enabled": false,
"local_auth_disabled": false
},
"domain": "netbird.io",
"domain_category": "private",
@@ -1038,6 +1103,10 @@ echo $response;
"routing_peer_dns_resolution_enabled": "boolean",
"dns_domain": "string",
"network_range": "string",
"peer_expose_enabled": "boolean",
"peer_expose_groups": [
"string"
],
"extra": {
"peer_approval_enabled": "boolean",
"user_approval_required": "boolean",
@@ -1049,7 +1118,8 @@ echo $response;
},
"lazy_connection_enabled": "boolean",
"auto_update_version": "string",
"embedded_idp_enabled": "boolean"
"embedded_idp_enabled": "boolean",
"local_auth_disabled": "boolean"
},
"domain": "string",
"domain_category": "string",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,517 @@
export const title = 'EDR Peers'
## Bypass compliance for a non-compliant peer {{ tag: 'POST' , label: '/api/peers/{peer-id}/edr/bypass' }}
<Row>
<Col>
Allows an admin to bypass EDR compliance checks for a specific peer.
The peer will remain bypassed until the admin revokes it OR the device becomes
naturally compliant in the EDR system.
</Col>
<Col sticky>
<CodeGroup title="Request" tag="POST" label="/api/peers/{peer-id}/edr/bypass">
```bash {{ title: 'cURL' }}
curl -X POST https://api.netbird.io/api/peers/{peer-id}/edr/bypass \
-H 'Accept: application/json' \
-H 'Authorization: Token <TOKEN>'
```
```js
const axios = require('axios');
let config = {
method: 'post',
maxBodyLength: Infinity,
url: '/api/peers/{peer-id}/edr/bypass',
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/peers/{peer-id}/edr/bypass"
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/peers/{peer-id}/edr/bypass"
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/peers/{peer-id}/edr/bypass")
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/peers/{peer-id}/edr/bypass")
.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/peers/{peer-id}/edr/bypass',
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' }}
{
"peer_id": "chacbco6lnnbn6cg5s91"
}
```
```json {{ title: 'Schema' }}
{
"peer_id": "string"
}
```
</CodeGroup>
</Col>
</Row>
---
## Revoke compliance bypass for a peer {{ tag: 'DELETE' , label: '/api/peers/{peer-id}/edr/bypass' }}
<Row>
<Col>
Removes the compliance bypass, subjecting the peer to normal EDR validation.
</Col>
<Col sticky>
<CodeGroup title="Request" tag="DELETE" label="/api/peers/{peer-id}/edr/bypass">
```bash {{ title: 'cURL' }}
curl -X DELETE https://api.netbird.io/api/peers/{peer-id}/edr/bypass \
-H 'Authorization: Token <TOKEN>'
```
```js
const axios = require('axios');
let config = {
method: 'delete',
maxBodyLength: Infinity,
url: '/api/peers/{peer-id}/edr/bypass',
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/peers/{peer-id}/edr/bypass"
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/peers/{peer-id}/edr/bypass"
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/peers/{peer-id}/edr/bypass")
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/peers/{peer-id}/edr/bypass")
.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/peers/{peer-id}/edr/bypass',
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 bypassed peers {{ tag: 'GET' , label: '/api/peers/edr/bypassed' }}
<Row>
<Col>
Returns all peers that have compliance bypassed by an admin.
</Col>
<Col sticky>
<CodeGroup title="Request" tag="GET" label="/api/peers/edr/bypassed">
```bash {{ title: 'cURL' }}
curl -X GET https://api.netbird.io/api/peers/edr/bypassed \
-H 'Accept: application/json' \
-H 'Authorization: Token <TOKEN>'
```
```js
const axios = require('axios');
let config = {
method: 'get',
maxBodyLength: Infinity,
url: '/api/peers/edr/bypassed',
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/peers/edr/bypassed"
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/peers/edr/bypassed"
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/peers/edr/bypassed")
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/peers/edr/bypassed")
.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/peers/edr/bypassed',
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' }}
[
{
"peer_id": "chacbco6lnnbn6cg5s91"
}
]
```
```json {{ title: 'Schema' }}
[
{
"peer_id": "string"
}
]
```
</CodeGroup>
</Col>
</Row>
---

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -561,3 +561,289 @@ echo $response;
</Row>
---
## List all Reverse Proxy Access Logs {{ tag: 'GET' , label: '/api/events/proxy' }}
<Row>
<Col>
Returns a paginated list of all reverse proxy access log entries
### 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 (url sorts by host then path)
</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 request ID, host, path, source IP, user email, and user name
</Property>
<Property name="source_ip" type="string" required={false}>
Filter by source IP address
</Property>
<Property name="host" type="string" required={false}>
Filter by host header
</Property>
<Property name="path" type="string" required={false}>
Filter by request path (supports partial matching)
</Property>
<Property name="user_id" type="string" required={false}>
Filter by authenticated user ID
</Property>
<Property name="user_email" type="string" required={false}>
Filter by user email (partial matching)
</Property>
<Property name="user_name" type="string" required={false}>
Filter by user name (partial matching)
</Property>
<Property name="method" type="string" required={false}>
Filter by HTTP method
</Property>
<Property name="status" type="string" required={false}>
Filter by status (success = 2xx/3xx, failed = 1xx/4xx/5xx)
</Property>
<Property name="status_code" type="integer" required={false}>
Filter by HTTP status code
</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/events/proxy">
```bash {{ title: 'cURL' }}
curl -X GET https://api.netbird.io/api/events/proxy \
-H 'Accept: application/json' \
-H 'Authorization: Token <TOKEN>'
```
```js
const axios = require('axios');
let config = {
method: 'get',
maxBodyLength: Infinity,
url: '/api/events/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/events/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/events/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/events/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/events/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/events/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' }}
{
"data": [
{
"id": "ch8i4ug6lnn4g9hqv7m0",
"service_id": "ch8i4ug6lnn4g9hqv7m0",
"timestamp": "2024-01-31T15:30:00Z",
"method": "GET",
"host": "example.com",
"path": "/api/users",
"duration_ms": 150,
"status_code": 200,
"source_ip": "192.168.1.100",
"reason": "Authentication failed",
"user_id": "user-123",
"auth_method_used": "oidc",
"country_code": "US",
"city_name": "San Francisco"
}
],
"page": 1,
"page_size": 50,
"total_records": 523,
"total_pages": 11
}
```
```json {{ title: 'Schema' }}
{
"data": [
{
"id": "string",
"service_id": "string",
"timestamp": "string",
"method": "string",
"host": "string",
"path": "string",
"duration_ms": "integer",
"status_code": "integer",
"source_ip": "string",
"reason": "string",
"user_id": "string",
"auth_method_used": "string",
"country_code": "string",
"city_name": "string"
}
],
"page": "integer",
"page_size": "integer",
"total_records": "integer",
"total_pages": "integer"
}
```
</CodeGroup>
</Col>
</Row>
---

File diff suppressed because it is too large Load Diff

View File

@@ -178,6 +178,188 @@ echo $response;
---
## Get Version Info {{ tag: 'GET' , label: '/api/instance/version' }}
<Row>
<Col>
Returns version information for NetBird components including the current management server version and latest available versions from GitHub.
</Col>
<Col sticky>
<CodeGroup title="Request" tag="GET" label="/api/instance/version">
```bash {{ title: 'cURL' }}
curl -X GET https://api.netbird.io/api/instance/version \
-H 'Accept: application/json' \
-H 'Authorization: Token <TOKEN>'
```
```js
const axios = require('axios');
let config = {
method: 'get',
maxBodyLength: Infinity,
url: '/api/instance/version',
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/instance/version"
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/instance/version"
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/instance/version")
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/instance/version")
.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/instance/version',
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' }}
{
"management_current_version": "0.35.0",
"dashboard_available_version": "2.10.0",
"management_available_version": "0.35.0",
"management_update_available": true
}
```
```json {{ title: 'Schema' }}
{
"management_current_version": "string",
"dashboard_available_version": "string",
"management_available_version": "string",
"management_update_available": "boolean"
}
```
</CodeGroup>
</Col>
</Row>
---
## Setup Instance {{ tag: 'POST' , label: '/api/setup' }}
<Row>

View File

@@ -0,0 +1,543 @@
export const title = 'Invoice'
## Get account's paid invoices {{ tag: 'GET' , label: '/api/integrations/billing/invoices' }}
<Row>
<Col>
</Col>
<Col sticky>
<CodeGroup title="Request" tag="GET" label="/api/integrations/billing/invoices">
```bash {{ title: 'cURL' }}
curl -X GET https://api.netbird.io/api/integrations/billing/invoices \
-H 'Accept: application/json' \
-H 'Authorization: Token <TOKEN>'
```
```js
const axios = require('axios');
let config = {
method: 'get',
maxBodyLength: Infinity,
url: '/api/integrations/billing/invoices',
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/billing/invoices"
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/billing/invoices"
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/billing/invoices")
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/billing/invoices")
.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/billing/invoices',
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": "in_1MtHbELkdIwHu7ixl4OzzPMv",
"type": {
"type": "string",
"description": "The invoice type",
"enum": [
"account",
"tenants"
]
},
"period_start": "2021-08-01T12:00:00Z",
"period_end": "2021-08-31T12:00:00Z"
}
]
```
```json {{ title: 'Schema' }}
[
{
"id": "string",
"type": "string",
"period_start": "string",
"period_end": "string"
}
]
```
</CodeGroup>
</Col>
</Row>
---
## Get account invoice URL to Stripe. {{ tag: 'GET' , label: '/api/integrations/billing/invoices/{id}/pdf' }}
<Row>
<Col>
### Path Parameters
<Properties>
<Property name="id" type="string" required={true}>
The unique identifier of the invoice
</Property>
</Properties>
</Col>
<Col sticky>
<CodeGroup title="Request" tag="GET" label="/api/integrations/billing/invoices/{id}/pdf">
```bash {{ title: 'cURL' }}
curl -X GET https://api.netbird.io/api/integrations/billing/invoices/{id}/pdf \
-H 'Accept: application/json' \
-H 'Authorization: Token <TOKEN>'
```
```js
const axios = require('axios');
let config = {
method: 'get',
maxBodyLength: Infinity,
url: '/api/integrations/billing/invoices/{id}/pdf',
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/billing/invoices/{id}/pdf"
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/billing/invoices/{id}/pdf"
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/billing/invoices/{id}/pdf")
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/billing/invoices/{id}/pdf")
.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/billing/invoices/{id}/pdf',
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' }}
{
"url": "https://invoice.stripe.com/i/acct_1M2DaBKina4I2KUb/test_YWNjdF8xTTJEdVBLaW5hM0kyS1ViLF1SeFpQdEJZd3lUOGNEajNqeWdrdXY2RFM4aHcyCnpsLDEzMjg3GTgyNQ02000JoIHc1X?s=db"
}
```
```json {{ title: 'Schema' }}
{
"url": "string"
}
```
</CodeGroup>
</Col>
</Row>
---
## Get account invoice CSV. {{ tag: 'GET' , label: '/api/integrations/billing/invoices/{id}/csv' }}
<Row>
<Col>
### Path Parameters
<Properties>
<Property name="id" type="string" required={true}>
The unique identifier of the invoice
</Property>
</Properties>
</Col>
<Col sticky>
<CodeGroup title="Request" tag="GET" label="/api/integrations/billing/invoices/{id}/csv">
```bash {{ title: 'cURL' }}
curl -X GET https://api.netbird.io/api/integrations/billing/invoices/{id}/csv \
-H 'Authorization: Token <TOKEN>'
```
```js
const axios = require('axios');
let config = {
method: 'get',
maxBodyLength: Infinity,
url: '/api/integrations/billing/invoices/{id}/csv',
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/integrations/billing/invoices/{id}/csv"
headers = {
'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/billing/invoices/{id}/csv"
method := "GET"
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/integrations/billing/invoices/{id}/csv")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.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/integrations/billing/invoices/{id}/csv")
.method("GET")
.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/billing/invoices/{id}/csv',
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(
'Authorization: Token <TOKEN>'
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
```
</CodeGroup>
</Col>
</Row>
---

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,184 @@
export const title = 'Usage'
## Get current usage {{ tag: 'GET' , label: '/api/integrations/billing/usage' }}
<Row>
<Col>
</Col>
<Col sticky>
<CodeGroup title="Request" tag="GET" label="/api/integrations/billing/usage">
```bash {{ title: 'cURL' }}
curl -X GET https://api.netbird.io/api/integrations/billing/usage \
-H 'Accept: application/json' \
-H 'Authorization: Token <TOKEN>'
```
```js
const axios = require('axios');
let config = {
method: 'get',
maxBodyLength: Infinity,
url: '/api/integrations/billing/usage',
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/billing/usage"
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/billing/usage"
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/billing/usage")
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/billing/usage")
.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/billing/usage',
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' }}
{
"active_users": 15,
"total_users": 20,
"active_peers": 10,
"total_peers": 25
}
```
```json {{ title: 'Schema' }}
{
"active_users": "integer",
"total_users": "integer",
"active_peers": "integer",
"total_peers": "integer"
}
```
</CodeGroup>
</Col>
</Row>
---

File diff suppressed because it is too large Load Diff