Skip to content

GLM 5.2 Review: We Tested the API and the Docs Lie

GLM 5.2: What the API Actually Does When You Call It

We called Z.ai asking for GLM-5.2 and got an error, not a model. What really happens, plus an effort-level benchmark on a real TypeScript task.

· · 8 min read

Quick Take

Z.ai shipped GLM-5.2 in June 2026 as an MIT-licensed 753B coding model, and GLM-5.3 replaced it in August. We spent an afternoon on the live API to find out which one you actually get, and three documented behaviours turned out to be wrong.

Quick take: GLM-5.2 is Z.ai's open-weights coding model: 753B parameters, about 40B active per token, MIT licensed, 1M-token context. We tested the live API on 2026-08-27. Asking for glm-5.2 on a pay-as-you-go key returns HTTP 429, not a model, while glm-5.3 answers in two seconds. Reasoning can't be disabled, the error explaining how to tune it names the wrong field, and nine of ten short requests came back empty. The weights, not the API, are where GLM-5.2 still lives.

What Is GLM 5.2?

GLM-5.2 is an open-weights mixture-of-experts model for coding and long-horizon agent work, published by Z.ai (Zhipu AI) under an MIT license with no regional restrictions. It carries 753B total parameters, roughly 40B active per token, a 1,048,576-token context window and a 128K output ceiling.

The models endpoint timestamps it exactly: glm-5.2 carries created: 1781625600, or 2026-06-16 16:00 UTC, midnight in Beijing on June 17. That list runs from glm-4.5 to glm-5.3-flash, so every generation since mid-2025 is still addressable by name.

The architectural piece worth knowing is IndexShare: Z.ai reuses one sparse-attention indexer across every four layers instead of computing a fresh one per layer, cutting per-token FLOPs by 2.9x at 1M context. Attention bookkeeping is what makes long context expensive, so that is the difference between a 1M window you can advertise and one you can bill for.

Does the GLM 5.2 API Still Serve GLM 5.2?

No, and not in the way the coverage suggests either.

GLM-5.3 shipped on 2026-08-14, reuses the GLM-5.2 base model unchanged and takes every reported gain from post-training. The repeated claim is that Z.ai silently routes GLM-5.2 and GLM-5.1 requests to it. So we tried, on a pay-as-you-go key:

curl -s https://api.z.ai/api/paas/v4/chat/completions \
  -H "Authorization: Bearer $ZAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"glm-5.2","messages":[{"role":"user","content":"ping"}]}'
{"error":{"code":"1113","message":"Insufficient balance or no resource package. Please recharge."}}

That is HTTP 429. No silent upgrade, no answer, a billing wall. The same request with glm-5.3 returned HTTP 200 in 2.1 seconds on the same key. Nothing else did: glm-5.1, glm-5, glm-4.7 and even glm-5.3-flash all returned 1113, on the standard endpoint and the coding one alike.

Is 1113 just Z.ai's way of saying "gone"? The control says no. Asking for glm-9.9, an id that never existed, returns HTTP 400 with {"code":"1214","message":"modelCode: does not exist"}. Two errors, two meanings: 1214 is "no such model", 1113 is "real model, no package on your account".

The distinction matters: an alias would let a pinned version drift silently and change your outputs, while this fails loudly. Auto-upgrade behaviour, where it exists, belongs to the Coding Plan rather than to token billing.

Reasoning Cannot Be Turned Off, and the Error Lies

GLM-5.2's model card lists three modes: non-thinking, High, and Max. On 5.3 the first one is gone:

{"error":{"code":"1210","message":"This model always engages in thinking and cannot be disabled; please use low, high, or max"}}

Fair enough, except following that instruction fails too. {"thinking":{"type":"high"}} returns the same 1210 error, because thinking.type is not where effort goes. The working field is the OpenAI-style one at the top level:

{"model":"glm-5.3","reasoning_effort":"high","messages":[{"role":"user","content":"say pong"}]}

An error naming three valid values for a field that accepts none of them is the kind of thing you only find by hitting the endpoint. Budget an hour if you're porting an agent loop across.

The max_tokens Trap

Reasoning tokens come out of the same max_tokens budget as the answer, and they come out first. We sent "Reply with exactly one word: pong" ten times at max_tokens: 32. Nine came back with content as an empty string, finish_reason of length, and 30 to 32 reasoning tokens burned. The tenth answered because it happened to think for only 14.

Note what that does to error handling: HTTP 200, a well-formed response, a usage block, nothing in content. Any code doing if (!res.ok) sails past it. Check finish_reason and retry on length with empty content.

Effort Levels on a Real Module

Vendor benchmarks are somebody else's harness. Here's ours: we deleted md-utils.ts from this monorepo, handed GLM-5.3 nothing but its existing vitest file, and asked for an implementation that passes. Thirty-four assertions over eight pure functions, written months ago with no idea a model would be graded on them. Then we ran the real suite.

EffortWall timeReasoning tokensCompletion tokensTests passed
low8.2s066934/34
high10.0s11687133/34
max117.2s81878192no code returned

Read that bottom row twice. At max_tokens: 8192 max effort spent the entire budget thinking and returned an empty string: not a wrong answer, not a partial file, nothing, billed in full. Raising the ceiling to 32768 produced working code at 18398 reasoning tokens and 249 seconds. Four minutes and 29 times the tokens to match what low did in eight seconds.

Completion tokens to reimplement one module, graded by its own 34 tests low 669 tokens, 8.2s, 34/34 high 871 tokens, 10.0s, 33/34 max 19216 tokens, 249s, 34/34 2026-08-27, glm-5.3 via api.z.ai. Red bar failed a test. Max needed a 32768 budget to emit any code.

