curl --request GET \
--url https://your-tenant.bloodhoundenterprise.io/api/v2/graphs/shortest-path \
--header 'Authorization: Bearer <token>'import requests
url = "https://your-tenant.bloodhoundenterprise.io/api/v2/graphs/shortest-path"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://your-tenant.bloodhoundenterprise.io/api/v2/graphs/shortest-path', 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/graphs/shortest-path",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://your-tenant.bloodhoundenterprise.io/api/v2/graphs/shortest-path"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://your-tenant.bloodhoundenterprise.io/api/v2/graphs/shortest-path")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://your-tenant.bloodhoundenterprise.io/api/v2/graphs/shortest-path")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": {
"nodes": {},
"edges": [
{
"source": "<string>",
"target": "<string>",
"label": "<string>",
"kind": "<string>",
"lastSeen": "2023-11-07T05:31:56Z",
"properties": {}
}
]
}
}{
"http_status": 400,
"timestamp": "2024-02-19T19:27:43.866Z",
"request_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errors": [
{
"context": "clients",
"message": "The JSON payload could not be unmarshalled."
}
]
}{
"http_status": 401,
"timestamp": "2024-02-19T19:27:43.866Z",
"request_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errors": [
{
"context": "login",
"message": "Unauthorized"
}
]
}{
"http_status": 403,
"timestamp": "2024-02-19T19:27:43.866Z",
"request_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errors": [
{
"context": "clients",
"message": "You do not have permission to access this resource"
}
]
}{
"http_status": 429,
"timestamp": "2024-02-19T19:27:43.866Z",
"request_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errors": [
{
"context": "middleware",
"message": "Too many requests. Please try again later."
}
]
}{
"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."
}
]
}Get the shortest path graph
A graph of the shortest path from start_node to end_node.
curl --request GET \
--url https://your-tenant.bloodhoundenterprise.io/api/v2/graphs/shortest-path \
--header 'Authorization: Bearer <token>'import requests
url = "https://your-tenant.bloodhoundenterprise.io/api/v2/graphs/shortest-path"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://your-tenant.bloodhoundenterprise.io/api/v2/graphs/shortest-path', 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/graphs/shortest-path",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://your-tenant.bloodhoundenterprise.io/api/v2/graphs/shortest-path"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://your-tenant.bloodhoundenterprise.io/api/v2/graphs/shortest-path")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://your-tenant.bloodhoundenterprise.io/api/v2/graphs/shortest-path")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": {
"nodes": {},
"edges": [
{
"source": "<string>",
"target": "<string>",
"label": "<string>",
"kind": "<string>",
"lastSeen": "2023-11-07T05:31:56Z",
"properties": {}
}
]
}
}{
"http_status": 400,
"timestamp": "2024-02-19T19:27:43.866Z",
"request_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errors": [
{
"context": "clients",
"message": "The JSON payload could not be unmarshalled."
}
]
}{
"http_status": 401,
"timestamp": "2024-02-19T19:27:43.866Z",
"request_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errors": [
{
"context": "login",
"message": "Unauthorized"
}
]
}{
"http_status": 403,
"timestamp": "2024-02-19T19:27:43.866Z",
"request_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errors": [
{
"context": "clients",
"message": "You do not have permission to access this resource"
}
]
}{
"http_status": 429,
"timestamp": "2024-02-19T19:27:43.866Z",
"request_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"errors": [
{
"context": "middleware",
"message": "Too many requests. Please try again later."
}
]
}{
"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
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.
^wait=(-1|[0-9]+)$Query Parameters
The start node objectId
The end node objectId
Specific relationship kinds to include in the pathfinding search. If the kinds are not valid kinds, the query will error. The contains predicate checks a property against the values in a given comma separated list.
inchecks if the property matches an element in the given comma separated list.in:Contains,GetChangesAll,MemberOf
ninchecks if the property does not match an element in the given comma separated list.nin:LocalToComputer,MemberOfLocalGroup
^(in|nin):(\w+)(,\s*\w+)*$Whether or not to only include traversable kinds. If true and no relationship_kinds are specified, all traversable kinds will be searched. If true, and relationship_kinds param includes non-traversable kinds, the non-traversable kinds will be excluded from the path search. If false or omitted, all kinds will be searched.
Response
A graph of the shortest path from start_node to end_node.
Show child attributes
Show child attributes