Update custom node
curl --request PUT \
--url https://your-tenant.bloodhoundenterprise.io/api/v2/custom-nodes/{kind_name} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"config": {
"icon": {
"type": "font-awesome",
"name": "house",
"color": "#333"
}
}
}
'import requests
url = "https://your-tenant.bloodhoundenterprise.io/api/v2/custom-nodes/{kind_name}"
payload = { "config": { "icon": {
"type": "font-awesome",
"name": "house",
"color": "#333"
} } }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({config: {icon: {type: 'font-awesome', name: 'house', color: '#333'}}})
};
fetch('https://your-tenant.bloodhoundenterprise.io/api/v2/custom-nodes/{kind_name}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://your-tenant.bloodhoundenterprise.io/api/v2/custom-nodes/{kind_name}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'config' => [
'icon' => [
'type' => 'font-awesome',
'name' => 'house',
'color' => '#333'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://your-tenant.bloodhoundenterprise.io/api/v2/custom-nodes/{kind_name}"
payload := strings.NewReader("{\n \"config\": {\n \"icon\": {\n \"type\": \"font-awesome\",\n \"name\": \"house\",\n \"color\": \"#333\"\n }\n }\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://your-tenant.bloodhoundenterprise.io/api/v2/custom-nodes/{kind_name}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"config\": {\n \"icon\": {\n \"type\": \"font-awesome\",\n \"name\": \"house\",\n \"color\": \"#333\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://your-tenant.bloodhoundenterprise.io/api/v2/custom-nodes/{kind_name}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"config\": {\n \"icon\": {\n \"type\": \"font-awesome\",\n \"name\": \"house\",\n \"color\": \"#333\"\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"kindName": "<string>",
"config": {
"icon": {
"type": "<string>",
"name": "<string>",
"color": "<string>"
}
}
}{
"http_status": 401,
"timestamp": "2024-02-19T19:27:43.866Z",
"request_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errors": [
{
"context": "login",
"message": "Unauthorized"
}
]
}{
"http_status": 404,
"timestamp": "2024-02-19T19:27:43.866Z",
"request_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errors": [
{
"context": "clients",
"message": "The requested client could not be found."
}
]
}{
"http_status": 500,
"timestamp": "2024-02-19T19:27:43.866Z",
"request_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errors": [
{
"context": "clients",
"message": "The request could not be handled due to an unexpected database error."
}
]
}Custom Node Management
Update custom node
This endpoint updates an existing node kind along with optional display metadata such as icons and colors. The provided configuration controls how nodes of the specified kinds are interpreted and rendered in the UI. Only free, solid-style Font Awesome icons are supported. Hex color codes must follow the format #RGB or #RRGGBB. If no valid icon or color is provided, the system will fall back to a question mark icon and a white background color.
PUT
/
api
/
v2
/
custom-nodes
/
{kind_name}
Update custom node
curl --request PUT \
--url https://your-tenant.bloodhoundenterprise.io/api/v2/custom-nodes/{kind_name} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"config": {
"icon": {
"type": "font-awesome",
"name": "house",
"color": "#333"
}
}
}
'import requests
url = "https://your-tenant.bloodhoundenterprise.io/api/v2/custom-nodes/{kind_name}"
payload = { "config": { "icon": {
"type": "font-awesome",
"name": "house",
"color": "#333"
} } }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({config: {icon: {type: 'font-awesome', name: 'house', color: '#333'}}})
};
fetch('https://your-tenant.bloodhoundenterprise.io/api/v2/custom-nodes/{kind_name}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://your-tenant.bloodhoundenterprise.io/api/v2/custom-nodes/{kind_name}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'config' => [
'icon' => [
'type' => 'font-awesome',
'name' => 'house',
'color' => '#333'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://your-tenant.bloodhoundenterprise.io/api/v2/custom-nodes/{kind_name}"
payload := strings.NewReader("{\n \"config\": {\n \"icon\": {\n \"type\": \"font-awesome\",\n \"name\": \"house\",\n \"color\": \"#333\"\n }\n }\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.put("https://your-tenant.bloodhoundenterprise.io/api/v2/custom-nodes/{kind_name}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"config\": {\n \"icon\": {\n \"type\": \"font-awesome\",\n \"name\": \"house\",\n \"color\": \"#333\"\n }\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://your-tenant.bloodhoundenterprise.io/api/v2/custom-nodes/{kind_name}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"config\": {\n \"icon\": {\n \"type\": \"font-awesome\",\n \"name\": \"house\",\n \"color\": \"#333\"\n }\n }\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"kindName": "<string>",
"config": {
"icon": {
"type": "<string>",
"name": "<string>",
"color": "<string>"
}
}
}{
"http_status": 401,
"timestamp": "2024-02-19T19:27:43.866Z",
"request_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errors": [
{
"context": "login",
"message": "Unauthorized"
}
]
}{
"http_status": 404,
"timestamp": "2024-02-19T19:27:43.866Z",
"request_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errors": [
{
"context": "clients",
"message": "The requested client could not be found."
}
]
}{
"http_status": 500,
"timestamp": "2024-02-19T19:27:43.866Z",
"request_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errors": [
{
"context": "clients",
"message": "The request could not be handled due to an unexpected database error."
}
]
}Authorizations
JWTBearerTokenSignedRequest & RequestDate & HMACSignature
Authorization: Bearer $JWT_TOKEN
Headers
Prefer header, used to specify a custom timeout in seconds using the wait parameter as per RFC7240. Passing in wait=-1 bypasses all timeout limits when the feature is enabled.
Pattern:
^wait=(-1|[0-9]+)$Path Parameters
Kind Name
Body
application/json
Show child attributes
Show child attributes
⌘I