The failure at high effort is the detail worth keeping. One test asserts that slugify("a b") returns "a--b", preserving both spaces as separate hyphens. Low wrote text.replace(/\s/g, "-") and passed. High wrote text.replace(/\s+/g, "-") and failed.

That's less a bug than a warning about what extra reasoning does. High effort wrote the function a thoughtful engineer would write; the test wanted the function our codebase has. Generating against an existing suite, the naive answer is often the correct one, and the more a model deliberates the likelier it is to improve your spec out from under you.

How Does It Compare to Claude?

We ran a second, blind round: a different module from the same repo, push-config-guard.ts, 12 assertions, filesystem and all. Neither side had seen the reference implementation.

Everyone passed. GLM at low effort took 10.1 seconds and 865 completion tokens, at high effort 14.8 seconds and 1120. Claude: also 12 of 12.

So we pushed on six cases the suite never covers, and that's the most useful result here. All three behaved identically on every one, including an uppercase UUID, an empty literal, a value on the following line, and a missing directory. All three share the same bug too: a commented-out oneSignalAppId line still counts as a committed id. Two model families, one blind spot, because all three inferred the spec from tests that never asked.

Two disclosures: the Claude side was written by the model writing this article, so read it as a sanity check rather than a contest, and it carries no timing. And n=1 per cell, two modules, one language.

What Do the Vendor Benchmarks Say?

Z.ai's own numbers, from Z.ai's harness:

BenchmarkGLM-5.2Claude Opus 4.8GPT-5.5
FrontierSWE74.475.172.6
SWE-bench Pro62.169.258.6
SWE-Marathon13.026.012.0

Read the first row and it looks like a frontier model. Read the last, 13.0 against 26.0, and it looks like a good model that falls apart on long tasks. The second reading is the honest summary of a long-horizon pitch.

What Does It Cost?

The API is cheap: 1.40 dollars per million input tokens, 4.40 per million output, 0.26 cached. GLM-5.3 costs the same.

Local is another conversation. Unsloth's dynamic GGUFs run 223 GB at 1-bit and 239 GB at 2-bit, needing about 245 GB of combined RAM and VRAM, rising to 810 GB at 8-bit. Buy that hardware for privacy, air-gapped work, or fine-tuning, not to save money on tokens.

Should You Use GLM 5.2 Today?

For general work with no sensitive data in the prompt, it's a fine tool at a sixth of frontier pricing. We wouldn't reach for it as freely as for Claude, and the reason isn't benchmark scores. Sending a client's proprietary code to a jurisdiction your DPA never mentioned deserves a deliberate decision in writing, not a pasted base URL in a config file.

Download the weights if you need the exact model behind the published numbers, if code cannot leave the building, or if you're fine-tuning. GLM-5.3's weights were promised about two weeks after its August 14 launch, so that calculus may have changed by the time you read this.

Test on your own repository, at low effort first. The useful thing we learned in an afternoon wasn't which model wins a benchmark, it was that the cheapest setting beat the dearest one on our own tests at a fraction of the cost. You only get that from your own harness, which is why we ship one alongside testing AI-generated React components and the CI quality gates for AI code.

Frequently Asked Questions

Can I still call GLM 5.2 through the Z.ai API?
Only if your account has a resource package that covers it. We tested this on 2026-08-27 with a pay-as-you-go key. The id glm-5.2 is still listed by the models endpoint, but a chat completion asking for it came back HTTP 429 with error 1113, insufficient balance or no resource package, while glm-5.3 answered normally on the same key. An id that genuinely does not exist returns HTTP 400 with error 1214 instead, so 5.2 is a real, separately billed model rather than an alias for 5.3. Reports that legacy names auto-upgrade describe the Coding Plan, not a plain API key.
Why does GLM return an empty content string?
Because reasoning tokens eat your max_tokens budget before any answer is written. We sent the prompt 'Reply with exactly one word: pong' ten times at max_tokens 32. Nine responses came back with content set to an empty string, finish_reason length, and 30 to 32 reasoning tokens spent. The tenth answered because that run happened to think for only 14 tokens. Budget for reasoning on top of the output you actually want, and never set a tight max_tokens on a thinking model.
How do I set the reasoning effort on GLM 5.3?
Use the OpenAI-style reasoning_effort field with low, high, or max. Sending thinking with type disabled returns error 1210, and the message tells you to use low, high, or max instead. That advice is wrong: passing thinking with type high returns the same 1210 error. The field that actually works is reasoning_effort at the top level of the request body. Thinking cannot be switched off at all on this model.
Is max reasoning effort worth the tokens?
It was actively worse in our test. We asked GLM-5.3 to reimplement a module from our own monorepo, graded by that module's existing 34 vitest assertions. Low passed 34 of 34 in 8.2 seconds on 669 completion tokens. High failed one. Max spent all 8192 tokens of its budget on reasoning and returned an empty string, no code at all, after 117 seconds. Raising the budget to 32768 got working code, but it cost 19216 completion tokens and 249 seconds to match what low did in eight. Reasoning effort is not a quality dial you turn up when the task matters.
What hardware do I need to run GLM 5.2 locally?
More than one GPU can hold. GLM-5.2 is 753B total parameters with about 40B active per token, so even aggressive quantization stays large. Unsloth's dynamic GGUFs land at roughly 223 GB for 1-bit and 239 GB for 2-bit, needing about 245 GB of combined RAM and VRAM, while 4-bit sits between 372 and 475 GB and 8-bit reaches 810 GB. The workable consumer setup is a high-RAM workstation, for example 256 GB of DDR5 with a 24 GB GPU, letting llama.cpp offload whatever layers fit.