Check that an expression compiles
Compiles an expression without touching cost data, for checking a rule as it is typed. Returns the compiler error when it does not compile. Use preview to find out what it would match. A rule is written one of three ways and exactly one may be sent: expression as CostQL text, clause as a single chip, or node as a tree of chips. A node is rendered server-side by the same renderer the decompose endpoint round-trips through, so a rule saved from chips reads back as the identical tree, and sending node together with expression or clause is a 400 rather than a silent pick. Every leaf of a node is checked like a flat clause, so a tree cannot smuggle in a field or operator the clause path would refuse. Send key as well and the response also reports whether an existing literal rule with no validity window under that tag key (matched case-insensitively) already carries the same predicate, returning its id; the match is on a canonical fingerprint, so a reordered restatement of the same predicate is reported as a duplicate. The response also carries expression_hash, that same canonical fingerprint of the expression that was checked, so a caller can compare two expressions for semantic equality without canonicalising them itself.
curl --request POST \
--url https://api.costgraph.ai/api/v1/tenant/virtual-tags/validate \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"clause": {
"field": "<string>",
"match_value": "<string>",
"operator": "<string>"
},
"expression": "<string>",
"key": "<string>",
"node": {
"children": "<array>",
"clause": {
"field": "<string>",
"match_value": "<string>",
"operator": "<string>"
},
"kind": "<string>"
},
"scope": "<string>",
"yields": "<string>"
}
'import requests
url = "https://api.costgraph.ai/api/v1/tenant/virtual-tags/validate"
payload = {
"clause": {
"field": "<string>",
"match_value": "<string>",
"operator": "<string>"
},
"expression": "<string>",
"key": "<string>",
"node": {
"children": "<array>",
"clause": {
"field": "<string>",
"match_value": "<string>",
"operator": "<string>"
},
"kind": "<string>"
},
"scope": "<string>",
"yields": "<string>"
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
clause: {field: '<string>', match_value: '<string>', operator: '<string>'},
expression: '<string>',
key: '<string>',
node: {
children: '<array>',
clause: {field: '<string>', match_value: '<string>', operator: '<string>'},
kind: '<string>'
},
scope: '<string>',
yields: '<string>'
})
};
fetch('https://api.costgraph.ai/api/v1/tenant/virtual-tags/validate', 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.costgraph.ai/api/v1/tenant/virtual-tags/validate",
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([
'clause' => [
'field' => '<string>',
'match_value' => '<string>',
'operator' => '<string>'
],
'expression' => '<string>',
'key' => '<string>',
'node' => [
'children' => '<array>',
'clause' => [
'field' => '<string>',
'match_value' => '<string>',
'operator' => '<string>'
],
'kind' => '<string>'
],
'scope' => '<string>',
'yields' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"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.costgraph.ai/api/v1/tenant/virtual-tags/validate"
payload := strings.NewReader("{\n \"clause\": {\n \"field\": \"<string>\",\n \"match_value\": \"<string>\",\n \"operator\": \"<string>\"\n },\n \"expression\": \"<string>\",\n \"key\": \"<string>\",\n \"node\": {\n \"children\": \"<array>\",\n \"clause\": {\n \"field\": \"<string>\",\n \"match_value\": \"<string>\",\n \"operator\": \"<string>\"\n },\n \"kind\": \"<string>\"\n },\n \"scope\": \"<string>\",\n \"yields\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
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.costgraph.ai/api/v1/tenant/virtual-tags/validate")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"clause\": {\n \"field\": \"<string>\",\n \"match_value\": \"<string>\",\n \"operator\": \"<string>\"\n },\n \"expression\": \"<string>\",\n \"key\": \"<string>\",\n \"node\": {\n \"children\": \"<array>\",\n \"clause\": {\n \"field\": \"<string>\",\n \"match_value\": \"<string>\",\n \"operator\": \"<string>\"\n },\n \"kind\": \"<string>\"\n },\n \"scope\": \"<string>\",\n \"yields\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.costgraph.ai/api/v1/tenant/virtual-tags/validate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"clause\": {\n \"field\": \"<string>\",\n \"match_value\": \"<string>\",\n \"operator\": \"<string>\"\n },\n \"expression\": \"<string>\",\n \"key\": \"<string>\",\n \"node\": {\n \"children\": \"<array>\",\n \"clause\": {\n \"field\": \"<string>\",\n \"match_value\": \"<string>\",\n \"operator\": \"<string>\"\n },\n \"kind\": \"<string>\"\n },\n \"scope\": \"<string>\",\n \"yields\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"message": "some message",
"status": "success",
"data": {
"duplicate": true,
"duplicate_rule_id": "<string>",
"expression_hash": "<string>"
}
}{
"message": "some message",
"status": "error"
}{
"message": "some message",
"status": "error"
}Authorizations
Enter "Bearer {token}"
Body
Expression to check, or a clause or node to build one from; set yields to value for an inherited rule's value expression, and key to also check the predicate is not already taken under that tag key
Was this page helpful?
curl --request POST \
--url https://api.costgraph.ai/api/v1/tenant/virtual-tags/validate \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"clause": {
"field": "<string>",
"match_value": "<string>",
"operator": "<string>"
},
"expression": "<string>",
"key": "<string>",
"node": {
"children": "<array>",
"clause": {
"field": "<string>",
"match_value": "<string>",
"operator": "<string>"
},
"kind": "<string>"
},
"scope": "<string>",
"yields": "<string>"
}
'import requests
url = "https://api.costgraph.ai/api/v1/tenant/virtual-tags/validate"
payload = {
"clause": {
"field": "<string>",
"match_value": "<string>",
"operator": "<string>"
},
"expression": "<string>",
"key": "<string>",
"node": {
"children": "<array>",
"clause": {
"field": "<string>",
"match_value": "<string>",
"operator": "<string>"
},
"kind": "<string>"
},
"scope": "<string>",
"yields": "<string>"
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
clause: {field: '<string>', match_value: '<string>', operator: '<string>'},
expression: '<string>',
key: '<string>',
node: {
children: '<array>',
clause: {field: '<string>', match_value: '<string>', operator: '<string>'},
kind: '<string>'
},
scope: '<string>',
yields: '<string>'
})
};
fetch('https://api.costgraph.ai/api/v1/tenant/virtual-tags/validate', 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.costgraph.ai/api/v1/tenant/virtual-tags/validate",
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([
'clause' => [
'field' => '<string>',
'match_value' => '<string>',
'operator' => '<string>'
],
'expression' => '<string>',
'key' => '<string>',
'node' => [
'children' => '<array>',
'clause' => [
'field' => '<string>',
'match_value' => '<string>',
'operator' => '<string>'
],
'kind' => '<string>'
],
'scope' => '<string>',
'yields' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"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.costgraph.ai/api/v1/tenant/virtual-tags/validate"
payload := strings.NewReader("{\n \"clause\": {\n \"field\": \"<string>\",\n \"match_value\": \"<string>\",\n \"operator\": \"<string>\"\n },\n \"expression\": \"<string>\",\n \"key\": \"<string>\",\n \"node\": {\n \"children\": \"<array>\",\n \"clause\": {\n \"field\": \"<string>\",\n \"match_value\": \"<string>\",\n \"operator\": \"<string>\"\n },\n \"kind\": \"<string>\"\n },\n \"scope\": \"<string>\",\n \"yields\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<api-key>")
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.costgraph.ai/api/v1/tenant/virtual-tags/validate")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"clause\": {\n \"field\": \"<string>\",\n \"match_value\": \"<string>\",\n \"operator\": \"<string>\"\n },\n \"expression\": \"<string>\",\n \"key\": \"<string>\",\n \"node\": {\n \"children\": \"<array>\",\n \"clause\": {\n \"field\": \"<string>\",\n \"match_value\": \"<string>\",\n \"operator\": \"<string>\"\n },\n \"kind\": \"<string>\"\n },\n \"scope\": \"<string>\",\n \"yields\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.costgraph.ai/api/v1/tenant/virtual-tags/validate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"clause\": {\n \"field\": \"<string>\",\n \"match_value\": \"<string>\",\n \"operator\": \"<string>\"\n },\n \"expression\": \"<string>\",\n \"key\": \"<string>\",\n \"node\": {\n \"children\": \"<array>\",\n \"clause\": {\n \"field\": \"<string>\",\n \"match_value\": \"<string>\",\n \"operator\": \"<string>\"\n },\n \"kind\": \"<string>\"\n },\n \"scope\": \"<string>\",\n \"yields\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"message": "some message",
"status": "success",
"data": {
"duplicate": true,
"duplicate_rule_id": "<string>",
"expression_hash": "<string>"
}
}{
"message": "some message",
"status": "error"
}{
"message": "some message",
"status": "error"
}