{"openapi":"3.1.0","info":{"title":"TokenTally by Harlo","version":"0.1.0","description":"TokenTally counts tokens for text across o200k_base and cl100k_base side by side, truncates text to a token budget, chunks text for RAG on paragraph/sentence boundaries with offsets, and estimates cost per model. OpenAI counts (o200k_base, cl100k_base) are exact for those tokenizers. Claude, Gemini and Llama counts are APPROXIMATE (proxy encoding; real tokenizers differ, often by 10-20%, and newer Claude tokenizers by ~30% or more). Cost estimates use a dated price table (prices_as_of 2026-10-27) and are estimates, not live billing. Stateless: text is not stored or logged; no URL fetching. Max input is 256 KB. A single unbroken run of characters near that cap may hit a CPU timeout (503); normal text at the cap is supported. Plans: Free $0/mo · 2,000 calls/mo; BASIC $9/mo · 50,000 calls/mo; PRO $15/mo · 250,000 calls/mo.","contact":{"name":"Harlo","email":"digitalpromohub.support@gmail.com"}},"servers":[{"url":"https://tokentally.mike-tusa.workers.dev"}],"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"x-api-key"},"bearer":{"type":"http","scheme":"bearer"}}},"paths":{"/v1/count":{"post":{"operationId":"count","summary":"Count tokens for text in o200k_base and cl100k_base side by side, plus approximate Claude/Gemini/Llama counts with method notes","description":"Count tokens for text in o200k_base and cl100k_base side by side, plus approximate Claude/Gemini/Llama counts with method notes. OpenAI counts (o200k_base, cl100k_base) are exact for those tokenizers. Claude, Gemini and Llama counts are APPROXIMATE (proxy encoding; real tokenizers differ, often by 10-20%, and newer Claude tokenizers by ~30% or more). Cost estimates use a dated price table (prices_as_of 2026-10-27) and are estimates, not live billing. Stateless: text is not stored or logged; no URL fetching. Max input is 256 KB. A single unbroken run of characters near that cap may hit a CPU timeout (503); normal text at the cap is supported.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","description":"Text (≤256 KB). URLs are not fetched."}},"required":["text"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Invalid API key"},"413":{"description":"Body too large"},"429":{"description":"Rate limited"}}}},"/v1/truncate":{"post":{"operationId":"truncate","summary":"Truncate text to max_tokens (keep start or end) for an encoding or model.","description":"Truncate text to max_tokens (keep start or end) for an encoding or model.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","description":"Text (≤256 KB). URLs are not fetched."},"max_tokens":{"type":"integer"},"keep":{"type":"string","enum":["start","end"]},"encoding":{"type":"string","enum":["o200k_base","cl100k_base"]},"model":{"type":"string"}},"required":["text","max_tokens"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Invalid API key"},"413":{"description":"Body too large"},"429":{"description":"Rate limited"}}}},"/v1/chunk":{"post":{"operationId":"chunk","summary":"Split text into token-bounded chunks on paragraph/sentence boundaries with character offsets, token counts and optional overlap.","description":"Split text into token-bounded chunks on paragraph/sentence boundaries with character offsets, token counts and optional overlap.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","description":"Text (≤256 KB). URLs are not fetched."},"chunk_tokens":{"type":"integer"},"overlap_tokens":{"type":"integer"},"encoding":{"type":"string","enum":["o200k_base","cl100k_base"]},"model":{"type":"string"}},"required":["text"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Invalid API key"},"413":{"description":"Body too large"},"429":{"description":"Rate limited"}}}},"/v1/estimate":{"post":{"operationId":"estimate","summary":"Estimate USD cost per model from text or input_tokens plus output_tokens using a dated price table (prices_as_of 2026-10-27)","description":"Estimate USD cost per model from text or input_tokens plus output_tokens using a dated price table (prices_as_of 2026-10-27). Estimates, not live billing.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","description":"Text (≤256 KB). URLs are not fetched."},"input_tokens":{"type":"integer"},"output_tokens":{"type":"integer"},"models":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Invalid API key"},"413":{"description":"Body too large"},"429":{"description":"Rate limited"}}}},"/v1/encodings":{"get":{"operationId":"encodings","summary":"encodings endpoint.","description":"encodings endpoint.","responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Invalid API key"},"413":{"description":"Body too large"},"429":{"description":"Rate limited"}}}}}}