Say you added temperature: 0 to your summarizer a few months ago to keep its output steady. Today you update your dependencies, redeploy, and only the summarizer starts returning 400 errors. You didn't touch the model or the prompt.
The first suspect worth checking is the new Claude API version, 2026-10-21. Anthropic's API versioning page says this version removes temperature, top_p and top_k, and that a request sending any one of them returns a 400.
Not every app breaks today, though. Only apps that have started sending the new version do. Below is how to tell which camp yours is in, a script that finds the spots in your code, and the order I would fix things in.
It breaks the moment your app switches versions
Here is what I could confirm on the official page. There are three API versions: 2023-01-01, 2023-06-01 and 2026-10-21. Every request must carry an anthropic-version header, and if you use an official SDK, the SDK sets it for you.
So which version your app sends depends on how it calls the API.
| How you call it | Version sent | If you pass temperature |
|---|---|---|
Plain fetch with 2023-06-01 hard-coded in the header | The old one, until you change it | Still works today. The moment you switch the header to the new version, it returns a 400 |
Official SDK 0.x (for example ^0.137.0) | Old version 2023-06-01 | Still works today |
| Official SDK 1.0.0 or later (TypeScript) | New version 2026-10-21 | A 400 as soon as you send it |
The third row comes from my own check, not from the official page. I pulled @anthropic-ai/sdk 0.137.0 and 1.0.0 from npm and compared them. The default header in client.js is 2023-06-01 in 0.137.0 and 2026-10-21 in 1.0.0. On npm, 1.0.0 was published on October 21, 2026, and its CHANGELOG reads "add support for new API version 2026-10-21".
One more thing that is easy to miss. Even with ^0.137.0 in package.json, a caret range on a 0.x package stays within 0.137.x, so npm update will not carry you to 1.0.0 on its own. Your app breaks on the day you decide to take the major upgrade. If you scan beforehand, that day can be uneventful.
The scan script
It has no dependencies and runs on Node.js alone. It looks for three things: temperature, top_p and top_k assignments, the value of the anthropic-version header, and the SDK version in package.json. To avoid picking up another vendor's temperature, it only reads files that contain the word anthropic or claude.
// scan-claude-api-params.mjs — find settings that return 400 on API version 2026-10-21
// Usage: node scan-claude-api-params.mjs ./my-app
import { readdirSync, readFileSync, statSync } from "node:fs";
import { join, relative, extname } from "node:path";
const root = process.argv[2] ?? ".";
const SKIP_DIRS = new Set(["node_modules", ".git", ".expo", "ios", "android", "dist", "build"]);
const EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".json", ".sql"]);
const samplingRe = /\b(temperature|top_p|top_k)\b\s*[:=]/;
const versionRe = /anthropic-version['"]?\s*[:=,]\s*['"](\d{4}-\d{2}-\d{2})['"]/i;
const sdkRe = /"@anthropic-ai\/sdk"\s*:\s*"([^"]+)"/;
const claudeRe = /anthropic|claude/i;
const rows = [];
function walk(dir) {
for (const name of readdirSync(dir)) {
if (SKIP_DIRS.has(name)) continue;
const path = join(dir, name);
const st = statSync(path);
if (st.isDirectory()) { walk(path); continue; }
if (!EXTS.has(extname(name)) || st.size > 1_000_000) continue;
const text = readFileSync(path, "utf8");
const rel = relative(root, path);
const isClaudeFile = claudeRe.test(text); // only files that talk to Claude (skips other vendors' temperature)
text.split("\n").forEach((line, i) => {
const at = `${rel}:${i + 1}`;
const sdk = line.match(sdkRe);
if (sdk) rows.push({ kind: "SDK", at, note: `@anthropic-ai/sdk ${sdk[1]} (sends the new version once you are on major 1 or later)`, bad: false });
const ver = line.match(versionRe);
if (ver) rows.push({ kind: "VERSION", at, note: `anthropic-version ${ver[1]}${ver[1] >= "2026-10-21" ? " (affected)" : " (still on the old version)"}`, bad: false });
const s = isClaudeFile && line.match(samplingRe);
if (s) rows.push({ kind: "FIX", at, note: `${s[1]} is set (a 400 on 2026-10-21 just for sending it)`, bad: true });
});
}
}
walk(root);
for (const r of rows) console.log(`${r.kind} | ${r.at} | ${r.note}`);
const bad = rows.filter((r) => r.bad).length;
console.log(`\nFound ${rows.length} / need fixing: ${bad}`);
process.exit(bad > 0 ? 1 : 0);Run it like this.
node scan-claude-api-params.mjs ./my-appI tested it on a dummy project with five files: an Edge Function-style fetch (2023-06-01 plus temperature: 0), an SDK-based screen file (temperature and top_p), a package.json with ^0.137.0, a file that only calls another vendor's API, and the same strings inside node_modules. The run produced the following.
SDK | package.json:1 | @anthropic-ai/sdk ^0.137.0 (sends the new version once you are on major 1 or later)
FIX | src/caption.ts:3 | temperature is set (a 400 on 2026-10-21 just for sending it)
VERSION | supabase/functions/summarize/index.ts:3 | anthropic-version 2023-06-01 (still on the old version)
FIX | supabase/functions/summarize/index.ts:4 | temperature is set (a 400 on 2026-10-21 just for sending it)
Found 4 / need fixing: 2
That run also confirmed that the other vendor's file and node_modules are skipped. The exit code is 1 when anything needs fixing, so you can wire it into a pre-build check.
A few limits. It searches line by line as plain text, so options gathered into a separate file and spread in with ...options will slip through. Servers written in Python or other languages are out of scope. I would read the result as a tool for making sure that what it finds gets fixed, not as proof of safety when it prints zero.
Fix it before you change the version
Removing temperature is safe on the old version too, because you are only leaving out an argument. That gives you a clean order.
- Remove
temperature,top_pandtop_kfirst, and deploy on the version you are on today. - Watch the output for a while.
- Later, take the SDK major upgrade or change the header to the new version.
The fix itself is small. Before and after:
// Before: temperature: 0 was added to keep summaries from drifting
body: JSON.stringify({ model: "claude-sonnet-5-5", max_tokens: 400, temperature: 0, messages }),
// After: no sampling settings; the shape is pinned in the prompt instead
body: JSON.stringify({
model: "claude-sonnet-5-5",
max_tokens: 400,
system: "Write the summary in three sentences or fewer, each under 25 words.",
messages,
}),As an indie developer, I watch most closely the spots where temperature: 0 was standing in for "the same input always gives the same output". Once it is gone, the output will vary a little from call to call, so the receiving side needs to be built for that. If a feature expects JSON, validate the string with JSON.parse and retry once on failure. If a screen has a length limit, trim the text on the display side. Having those guards in first makes the app's behavior after the change much easier to predict.
Anthropic's page does not name a replacement setting. The more practical framing, I think, is not "what replaces it" but "make the app work without it".
Keep the model swap in a separate deploy
Claude Sonnet 4.5 is scheduled to retire from the API on November 30. I covered finding leftover model IDs in Is Your Rork App Still Calling Sonnet 4.5? Finding Out Before November 30.
One piece of advice here: do not ship the model ID change and the sampling-parameter removal in the same deploy. If a 400 or an odd-looking output appears after changing both, you cannot tell which one caused it. Ship the parameter removal first (safe on the old version), then swap the model ID the next day or later. If something goes wrong, you know where to look.
The idea of checking before a major upgrade is the same as in A Script to Find the React Native APIs SDK 58 Removed, Before You Upgrade.
A first step you can take today
Run the script once in your project folder and look at two things: the number of FIX lines, and the value on any VERSION line. If it still says 2023-06-01 and your SDK is on 0.x, nothing breaks today. If it does find something, remove just those lines and ship that change on the version you are already on.
Anthropic's pages can change. Before you actually switch, take one more look at the API versioning page.