On 21 August 2026, a model called Ox Alpha appeared on OpenRouter under a "Stealth" banner. No lab claimed it. No benchmarks preceded it. The page said only: "developed and operated by a third-party model provider."
The timeline lit up with guesses. Google Gemini? xAI Grok? A new Chinese lab? Every hot take lived and died in a single reply — one person compared token counts, another parsed error codes, someone else sent temperature 2.0 and watched what came back. Each trick worked once in isolation. Nobody had the full picture.
modelprint changed that. One page, nine probes, a few API calls, and the mystery collapsed: Ox Alpha is Z.AI's GLM-5.3. The tokenizers matched, the error codes matched, the template offset matched. Every probe independently confirmed the fingerprint.
I cloned the source, ran the tests, and read every probe. Here's what I found.
What modelprint Does
One question: who is really behind that API? modelprint is a single-page browser app (try it live) that runs infrastructure probes against any OpenAI-compatible endpoint and compares fingerprints side-by-side. No install. No server. Your API keys stay in your browser tab.
The key insight: plumbing does not lie; personality does. A model's system prompt can be swapped. Its censorship patterns can be tuned. But its tokenizer, its error format, its serving stack — those are infrastructure. They're hard to fake.
graph TD
A[Your API Key] --> B{modelprint}
B --> C[Tokenizer Probes
4 texts × ping-pong stability]
B --> D[Error Probes
temperature 2.0, max_tokens 10^9]
B --> E[Shape Probes
template offset, finish vocab]
B --> F[Network Forensics
headers, region, generation ledger]
B --> G[Capability Probes
context ceiling, cutoff dating]
C --> H[Normalized fingerprint]
D --> H
E --> H
F --> H
G --> H
H --> I[Compare against known models]
I --> J[Who is really behind it]
The Probes
Fourteen probes organized into six groups. Each returns a value that identifies a lab. I ran the self-test suite locally to confirm every one works:
cd /tmp/modelprint
node selftest.mjs
Output, all 28 runs green:
selftest: 14 registry entries
tok-english ok (rich) 100
tok-english ok (mini) 100
tok-chinese ok (rich) 45
tok-chinese ok (mini) 45
tok-code ok (rich) 116
tok-code ok (mini) 116
tok-emoji ok (rich) 33
tok-emoji ok (mini) 33
template-offset ok (rich) +8 (delta 7)
template-offset ok (mini) +8 (delta 7)
err-temperature ok (rich) temperature must be in [0, 2) · code 1301
err-temperature ok (mini) temperature must be in [0, 2) · code 1301
err-maxtokens ok (rich) accepted 10^9 (silently capped)
err-maxtokens ok (mini) accepted 10^9 (silently capped)
err-code-family ok (rich) numeric-code
err-code-family ok (mini) numeric-code
finish-vocab ok (rich) stop · stop
finish-vocab ok (mini) stop · stop
net-region ok (rich) iad · Z.AI · direct
net-region ok (mini) no-router-metadata
net-genrecord ok (rich) Z.AI · global · stop
net-genrecord ok (mini) harness-lacks-http
net-headerdna ok (rich) cf-ray · oai-ver:2020-10-01 · ...
net-headerdna ok (mini) headers-hidden-by-cors
cap-contextceiling ok (rich) >64k ≤128k
cap-contextceiling ok (mini) >64k ≤128k
lp-geometry ok (rich) δ=0.33 · span=0.00 · k=10
lp-geometry ok (mini) logprobs-unsupported
all green across 28 runs
The "rich" run uses a real OpenRouter key; "mini" uses a mock harness. Every probe passes both. The ones that caught Ox Alpha were the tokenizer group — specifically the normalized counts against a one-character baseline that cancels out any serving template.
Why the Tokenizer Probes Are the Smoking Gun
Each tokenizer probe sends a pinned text (English pangram, Chinese paragraph, code snippet, emoji set) and reads usage.prompt_tokens. It normalizes by subtracting a one-character baseline, which eliminates the host's hidden template. Then it runs the same text twice — if the counts differ, a router is spreading calls across hosts and the result is marked "unstable."
Here's the contract from the English pangram probe:
const TEXT = "The quick brown fox jumps over the lazy dog while packing my box "
+ "with five dozen liquor jugs; sphinx of black quartz, judge my vow. "
+ "Amazingly few discotheques provide jukeboxes, yet vexed zombies quip.";
export async function probe(ctx) {
const a = await ctx.chat({ messages: [{ role: "user", content: TEXT }], max_tokens: 1 });
const b = await ctx.chat({ messages: [{ role: "user", content: TEXT }], max_tokens: 1 });
const base = await ctx.chat({ messages: [{ role: "user", content: "a" }], max_tokens: 1 });
// ... normalize and check stability
const norm = a.usage.prompt_tokens - base.usage.prompt_tokens;
return { value: norm };
}
The result is a single integer per text — the lab's tokenizer signature. Two hosts wrapping the same tokenizer match; raw counts would never.
What It Found on Day One
The full suspect lineup, 12 models, 9 probes each:
mystery model (stealth/ox-alpha) against the crowd's guesses:
6/9 tokenizer 4/4 z-ai/glm-5.3 ← THIS IS IT
5/9 tokenizer 4/4 z-ai/glm-4.7-flash
2/9 tokenizer 2/4 openai/gpt-5.6-luna
2/9 tokenizer 1/4 qwen/qwen3.7-flash
2/9 tokenizer 0/4 kimi-k3, deepseek-v4-flash, minimax-m3
1/9 tokenizer 0/4 google/gemini-3.7-flash
0/9 tokenizer 0/4 x-ai/grok-4.6, claude-opus-5
Only the GLM family matched all four tokenizer probes. Every other lab's best was 2 of 4. Then the error probe sealed it — error code 1301 on a temperature 2.0 request. That's GLM's specific numeric error format. No other API returns that code.
One More Thing: DeepSeek's Swap
The README mentions this casually, but it's worth sitting with: two days before Ox Alpha appeared, the same author showed that DeepSeek's API silently serves a different model under the old deepseek-chat alias. No announcement. No deprecation notice. Just a model swap behind a stable name.
This is not theoretical. If you're hitting deepseek-chat and evaluating it against a baseline from three weeks ago, you're comparing against a model you never agreed to evaluate. Your benchmarks shifted under you without consent.
Opinion: Why This Matters
Two things are happening here, and neither is getting enough attention.
First: stealth models. Ox Alpha was a deliberate test — a model released without attribution to see if the community could identify it. That's a fun game, but the same infrastructure could serve something worse. A model with poisoned weights, a model trained on copyrighted data that the provider wants to launder through a front, a model with different safety guardrails. The OpenRouter listing for Ox Alpha says "prompts and completions are retained by the provider and are not used for training" — but who is the provider? You don't know. The page doesn't say.
Second: silent model swaps. DeepSeek's deepseek-chat swap is the more insidious problem because it affects everyone, not just people chasing mysteries. Every production system that pins a model name but not a version is one no-notice swap away from an undiagnosed regression. And the default behavior of most API clients is to trust the name.
modelprint doesn't solve either problem, but it gives you the tool to detect them. That's more than anyone else has shipped.
Bottom Line
modelprint is the kind of tool I wish didn't need to exist — a debugger for a trust failure in the API ecosystem. But it does need to exist, and unclecode built it well. The probes are elegant (normalized tokenizer counts, error code fingerprinting, template offset detection), the architecture is clean (browser-side, no server, honest degradation), and it has already produced real results on day one.
If you rely on LLM APIs for anything production-critical, run modelprint against your providers today. If nothing else, you'll confirm that the model you're paying for is the model you're calling. And if it isn't, you'll have evidence.
- modelprint — Who is really behind that API? — unclecode, GitHub, 21 Aug 2026
- Ox Alpha — Stealth Model on OpenRouter — OpenRouter, 20 Aug 2026
- Ox Alpha HN Discussion (235 points) — Hacker News, 20 Aug 2026
- modelprint Live Demo — unclecode, 21 Aug 2026
- Crawl4AI — unclecode's previous project (10k+ ★) — GitHub