curl --request GET \
--url https://api.closebot.com/agency/billing/ai-cost-breakdown \
--header 'X-CB-KEY: <api-key>'import requests
url = "https://api.closebot.com/agency/billing/ai-cost-breakdown"
headers = {"X-CB-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-CB-KEY': '<api-key>'}};
fetch('https://api.closebot.com/agency/billing/ai-cost-breakdown', 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.closebot.com/agency/billing/ai-cost-breakdown",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-CB-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"
"net/http"
"io"
)
func main() {
url := "https://api.closebot.com/agency/billing/ai-cost-breakdown"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-CB-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.closebot.com/agency/billing/ai-cost-breakdown")
.header("X-CB-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.closebot.com/agency/billing/ai-cost-breakdown")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-CB-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"startTime": "2023-11-07T05:31:56Z",
"endTime": "2023-11-07T05:31:56Z",
"standard": {
"calls": 123
},
"metered": {
"calls": 123,
"segments": 123,
"shares": {
"globalPromptBase": 123,
"nodePrompting": 123,
"toolDescriptions": 123,
"knowledgeBase": 123,
"toolCallResults": 123,
"conversationHistory": 123,
"responseFormat": 123,
"thinking": 123,
"toolCallsEmitted": 123,
"message": 123
},
"tools": [
{
"apiName": "<string>",
"displayName": "<string>",
"isCustom": true,
"share": 123
}
]
}
}AI cost breakdown for a period
Splits the period’s AI spend by what drove it — global prompt base, node instructions, tool descriptions, knowledge base, tool results, conversation history, response format, thinking, emitted tool calls and the reply itself.
Injected variable values are costed against the section they were injected into rather than broken out separately, so the same substitution cannot appear under both the agent node and the global prompt area.
The response separates flat-rate (“standard”) traffic from cost-based (“metered”) traffic. Only the metered block carries shares and segments; multiply the shares by the metered portion of the invoice to get dollars. Standard traffic is billed at a fixed per-message rate, so it is reported as a call count alone — its real cost composition is captured internally but deliberately never emitted, because it would describe money the customer did not pay.
curl --request GET \
--url https://api.closebot.com/agency/billing/ai-cost-breakdown \
--header 'X-CB-KEY: <api-key>'import requests
url = "https://api.closebot.com/agency/billing/ai-cost-breakdown"
headers = {"X-CB-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-CB-KEY': '<api-key>'}};
fetch('https://api.closebot.com/agency/billing/ai-cost-breakdown', 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.closebot.com/agency/billing/ai-cost-breakdown",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-CB-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"
"net/http"
"io"
)
func main() {
url := "https://api.closebot.com/agency/billing/ai-cost-breakdown"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-CB-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.closebot.com/agency/billing/ai-cost-breakdown")
.header("X-CB-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.closebot.com/agency/billing/ai-cost-breakdown")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-CB-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"startTime": "2023-11-07T05:31:56Z",
"endTime": "2023-11-07T05:31:56Z",
"standard": {
"calls": 123
},
"metered": {
"calls": 123,
"segments": 123,
"shares": {
"globalPromptBase": 123,
"nodePrompting": 123,
"toolDescriptions": 123,
"knowledgeBase": 123,
"toolCallResults": 123,
"conversationHistory": 123,
"responseFormat": 123,
"thinking": 123,
"toolCallsEmitted": 123,
"message": 123
},
"tools": [
{
"apiName": "<string>",
"displayName": "<string>",
"isCustom": true,
"share": 123
}
]
}
}
