Pre-release, the API is not public yet
Compress the JSON before it reaches the model.
Tokendoo is a lossless structural codec for JSON on its way to an LLM, running at the edge. The original value is exactly recoverable, enforced by property-based tests over 1,000+ generated cases, not promised in a policy.
median wire token ratio, shipping fixtures, shipped defaults
Wire ratio: compressed payload alone. Format legend costs 97 to 174 tokens and can erase the gain on small payloads.
published synthetic corpus · exact cl100k_base counts · 2026-08-06
01 / The problem
Structured payloads pay a structure tax.
A 1,000-row JSON array states its keys 1,000 times. Braces, quotes, field names, repeated string values: the API bills every one of them, on every request, at per-token prices.
Prose carries meaning; structure mostly carries itself. Repetition is the one part of a payload that can be removed and put back exactly, so it is the only part Tokendoo touches.
02 / How it works
Four transforms, in order.
Each one is structural and reversible, and each is kept only when it makes the payload smaller. When nothing helps, the codec emits the input unchanged and says so in the header.
Canonicalisation
Whitespace dropped, keys sorted, numbers normalised. Deterministic input for every step after it.
{ "sku": "a-114", "qty": 2 }{"qty":2,"sku":"a-114"}Key dictionary, off by default
Repeated keys become base-36 ordinals plus a table. On the shipping corpus it failed the ≥10% token-gain bar, so it ships off until it earns its place.
{"quantity":2,"status":"active"}{"0":2,"1":"active"} k:["quantity","status"]Tabular collapse
An array of same-shape objects becomes one schema row plus value rows. Keys are stated once instead of once per record.
[{"qty":2,"sku":"a-114"},
{"qty":1,"sku":"a-115"}]["__T",["qty","sku"], [[2,"a-114"],[1,"a-115"]]]
Value interning
String values repeated across the payload move into a table and are referenced by ordinal. The table ships with the output, and every figure on this page counts it.
"eu-west-1" × 40
"0" × 40 v:["eu-west-1"]
The result is a T2 wire string, T246:…, plus a JSON dictionary. Both parts are counted in every ratio; quoting savings without the dictionary would overstate them.
03 / Live example
Three payloads, compressed in your browser.
There is no paste box, on purpose. A page that collected payloads to demonstrate a product built on not collecting payloads would refute itself. These three fixtures ship with the page; nothing here leaves your tab.
token ratio, this payload
Input
/_nuxt/homogeneous_100.C1heiKFQ.txt
04 / Measurements
The table we make decisions with.
Exact cl100k_base counts on a synthetic, published corpus, benched 2026-08-06 with the shipped defaults: tabular collapse and value interning on, key dictionary off. Every after-count includes the dictionary.
| fixture | what it is | tokens in | tokens out | token ratio | byte ratio |
|---|---|---|---|---|---|
homogeneous_100 | 100 records, one schema | 2 903 | 1 327 | 0.457 | 0.321 |
homogeneous_1000 | 1,000 records, one schema | 29 003 | 9 427 | 0.325 | 0.242 |
realistic_api | mixed API response | 3 200 | 2 789 | 0.872 | 0.791 |
size_10k | ≈10 KB mixed payload | 3 860 | 1 624 | 0.421 | 0.299 |
size_100k | ≈100 KB mixed payload | 39 983 | 13 087 | 0.327 | 0.242 |
size_250k | ≈250 KB mixed payload | 98 603 | 32 627 | 0.331 | 0.242 |
prose_heavy | long text values, thin structure | 2 965 | 2 975 | 1.003 | 1.001 |
shipping fixtures, median token ratio 0.421. Corpus and bench code are published in the repository; re-running the bench reproduces every count.
The last row is the case where the tool does nothing: structural compression has no purchase on prose, and prose_heavy comes out 0.3% larger. It stays on this page because a figure you can check is worth more than a figure you would like.
05 / Zero retention
Nothing to leak, by construction.
Request bodies, headers and IP addresses are never logged, cached or stored: there is no code path that could. Error responses carry structural fields only and never echo payload content.
Telemetry is limited to seven anonymous numeric counters:
bytes_beforebytes_aftertokens_beforetokens_aftermodelatency_msstatus
The invariant is enforced by tests that fail the build, not promised in a policy. The privacy notice you are looking for is this section.
06 / Status & roadmap
What ships, what is being measured, what waits.
as of 2026-08-07
Built, pre-release
POST /v1/compressPOST /v1/decompress- Rust compiled to WebAssembly, running on Cloudflare Workers
- JSON mode only; inputs up to 256 KiB
- Lossless round-trip over JSON values, enforced by 1,000+ property-test cases
Being measured now
- Whether a model answers as well on compressed input as on the original. We do not claim it does; that is exactly what is being measured. The harness exists; no model has answered yet.
- The cost of the legend that teaches a model the format: 97 to 174 tokens, enough to erase the gain on small payloads. It is counted, not hidden.
Deferred
- Code mode: a useful one is necessarily lossy, which breaks the round-trip guarantee. It waits until that trade-off can be explicit.
- Text mode: prose sits at ratio 1.003; structural compression has no purchase there.
- Billing and API keys: after the measurements above, not before.
07 / Waitlist
One field, one email, then silence.
The API is not open yet. Leave an address and you will get exactly one email when it is.