curl --request POST \
--url https://pria.praxislxp.com/api/admin/histories/charts/tools \
--header 'Content-Type: application/json' \
--header 'x-access-token: <api-key>' \
--data '
{
"view": "tools",
"lane": "all",
"model": "<string>",
"institution": "<string>",
"account": "<string>",
"daterange": [
"2023-12-25"
],
"top": 200
}
'import requests
url = "https://pria.praxislxp.com/api/admin/histories/charts/tools"
payload = {
"view": "tools",
"lane": "all",
"model": "<string>",
"institution": "<string>",
"account": "<string>",
"daterange": ["2023-12-25"],
"top": 200
}
headers = {
"x-access-token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-access-token': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
view: 'tools',
lane: 'all',
model: '<string>',
institution: '<string>',
account: '<string>',
daterange: ['2023-12-25'],
top: 200
})
};
fetch('https://pria.praxislxp.com/api/admin/histories/charts/tools', 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://pria.praxislxp.com/api/admin/histories/charts/tools",
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([
'view' => 'tools',
'lane' => 'all',
'model' => '<string>',
'institution' => '<string>',
'account' => '<string>',
'daterange' => [
'2023-12-25'
],
'top' => 200
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-access-token: <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://pria.praxislxp.com/api/admin/histories/charts/tools"
payload := strings.NewReader("{\n \"view\": \"tools\",\n \"lane\": \"all\",\n \"model\": \"<string>\",\n \"institution\": \"<string>\",\n \"account\": \"<string>\",\n \"daterange\": [\n \"2023-12-25\"\n ],\n \"top\": 200\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-access-token", "<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://pria.praxislxp.com/api/admin/histories/charts/tools")
.header("x-access-token", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"view\": \"tools\",\n \"lane\": \"all\",\n \"model\": \"<string>\",\n \"institution\": \"<string>\",\n \"account\": \"<string>\",\n \"daterange\": [\n \"2023-12-25\"\n ],\n \"top\": 200\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://pria.praxislxp.com/api/admin/histories/charts/tools")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-access-token"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"view\": \"tools\",\n \"lane\": \"all\",\n \"model\": \"<string>\",\n \"institution\": \"<string>\",\n \"account\": \"<string>\",\n \"daterange\": [\n \"2023-12-25\"\n ],\n \"top\": 200\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"view": "<string>",
"lane": "<string>",
"model": "<string>",
"window": {
"start": "2023-11-07T05:31:56Z",
"end": "2023-11-07T05:31:56Z",
"days": 123
},
"turnMarkerSince": "2023-12-25",
"truncated": true,
"warnings": [
"<string>"
],
"rows": [
{}
]
}
}Get tool usage and prompt cache census
Aggregate-only census of tool usage and prompt-cache behaviour over conversation history. The response carries tool names, model names, lane names, bucket labels and counts. It never carries a user id, a Digital Twin id, a conversation id, a question or an answer. Distinct users and twins are returned as counts. One request runs one bounded view. The window is at most 31 days (a wider window is rejected, never clamped) and defaults to the last 7 days. Results are cached. An administrator of one Digital Twin only ever sees that twin. Only real turns are counted - rows stamped by the turn save path (every saved turn since 2026-09-10) plus avatar embed sessions. Uploads, sign-in events and other non-turn history rows are left out. A window that starts before 2026-09-10 is answered with a warning, because older turns carry no marker. Lanes - qanda is a single-shot text turn, convo is one Convo Mode (realtime) or avatar embed session per row, agentic is a turn that ran a conductor, background workers or a plan execution (its tools are the conductor’s own), and workers (tools view only) counts the tools that the background workers of a turn ran. A tool that appears only under workers is never called by a single-shot turn. Labels are vetted - a tool label is a platform tool name, mcp_bridged or other, and a model label that does not look like a model name is returned as other. Tools reached through an MCP connector are counted together as mcp_bridged, because their stored name carries the connector label chosen by the customer. The twins count treats the personal scope (no twin) as one twin. Approximations - sameSlotTurns counts turns that share a clock-aligned five-minute slot with an earlier turn of the same conversation, which is a lower bound on follow-ups that land inside a five-minute prompt cache. A conversation is a user, a twin and a course_id, and a row without course_id counts as its own conversation.
curl --request POST \
--url https://pria.praxislxp.com/api/admin/histories/charts/tools \
--header 'Content-Type: application/json' \
--header 'x-access-token: <api-key>' \
--data '
{
"view": "tools",
"lane": "all",
"model": "<string>",
"institution": "<string>",
"account": "<string>",
"daterange": [
"2023-12-25"
],
"top": 200
}
'import requests
url = "https://pria.praxislxp.com/api/admin/histories/charts/tools"
payload = {
"view": "tools",
"lane": "all",
"model": "<string>",
"institution": "<string>",
"account": "<string>",
"daterange": ["2023-12-25"],
"top": 200
}
headers = {
"x-access-token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-access-token': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
view: 'tools',
lane: 'all',
model: '<string>',
institution: '<string>',
account: '<string>',
daterange: ['2023-12-25'],
top: 200
})
};
fetch('https://pria.praxislxp.com/api/admin/histories/charts/tools', 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://pria.praxislxp.com/api/admin/histories/charts/tools",
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([
'view' => 'tools',
'lane' => 'all',
'model' => '<string>',
'institution' => '<string>',
'account' => '<string>',
'daterange' => [
'2023-12-25'
],
'top' => 200
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-access-token: <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://pria.praxislxp.com/api/admin/histories/charts/tools"
payload := strings.NewReader("{\n \"view\": \"tools\",\n \"lane\": \"all\",\n \"model\": \"<string>\",\n \"institution\": \"<string>\",\n \"account\": \"<string>\",\n \"daterange\": [\n \"2023-12-25\"\n ],\n \"top\": 200\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-access-token", "<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://pria.praxislxp.com/api/admin/histories/charts/tools")
.header("x-access-token", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"view\": \"tools\",\n \"lane\": \"all\",\n \"model\": \"<string>\",\n \"institution\": \"<string>\",\n \"account\": \"<string>\",\n \"daterange\": [\n \"2023-12-25\"\n ],\n \"top\": 200\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://pria.praxislxp.com/api/admin/histories/charts/tools")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-access-token"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"view\": \"tools\",\n \"lane\": \"all\",\n \"model\": \"<string>\",\n \"institution\": \"<string>\",\n \"account\": \"<string>\",\n \"daterange\": [\n \"2023-12-25\"\n ],\n \"top\": 200\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"view": "<string>",
"lane": "<string>",
"model": "<string>",
"window": {
"start": "2023-11-07T05:31:56Z",
"end": "2023-11-07T05:31:56Z",
"days": 123
},
"turnMarkerSince": "2023-12-25",
"truncated": true,
"warnings": [
"<string>"
],
"rows": [
{}
]
}
}Authorizations
JWT token passed in x-access-token header
Body
tools - calls, turns, successes, MCP calls, distinct users and twins per tool and lane. turns - how many turns make 0, 1, 2, 3, 4 or 5+ tool calls per lane, with token sums. models - turns, turns with tools, cold turns, cache reads and writes per model and lane. conversations - conversation size buckets, tool use, first tool use, and distinct tools per tool-using conversation (text lanes only).
tools, turns, models, conversations Restrict to one lane. The conversations view does not accept convo. The workers lane exists only in the tools view. In the tools view, all returns the turn-level rows and the workers rows.
all, qanda, convo, agentic, workers Exact conversation model name to restrict to
200Space-separated institution IDs to filter (institution is the API word for a Digital Twin). Must be a string - any other type is rejected.
Space-separated account IDs to filter. Must be a string.
Start and end day, inclusive, in UTC. At most 31 days. Defaults to the last 7 days.
2 elementsMaximum rows for the tools view, ordered by calls
1 <= x <= 500Was this page helpful?