curl --request POST \
--url https://api.coval.dev/v1/metrics/sql:test \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"sql_query": "<string>",
"aggregation_method": "<string>",
"unit": "<string>"
}
'import requests
url = "https://api.coval.dev/v1/metrics/sql:test"
payload = {
"sql_query": "<string>",
"aggregation_method": "<string>",
"unit": "<string>"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({sql_query: '<string>', aggregation_method: '<string>', unit: '<string>'})
};
fetch('https://api.coval.dev/v1/metrics/sql:test', 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.coval.dev/v1/metrics/sql:test",
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([
'sql_query' => '<string>',
'aggregation_method' => '<string>',
'unit' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$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.coval.dev/v1/metrics/sql:test"
payload := strings.NewReader("{\n \"sql_query\": \"<string>\",\n \"aggregation_method\": \"<string>\",\n \"unit\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<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.coval.dev/v1/metrics/sql:test")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"sql_query\": \"<string>\",\n \"aggregation_method\": \"<string>\",\n \"unit\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.coval.dev/v1/metrics/sql:test")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"sql_query\": \"<string>\",\n \"aggregation_method\": \"<string>\",\n \"unit\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"value": 123,
"unit": "<string>",
"aggregation_method": "<string>",
"row_count": 123,
"subvalues": [
{
"start_offset_seconds": 123,
"end_offset_seconds": 123,
"value": 123
}
],
"error": "<string>"
}{
"error": {
"code": "INVALID_ARGUMENT",
"message": "<string>",
"details": [
{
"field": "<string>",
"description": "<string>"
}
]
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "Authentication failed",
"details": [
{
"field": "X-API-Key",
"description": "Invalid or missing API key"
}
]
}
}{
"error": {
"code": "INVALID_ARGUMENT",
"message": "<string>",
"details": [
{
"field": "<string>",
"description": "<string>"
}
]
}
}{
"error": {
"code": "INTERNAL",
"message": "Internal server error"
}
}{
"error": {
"code": "INTERNAL",
"message": "Service temporarily unavailable",
"details": [
{
"description": "Database routing is temporarily unavailable. Please retry."
}
]
}
}Test a draft SQL metric query
Run a draft SQL Float metric query against a fixed sample SimulationDataFrames
artifact and return the value it would produce. This is org-agnostic pure compute —
it never touches your organization’s data — so it needs no metric to exist yet and
makes no changes.
Use GET /v1/metrics/sql-schema to discover the tables, columns, and sample rows
your query runs against. The query must return the columns start_offset_milliseconds
and value.
Routine authoring failures (invalid SQL, no matching rows) return 200 with a
populated error field rather than an HTTP error; only a malformed request body is a
400.
curl --request POST \
--url https://api.coval.dev/v1/metrics/sql:test \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"sql_query": "<string>",
"aggregation_method": "<string>",
"unit": "<string>"
}
'import requests
url = "https://api.coval.dev/v1/metrics/sql:test"
payload = {
"sql_query": "<string>",
"aggregation_method": "<string>",
"unit": "<string>"
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({sql_query: '<string>', aggregation_method: '<string>', unit: '<string>'})
};
fetch('https://api.coval.dev/v1/metrics/sql:test', 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.coval.dev/v1/metrics/sql:test",
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([
'sql_query' => '<string>',
'aggregation_method' => '<string>',
'unit' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$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.coval.dev/v1/metrics/sql:test"
payload := strings.NewReader("{\n \"sql_query\": \"<string>\",\n \"aggregation_method\": \"<string>\",\n \"unit\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<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.coval.dev/v1/metrics/sql:test")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"sql_query\": \"<string>\",\n \"aggregation_method\": \"<string>\",\n \"unit\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.coval.dev/v1/metrics/sql:test")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"sql_query\": \"<string>\",\n \"aggregation_method\": \"<string>\",\n \"unit\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"value": 123,
"unit": "<string>",
"aggregation_method": "<string>",
"row_count": 123,
"subvalues": [
{
"start_offset_seconds": 123,
"end_offset_seconds": 123,
"value": 123
}
],
"error": "<string>"
}{
"error": {
"code": "INVALID_ARGUMENT",
"message": "<string>",
"details": [
{
"field": "<string>",
"description": "<string>"
}
]
}
}{
"error": {
"code": "UNAUTHENTICATED",
"message": "Authentication failed",
"details": [
{
"field": "X-API-Key",
"description": "Invalid or missing API key"
}
]
}
}{
"error": {
"code": "INVALID_ARGUMENT",
"message": "<string>",
"details": [
{
"field": "<string>",
"description": "<string>"
}
]
}
}{
"error": {
"code": "INTERNAL",
"message": "Internal server error"
}
}{
"error": {
"code": "INTERNAL",
"message": "Service temporarily unavailable",
"details": [
{
"description": "Database routing is temporarily unavailable. Please retry."
}
]
}
}Authorizations
API key for authentication
Body
Response
Query evaluated (check error for authoring failures)
The aggregated metric value, or null when the query produced no value.
Number of rows the query returned against the sample data.
Show child attributes
Show child attributes
Set when the query could not be evaluated (invalid SQL, missing columns, or no matching rows). Present on a 200 response — routine authoring failures are not HTTP errors.
Was this page helpful?