Google shipped Gemini 3.8 Flash on September 2, 2026, three weeks after 3.7 Flash, at the same intro price and roughly the same speed. The model ID is gemini-3.8-flash, no preview suffix, and the model card describes it as “based on Gemini 3.7 Flash”. So most teams expect a one-line swap. For a plain chat prompt, it is. For anything that sets thinking parameters, tunes sampling, or runs a tool loop, there are nine things to check, and two of them return errors that 3.7 Flash never did.
This guide is that checklist, built from Google’s What’s new in Gemini 3.8 Flash page and the Gemini 3 developer guide. Each item has a before and after fragment for both API shapes: the Interactions API, which Google now treats as the primary path, and the legacy generateContent endpoint that most 3.7 Flash code still uses. Every fragment can be pasted into Apidog and sent against the live endpoint before it touches production. If you want the model overview first, start with what Gemini 3.8 Flash is.
One framing note before the list. Google says 3.8 Flash “works harder” by design: on complex tasks it takes smaller reasoning steps, verifies its work, and calls tools iteratively. That is the source of most of its gains and also the reason a migration needs a token budget review, not only a config diff.
What changes and what doesn’t
| Area | 3.7 Flash | 3.8 Flash |
|---|---|---|
| Model ID | gemini-3.7-flash |
gemini-3.8-flash |
| Context / output | 1,048,576 / 65,536 | Same |
| Price (intro through Dec 31, 2026) | $0.75 / $3.75 per 1M | Same, then $1.50 / $7.50 for both from Jan 1, 2027 |
| Thinking levels | low, medium, high | Same; minimal returns a validation error; default is medium |
| Tokens per task | baseline | +30% output tokens on average (Artificial Analysis) |
| Function results | call_id + name |
Both required, enforced |
| Support status | “remains fully supported”, no deprecation date | Current |
Source for the pricing rows: Google’s Gemini API pricing page, where the 3.6, 3.7, and 3.8 Flash rows are identical.
Step 0: decide whether to move at all
Nothing forces the migration. Google’s launch post states that “Gemini 3.7 Flash remains fully supported”, and no sunset date is published. Per-token pricing is unchanged, so the only cost delta is usage. Artificial Analysis measured 3.8 Flash at high thinking using about 48k output tokens per task on their index, 30% more than 3.7 Flash, which moved cost per task from $0.40 to $0.58 at identical rates. Their index score rose from 56 to 59, and tool-use accuracy on τ³-Banking rose 12 points to 45%.
So the trade is more capability per task for more tokens per task. If your workload is short, latency-sensitive, or already passing its evals on 3.7 Flash, you can stay put. The full 3.8 Flash vs 3.7 Flash comparison has a decision matrix by workload. If you’re moving, keep reading.
Step 1: swap the model ID in both shapes
Interactions API (Google’s primary API for Gemini 3.x):
{"model": "gemini-3.7-flash", "input": "..."}
{"model": "gemini-3.8-flash", "input": "..."}
Legacy generateContent (still supported, no sunset):
POST /v1beta/models/gemini-3.7-flash:generateContent
POST /v1beta/models/gemini-3.8-flash:generateContent
Python SDK, both paths:
client.interactions.create(model="gemini-3.8-flash", input=..., generation_config={"thinking_level": "medium"})
client.models.generate_content(model="gemini-3.8-flash", contents=..., config=types.GenerateContentConfig(thinking_config=types.ThinkingConfig(thinking_level="low")))
If you’ve never used the Interactions API, the 3.8 Flash API guide covers both shapes end to end; the older 3.7 Flash API walkthrough only covered generateContent, which is why this guide shows both.
The nine-item migration checklist
Work through these in order. Items 1 to 4 are config changes that surface immediately. Items 5 and 6 affect tool loops and multi-turn state. Items 7 to 9 are planning and media changes you’ll only catch in testing.
1. Map thinking_level: "minimal" to "low"
This is the one that breaks first. 3.8 Flash accepts low, medium, and high. Sending minimal returns a validation error. The default when you send nothing is medium. Gemini 3 Pro defaults to high, so don’t copy a Pro config across and assume it matches.
Before (3.7 Flash, Interactions):
{"generation_config": {"thinking_level": "minimal"}}
After (3.8 Flash):
{"generation_config": {"thinking_level": "low"}}
Legacy shape, after:
{"generationConfig": {"thinkingConfig": {"thinkingLevel": "low"}}}
Google’s thinking documentation describes low as the latency setting and medium as the default for complex code and agentic work. Which level to use per route is its own article; for migration purposes, low is the direct replacement for minimal.
2. Remove temperature, top_p, and top_k
Google’s guidance for every Gemini 3 model is to keep temperature at its default of 1.0. Lowering it “may cause looping or degraded performance”. Many 3.7 Flash configs carry a temperature: 0.2 left over from earlier generations. Delete the sampling keys rather than setting them.
Before:
{"generationConfig": {"temperature": 0.2, "topP": 0.9, "topK": 40}}
After:
{"generationConfig": {"thinkingConfig": {"thinkingLevel": "medium"}}}
If you used a low temperature to get repeatable JSON, use structured outputs instead. They’re supported on 3.8 Flash and give you a schema-shaped response without touching sampling.
3. Replace thinking_budget with thinking_level
thinking_budget was an integer token cap. thinking_level is a string enum. There’s no arithmetic mapping between them, so pick the level by intent: latency routes get low, default routes get medium, hardest multi-step routes get high.
Before:
{"generationConfig": {"thinkingConfig": {"thinkingBudget": 4096}}}
After:
{"generationConfig": {"thinkingConfig": {"thinkingLevel": "low"}}}
Thinking tokens are still billed as output tokens and reported in usageMetadata.thoughtsTokenCount, so the cost control moves from a hard cap to a level choice plus an assertion in your tests (see the regression section below).
4. Remove candidate_count
Gemini 3 and later don’t support multiple candidates. Drop the key, and drop any code that indexed candidates[1] or beyond.
Before:
{"generationConfig": {"candidateCount": 2}}
After:
{"generationConfig": {}}
If you sampled several candidates to pick the best one, the replacement on 3.8 Flash is a higher thinking level, which does the verification inside one response.
5. Put call_id and name on every function result
This is the second hard break. On 3.8 Flash, every function result you send back must carry both the call’s id and the function name. Google’s Gemini 3 guide says to “ensure all FunctionResponse objects include call_id and name”. Code that only echoed the name will fail on the tool-result turn.
Interactions API, after:
{
"previous_interaction_id": "<id from the function_call step>",
"input": [{
"type": "function_result",
"name": "get_weather",
"call_id": "<id from the function_call step>",
"result": [{"type": "text", "text": "{\"temp_c\": 24}"}]
}]
}
The model’s function_call step gives you id, name, and arguments; copy the first two straight back. In the legacy shape, the functionResponse part carries the same value in a field spelled id (matching the id on the model’s functionCall part) alongside name and response. Google’s function calling reference has the canonical examples, and the 3.8 Flash function calling guide walks through the full two-turn loop, including why 3.8 Flash calls tools more times per task than 3.7 Flash did.
6. Pass thought signatures back exactly as received
Gemini 3 models attach thought signatures to response parts. When you build the next turn yourself, return every part unchanged, signatures included, for all part types, not only text. Stripping or re-serializing them degrades the model’s continuity on the next step.
The Interactions API removes this work when you let the server keep state: pass previous_interaction_id and Google holds the history. If you set store: false for a stateless call, you own the history again and must send the thought blocks and signatures back yourself. In legacy generateContent, you always own the history, so audit any code that rebuilds contents from a trimmed copy of the last response.
7. Budget more tokens per route
This item has no error to catch, which is why it gets missed. The +30% output-token figure from Artificial Analysis is an average across their index at high thinking. Google’s own wording is that the model “can use more tokens on longer running and complex tasks, by design” and that usage rises “especially at higher effort levels”.
Plan per route, not globally:
- Latency-sensitive endpoints:
low. AA measured 0.8 minutes per task at low versus 2.5 at high, and $0.24 per task versus $0.58. - Default routes:
medium, at about $0.41 per task on the same index. - Agent loops: expect more tool-call turns per task, so cap the loop by turn count, not only by tokens.
Also revisit the 65,536 output-token ceiling. A 3.7 Flash prompt that returned 40k tokens with thinking may now run closer to the limit. If you’re modeling the bill, the 3.8 Flash pricing breakdown works the per-task numbers at all three levels.
8. Test media_resolution_high on PDFs versus video
3.8 Flash accepts text, image, video, audio, and PDF input. The media resolution setting changes how many tokens each media input consumes, and the cost differs by media type, so the same setting that is cheap on a PDF page can be expensive on a long video. Don’t carry a global high-resolution setting across from 3.7 Flash without measuring. Send one representative PDF and one representative video at each resolution and compare usageMetadata.promptTokenCount between them.
9. Drop any image segmentation calls
Image segmentation is not supported on Gemini 3 models. If a 3.7 Flash-era pipeline still routed segmentation through an older Gemini model, that path is separate from this migration; if a prompt asked 3.8 Flash for segmentation masks, expect it to fail rather than return usable output. Image generation, audio generation, and the Live API are also not supported on 3.8 Flash, per the model page.
Build the regression plan in Apidog
A migration with two breaking changes and a token-usage shift needs a repeatable comparison, not a one-off curl. Here’s the setup we use in Apidog, which works because Apidog is an API client and test runner: it sends the requests, checks the responses, and schedules the run. It does not run the model.
Environment and variables. Create a Gemini environment with GEMINI_API_KEY stored as a secret variable and a MODEL variable. Use {{MODEL}} in the URL of the generateContent request and in the model field of the Interactions request, so the same saved request runs against either model.
Golden prompts. Save 10 to 20 prompts that represent your real routes: a short chat turn, a structured-output extraction, a two-turn function call with a mocked tool, one PDF and one video input. Each is one request in a test scenario.
Assertions. Add three per request:
- Status is 200, and the response body matches a JSON schema. For structured-output routes, assert on the fields you parse downstream.
usageMetadata.thoughtsTokenCountstays under a ceiling you set per route (for example, 8,000 on alowroute). This is the guard that catches a config that silently fell back tomedium.usageMetadata.totalTokenCountstays under the route’s budget from item 7.
Side by side. Duplicate the scenario, set MODEL to gemini-3.7-flash in one and gemini-3.8-flash in the other, and run both. Apidog’s test reports show pass/fail per assertion and the response bodies, so the token delta per prompt is visible in one view rather than reconstructed from logs. For the function-call scenario, add an assertion that the call_id you sent back equals the id from the previous step’s function_call.
Schedule it. Turn the 3.8 Flash scenario into a scheduled run so the token ceilings are checked daily during the rollout window. The scheduled API tests guide covers the setup. If you’d rather follow along in the app, Download Apidog and import the curl fragments above.
Rollback: keep 3.7 Flash behind a config flag
Because 3.7 Flash remains fully supported and shares 3.8 Flash’s price, the rollback is cheap: keep the model ID in configuration rather than code.
{"gemini_model": "gemini-3.8-flash", "gemini_fallback_model": "gemini-3.7-flash"}
Three rules make the flag safe:
- Keep the migrated request shape on both models. Items 1 to 6 (no
minimal, no sampling keys,thinking_levelnotthinking_budget, nocandidate_count,call_id+name, signatures preserved) are all valid on 3.7 Flash too, so a flipped flag never needs a second code path. - Roll out per route. Flip
low-level latency routes first, since their token delta is smallest; flip agent loops last, after the side-by-side scenario has passed for a few days. - Watch tokens, not only errors. A rollback trigger on 3.8 Flash is more likely to be a cost or latency regression than a 4xx, so wire the token-ceiling assertions into your alerting.
FAQ
Does Gemini 3.8 Flash cost more than 3.7 Flash? Not per token. Both are $0.75 input / $3.75 output per 1M through December 31, 2026, and both rise to $1.50 / $7.50 on January 1, 2027. Per task, 3.8 Flash uses more tokens by design; Artificial Analysis measured about 30% more output tokens on their index at high thinking.
What happens if I leave thinking_level: "minimal" in place? The request fails with a validation error on 3.8 Flash. Replace it with low. The thinking levels guide explains what each remaining level does and how to measure the difference.
Do I have to move to the Interactions API to use 3.8 Flash? No. generateContent is described as legacy but remains fully supported with no sunset date, and 3.8 Flash works on it. The Interactions API adds server-side conversation state via previous_interaction_id, which removes the thought-signature bookkeeping in item 6.
Is 3.7 Flash being deprecated? Google says it “remains fully supported” and has not published a deprecation date. That’s what makes the config-flag rollback viable.
Can I keep the same temperature I tuned for 3.7 Flash? Google’s advice for all Gemini 3 models is to leave temperature at 1.0. If you were already overriding it on 3.7 Flash, this migration is the moment to remove it and check your evals; structured outputs are the supported route to deterministic shapes.
Ship it in stages
The migration itself is small: one ID change, four config deletions or renames, two tool-loop fields, and a signature audit. The part that takes time is proving the token budget holds per route, and that’s a testing problem. Save the golden prompts, assert on schema and token ceilings, run 3.7 and 3.8 Flash side by side until the numbers settle, then flip the flag one route at a time. If a route regresses, the flag sends it back to 3.7 Flash with no code change, and you keep the improved routes.



