curl --request POST \
--url https://api.select.dev/v2/budgets/{budget_id}/actions/evaluate \
--header 'Authorization: Bearer <token>' \
--header 'x-tenant-id: <x-tenant-id>'import requests
url = "https://api.select.dev/v2/budgets/{budget_id}/actions/evaluate"
headers = {
"x-tenant-id": "<x-tenant-id>",
"Authorization": "Bearer <token>"
}
response = requests.post(url, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-tenant-id': '<x-tenant-id>', Authorization: 'Bearer <token>'}
};
fetch('https://api.select.dev/v2/budgets/{budget_id}/actions/evaluate', 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.select.dev/v2/budgets/{budget_id}/actions/evaluate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"x-tenant-id: <x-tenant-id>"
],
]);
$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://api.select.dev/v2/budgets/{budget_id}/actions/evaluate"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("x-tenant-id", "<x-tenant-id>")
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.post("https://api.select.dev/v2/budgets/{budget_id}/actions/evaluate")
.header("x-tenant-id", "<x-tenant-id>")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.select.dev/v2/budgets/{budget_id}/actions/evaluate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-tenant-id"] = '<x-tenant-id>'
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"budget_id": "<string>",
"period_start": "2023-12-25",
"period_end": "2023-12-25",
"spend": 123,
"forecast": 123,
"forecast_diff": 123
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}Evaluate a budget's spend now
Measures the budget against the warehouse now and stores the result, rather than waiting for the daily refresh, then returns the summary it wrote. The one budget operation that runs a warehouse query, so it is slower than a read and costs warehouse time — call it when a budget has just been created or changed, not to poll. Returns 409 if the budget changed while it was being measured. Requires budgets:write.
curl --request POST \
--url https://api.select.dev/v2/budgets/{budget_id}/actions/evaluate \
--header 'Authorization: Bearer <token>' \
--header 'x-tenant-id: <x-tenant-id>'import requests
url = "https://api.select.dev/v2/budgets/{budget_id}/actions/evaluate"
headers = {
"x-tenant-id": "<x-tenant-id>",
"Authorization": "Bearer <token>"
}
response = requests.post(url, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-tenant-id': '<x-tenant-id>', Authorization: 'Bearer <token>'}
};
fetch('https://api.select.dev/v2/budgets/{budget_id}/actions/evaluate', 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.select.dev/v2/budgets/{budget_id}/actions/evaluate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"x-tenant-id: <x-tenant-id>"
],
]);
$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://api.select.dev/v2/budgets/{budget_id}/actions/evaluate"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("x-tenant-id", "<x-tenant-id>")
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.post("https://api.select.dev/v2/budgets/{budget_id}/actions/evaluate")
.header("x-tenant-id", "<x-tenant-id>")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.select.dev/v2/budgets/{budget_id}/actions/evaluate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-tenant-id"] = '<x-tenant-id>'
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"budget_id": "<string>",
"period_start": "2023-12-25",
"period_end": "2023-12-25",
"spend": 123,
"forecast": 123,
"forecast_diff": 123
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}{
"title": "<string>",
"status": 123,
"detail": "<string>",
"code": "<string>",
"retryable": true,
"type": "about:blank",
"details": [
{}
]
}Authorizations
Organization API key (sl_…).
Headers
The organization ID the request is scoped to.
Path Parameters
Response
Successful Response
What a budget has spent so far this period, and where it is heading.
Refreshed once a day, on the same cadence as the budget's status. Only days
that have finished loading count toward spend, and a day only finishes once,
so these figures step forward daily rather than continuously. Null until the
first refresh after the budget is created — evaluate the budget to fill them in
without waiting for the next one.
The budget this summary is for.
The first day of the period these figures cover.
The last day of the period these figures cover.
Spend so far in the current period, counting only days that have finished loading. Null before the budget's first refresh.
Projected total spend by the end of the current period, extrapolated from the budget's recent daily spend. Null before the first refresh, when there is too little history to project from, or once the period has ended.
How far forecast lands from the budget's threshold, as a percentage of it — positive over, negative under. Null when there is no forecast, or the threshold is zero.

