POST
/countEstimate tokens and cost for a piece of text
Estimates the input token count for the supplied text and prices it against the chosen model.
Pass outputTokens to include the expected completion in the cost. The response reports context-window usage and whether the request would fit. Defaults to claude-sonnet-4 when no model is given.
$0.0002 per call300 req/minFree allowance applies
Request
curl -X POST "https://www.twotic.dev/v1/token-counter/count" \
-H "Authorization: Bearer $TWOTIC_KEY" \
-H "Content-Type: application/json" \
-d '{ "text": "Summarise the following support transcript…", "model": "claude-sonnet-4", "outputTokens": 500 }'const res = await fetch("https://www.twotic.dev/v1/token-counter/count", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.TWOTIC_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"text": "Summarise the following support transcript…",
"model": "claude-sonnet-4",
"outputTokens": 500
}),
})
if (!res.ok) throw new Error(await res.text())
const data = await res.json()
console.log(res.headers.get("X-Twotic-Cost"))import os, requests
res = requests.post(
"https://www.twotic.dev/v1/token-counter/count",
headers={"Authorization": f"Bearer {os.environ['TWOTIC_KEY']}"},
json={
"text": "Summarise the following support transcript…",
"model": "claude-sonnet-4",
"outputTokens": 500
},
)
res.raise_for_status()
data = res.json()
print(res.headers["X-Twotic-Cost"])package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
body := strings.NewReader(`{ "text": "Summarise the following support transcript…", "model": "claude-sonnet-4", "outputTokens": 500 }`)
req, _ := http.NewRequest("POST", "https://www.twotic.dev/v1/token-counter/count", body)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+os.Getenv("TWOTIC_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(string(out))
fmt.Println(res.Header.Get("X-Twotic-Cost"))
}<?php
$ch = curl_init("https://www.twotic.dev/v1/token-counter/count");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("TWOTIC_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => '{ "text": "Summarise the following support transcript…", "model": "claude-sonnet-4", "outputTokens": 500 }',
]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($data);require "net/http"
require "json"
uri = URI("https://www.twotic.dev/v1/token-counter/count")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch('TWOTIC_KEY')}"
req["Content-Type"] = "application/json"
req.body = {
"text": "Summarise the following support transcript…",
"model": "claude-sonnet-4",
"outputTokens": 500
}.to_json
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") do |http|
http.request(req)
end
puts JSON.parse(res.body)
puts res["X-Twotic-Cost"]{
"mcpServers": {
"token-counter": {
"type": "http",
"url": "https://www.twotic.dev/api/mcp/token-counter",
"headers": { "Authorization": "Bearer tk_live_your_key" }
}
}
}Request body
application/json · required
{
"text": "Summarise the following support transcript…",
"model": "claude-sonnet-4",
"outputTokens": 500
}Response
200The token estimate and cost breakdown.
{
"cost": {
"input": 0.003852,
"total": 0.011352,
"output": 0.0075,
"currency": "USD"
},
"model": "claude-sonnet-4",
"words": 812,
"characters": 5136,
"approximate": true,
"inputTokens": 1284,
"totalTokens": 1784,
"outputTokens": 500,
"contextWindow": 200000,
"fitsInContext": true,
"pricesUpdated": "2026-08-01",
"contextUsedPercent": 0.89
}400The text is missing or the model is unknown.
{
"error": "unknown_model",
"message": "Unknown model \"gpt-9\". Call GET /models for the supported list."
}As an agent tool
Connect https://www.twotic.dev/api/mcp/token-counter and this endpoint is exposed as the tool token-counter_count.
Estimate the token count and dollar cost of a piece of text for a specific LLM, and check whether it fits that model's context window. Choose this before sending a large prompt, when deciding between models on price, or when showing a user what a request will cost. Send {"text": "...", "model": "...", "outputTokens": n}. Results are approximate and marked as such.