curl --request POST \
--url https://api.opal.dev/v1/queries/run \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"type": "NODE",
"query": {
"nodeFilters": {
"entityTypes": [
"RESOURCE"
],
"entityTag": {
"key": "env",
"value": "prod"
}
},
"accessFilters": {
"isAccessibleBy": {
"entityTypes": [
"USER"
],
"entityTag": {
"key": "contractor"
}
}
}
},
"first": 50
}
'import requests
url = "https://api.opal.dev/v1/queries/run"
payload = {
"type": "NODE",
"query": {
"nodeFilters": {
"entityTypes": ["RESOURCE"],
"entityTag": {
"key": "env",
"value": "prod"
}
},
"accessFilters": { "isAccessibleBy": {
"entityTypes": ["USER"],
"entityTag": { "key": "contractor" }
} }
},
"first": 50
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
type: 'NODE',
query: {
nodeFilters: {entityTypes: ['RESOURCE'], entityTag: {key: 'env', value: 'prod'}},
accessFilters: {isAccessibleBy: {entityTypes: ['USER'], entityTag: {key: 'contractor'}}}
},
first: 50
})
};
fetch('https://api.opal.dev/v1/queries/run', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.opal.dev/v1/queries/run",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'type' => 'NODE',
'query' => [
'nodeFilters' => [
'entityTypes' => [
'RESOURCE'
],
'entityTag' => [
'key' => 'env',
'value' => 'prod'
]
],
'accessFilters' => [
'isAccessibleBy' => [
'entityTypes' => [
'USER'
],
'entityTag' => [
'key' => 'contractor'
]
]
]
],
'first' => 50
]),
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://api.opal.dev/v1/queries/run"
payload := strings.NewReader("{\n \"type\": \"NODE\",\n \"query\": {\n \"nodeFilters\": {\n \"entityTypes\": [\n \"RESOURCE\"\n ],\n \"entityTag\": {\n \"key\": \"env\",\n \"value\": \"prod\"\n }\n },\n \"accessFilters\": {\n \"isAccessibleBy\": {\n \"entityTypes\": [\n \"USER\"\n ],\n \"entityTag\": {\n \"key\": \"contractor\"\n }\n }\n }\n },\n \"first\": 50\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.opal.dev/v1/queries/run")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"type\": \"NODE\",\n \"query\": {\n \"nodeFilters\": {\n \"entityTypes\": [\n \"RESOURCE\"\n ],\n \"entityTag\": {\n \"key\": \"env\",\n \"value\": \"prod\"\n }\n },\n \"accessFilters\": {\n \"isAccessibleBy\": {\n \"entityTypes\": [\n \"USER\"\n ],\n \"entityTag\": {\n \"key\": \"contractor\"\n }\n }\n }\n },\n \"first\": 50\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.opal.dev/v1/queries/run")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"type\": \"NODE\",\n \"query\": {\n \"nodeFilters\": {\n \"entityTypes\": [\n \"RESOURCE\"\n ],\n \"entityTag\": {\n \"key\": \"env\",\n \"value\": \"prod\"\n }\n },\n \"accessFilters\": {\n \"isAccessibleBy\": {\n \"entityTypes\": [\n \"USER\"\n ],\n \"entityTag\": {\n \"key\": \"contractor\"\n }\n }\n }\n },\n \"first\": 50\n}"
response = http.request(request)
puts response.read_body{
"type": "NODE",
"edges": [
{
"node": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"entityType": "USER",
"entityItemType": "OPAL_ROLE"
},
"cursor": "<string>"
}
],
"pageInfo": {
"hasNextPage": true,
"endCursor": "<string>",
"hasPreviousPage": true,
"startCursor": "<string>"
}
}Run an ad-hoc OpalQuery
Executes an ad-hoc OpalQuery and returns paginated results. Two query types are supported: a Node query filters and returns entities (users, resources, or groups); an Access query returns the access grants between principals and their entitlements, one per (principal, entitlement, access level). Set type to NODE or ACCESS in the request body to select the query type.
This endpoint is available to OpalQuery beta participants. To request access, contact Opal support.
curl --request POST \
--url https://api.opal.dev/v1/queries/run \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"type": "NODE",
"query": {
"nodeFilters": {
"entityTypes": [
"RESOURCE"
],
"entityTag": {
"key": "env",
"value": "prod"
}
},
"accessFilters": {
"isAccessibleBy": {
"entityTypes": [
"USER"
],
"entityTag": {
"key": "contractor"
}
}
}
},
"first": 50
}
'import requests
url = "https://api.opal.dev/v1/queries/run"
payload = {
"type": "NODE",
"query": {
"nodeFilters": {
"entityTypes": ["RESOURCE"],
"entityTag": {
"key": "env",
"value": "prod"
}
},
"accessFilters": { "isAccessibleBy": {
"entityTypes": ["USER"],
"entityTag": { "key": "contractor" }
} }
},
"first": 50
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
type: 'NODE',
query: {
nodeFilters: {entityTypes: ['RESOURCE'], entityTag: {key: 'env', value: 'prod'}},
accessFilters: {isAccessibleBy: {entityTypes: ['USER'], entityTag: {key: 'contractor'}}}
},
first: 50
})
};
fetch('https://api.opal.dev/v1/queries/run', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.opal.dev/v1/queries/run",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'type' => 'NODE',
'query' => [
'nodeFilters' => [
'entityTypes' => [
'RESOURCE'
],
'entityTag' => [
'key' => 'env',
'value' => 'prod'
]
],
'accessFilters' => [
'isAccessibleBy' => [
'entityTypes' => [
'USER'
],
'entityTag' => [
'key' => 'contractor'
]
]
]
],
'first' => 50
]),
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://api.opal.dev/v1/queries/run"
payload := strings.NewReader("{\n \"type\": \"NODE\",\n \"query\": {\n \"nodeFilters\": {\n \"entityTypes\": [\n \"RESOURCE\"\n ],\n \"entityTag\": {\n \"key\": \"env\",\n \"value\": \"prod\"\n }\n },\n \"accessFilters\": {\n \"isAccessibleBy\": {\n \"entityTypes\": [\n \"USER\"\n ],\n \"entityTag\": {\n \"key\": \"contractor\"\n }\n }\n }\n },\n \"first\": 50\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.opal.dev/v1/queries/run")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"type\": \"NODE\",\n \"query\": {\n \"nodeFilters\": {\n \"entityTypes\": [\n \"RESOURCE\"\n ],\n \"entityTag\": {\n \"key\": \"env\",\n \"value\": \"prod\"\n }\n },\n \"accessFilters\": {\n \"isAccessibleBy\": {\n \"entityTypes\": [\n \"USER\"\n ],\n \"entityTag\": {\n \"key\": \"contractor\"\n }\n }\n }\n },\n \"first\": 50\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.opal.dev/v1/queries/run")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"type\": \"NODE\",\n \"query\": {\n \"nodeFilters\": {\n \"entityTypes\": [\n \"RESOURCE\"\n ],\n \"entityTag\": {\n \"key\": \"env\",\n \"value\": \"prod\"\n }\n },\n \"accessFilters\": {\n \"isAccessibleBy\": {\n \"entityTypes\": [\n \"USER\"\n ],\n \"entityTag\": {\n \"key\": \"contractor\"\n }\n }\n }\n },\n \"first\": 50\n}"
response = http.request(request)
puts response.read_body{
"type": "NODE",
"edges": [
{
"node": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"entityType": "USER",
"entityItemType": "OPAL_ROLE"
},
"cursor": "<string>"
}
],
"pageInfo": {
"hasNextPage": true,
"endCursor": "<string>",
"hasPreviousPage": true,
"startCursor": "<string>"
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
- Node
- Access
Request body for an ad-hoc OpalQuery. Set type to NODE to query entities, or ACCESS to query access grants. The fields available in query differ by type — refer to each tab for the full schema.
NODE The filter body for a NODE-type OpalQuery.
Show child attributes
Show child attributes
Maximum number of results to return. Defaults to 200.
200
Cursor from a previous response to fetch the next page of results.
"29827fb8-f2dd-4e80-9576-28e31e9934ac"
Response
The results of the OpalQuery.
- Option 1
- Option 2
Paginated results of an OpalQuery. The type field discriminates which result schema applies and mirrors the type field on the request.
Was this page helpful?