curl --request POST \
--url https://api.promptguard.co/api/v1/messages/count_tokens \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.promptguard.co/api/v1/messages/count_tokens"
headers = {"X-API-Key": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.promptguard.co/api/v1/messages/count_tokens', 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.promptguard.co/api/v1/messages/count_tokens",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"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"
"net/http"
"io"
)
func main() {
url := "https://api.promptguard.co/api/v1/messages/count_tokens"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("X-API-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.post("https://api.promptguard.co/api/v1/messages/count_tokens")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.promptguard.co/api/v1/messages/count_tokens")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Proxy Count Tokens
Proxy Anthropic’s token-counting endpoint.
A compatibility gap rather than a security surface: an Anthropic SDK pointed
at PromptGuard breaks on client.messages.count_tokens() because we did not
serve the route. It counts tokens and returns a number — nothing reaches a
model and nothing is generated, so there is no completion to scan.
The request still goes through the same handler as the rest, which means the
prompt IS scanned on the way in. That is deliberate: the body is a full
messages array, so it is a place a caller could otherwise probe or stage
content with no policy applied.
Note this is NOT what enforces max_tokens_per_request. That runs inline on
every request and must not make a network call to do it — see
shared/security/token_limiter.py.
curl --request POST \
--url https://api.promptguard.co/api/v1/messages/count_tokens \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.promptguard.co/api/v1/messages/count_tokens"
headers = {"X-API-Key": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.promptguard.co/api/v1/messages/count_tokens', 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.promptguard.co/api/v1/messages/count_tokens",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"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"
"net/http"
"io"
)
func main() {
url := "https://api.promptguard.co/api/v1/messages/count_tokens"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("X-API-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.post("https://api.promptguard.co/api/v1/messages/count_tokens")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.promptguard.co/api/v1/messages/count_tokens")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}