Skip to content

Gemini’s responseMimeType Options Beyond JSON

8 min read · updated August 11, 2026

responseMimeType tells Gemini what format to constrain its output to. Almost everything written about it covers application/json and stops, which leaves the one genuinely interesting value undocumented in practice: an enum mode that forces the model to return exactly one of a list of strings, with no parsing and no prompt engineering.

Where the field lives

It is a member of generationConfig, alongside temperature, maxOutputTokens and stopSequences:

POST https://generativelanguage.googleapis.com/v1beta/models/\
gemini-2.0-flash:generateContent

{
  "contents": [{"role": "user", "parts": [{"text": "..."}]}],
  "generationConfig": {
    "responseMimeType": "application/json",
    "responseSchema": { ... }
  }
}

In the Python SDK the same field appears as response_mime_type inside the generation config object, and in the Node SDK as responseMimeType. The value is the same string either way.

What it does is not prompting. Setting this field switches the decoder into a constrained mode: at each step, tokens that could not continue a valid document of the requested type are masked out before sampling. That is a mechanical guarantee about the output’s grammar and it is categorically stronger than asking the model nicely in the prompt, which the model can decline. It is also why the field interacts badly with anything that cuts generation at an arbitrary point — a grammatically valid prefix of a JSON document is not a JSON document.

The accepted values

Google documents the accepted values in the Gemini API generateContent reference. For text output there are three:

  • text/plain — the default. Unconstrained text. Setting it explicitly is the same as omitting the field, which is occasionally useful when you are building the config programmatically and want to clear a previous value rather than delete a key.
  • application/json — JSON output. On its own this asks for valid JSON of any shape; combined with responseSchema it constrains the structure too, which is what you almost always want. Covered in how responseSchema constrains the output.
  • text/x.enum — a single value from an enumerated list, returned as a bare string with no JSON wrapping. Requires a responseSchema of type STRING carrying an enum array.

Constrained decoding is not available on every model in the family and the availability differs between the Gemini API and Vertex AI. Check the model card before assuming a value is accepted; an unsupported combination is rejected at request time rather than degrading.

Notice what is not on the list. There is no text/csv, no application/xml, no text/markdown. If you want any of those you are back to asking in the prompt and validating the result, because there is no grammar for the decoder to enforce. The gap is not arbitrary: JSON and a closed enum are both formats where “is this token legal here” is answerable from a small amount of parser state, which is exactly what constrained decoding needs. Markdown has no such property. If a structured format matters and it is not one of these, the reliable route is to request JSON and render it yourself.

text/x.enum, the useful one

Classification is the most common LLM task in production and the most annoying to make reliable, because the failure is never a wrong class — it is the model returning "The sentiment here is clearly positive." when your code expected positive. Every prompt-engineering fix for that is a request that the model can decline. Enum mode is not a request; the decoder cannot emit anything outside the list.

{
  "contents": [{
    "role": "user",
    "parts": [{"text": "Ticket: my card was charged twice this morning."}]
  }],
  "generationConfig": {
    "responseMimeType": "text/x.enum",
    "responseSchema": {
      "type": "STRING",
      "enum": ["billing", "technical", "account", "other"]
    }
  }
}

The response text is exactly billing. No quotes, no braces, no preamble, nothing to strip. That is the distinction from doing the same thing with a one-field JSON schema, which works but costs you the wrapping tokens on every call and a parse on your side that can fail.

Two properties worth knowing. The enum values are visible to the model — they are part of the constraint, and their wording affects which one gets picked, so name them descriptively rather than as codes. And the list is finite and closed: there is no escape hatch, so include your own other or unknown member unless you genuinely want the model forced into one of the real classes. The same enum mechanism can also appear as a field type inside a larger JSON schema — see enum-constrained output for that variant.

There is a cost, and it is that the enum has to be in the request. If your label set is large or changes often, it lives in your code and travels on every call, which is fine at a dozen classes and unwieldy at a thousand. At that scale the constraint stops being the right tool and the job becomes retrieval or a classifier of its own. Enum mode is at its best where the list is short, stable, and the cost of an off-vocabulary answer is an exception in your pipeline.

Three fields that are not this one

Most of the confusion around this parameter is people reaching for it for a job one of these three does.

A part’s own mimeType

inlineData.mimeType and fileData.mimeType describe input — the type of an image, audio clip or PDF you are sending. They take real media types like image/png or audio/mp3. They are unrelated to the output constraint and take a completely different set of values.

"parts": [
  {"inlineData": {"mimeType": "image/png", "data": "<base64>"}},
  {"text": "What is in this image?"}
]

responseModalities

If you want the model to produce something other than text — an image, or audio — that is responseModalities, an array of modality names in generationConfig. Setting responseMimeType to image/png does not request an image and is not an accepted value.

Function calling

If what you want is a structured call to your own code rather than a structured document, that is tools and toolConfig, not a MIME type. The overlap is real — both produce schema-conforming JSON — and the deciding question is whether you want the model to hand you data or to invoke something. See forcing a function call with mode ANY.

What goes wrong

  • A schema without the MIME type. responseSchema on its own, with responseMimeType left at the default, is not an error in every SDK version but is not constrained output either. Set both.
  • An enum schema that is not a STRING. text/x.enum requires type: "STRING" with enum. An object type with an enum field inside it needs application/json instead.
  • Truncation producing invalid JSON. Constrained decoding guarantees the grammar, not that the model finishes within maxOutputTokens. If the budget runs out mid-object you get a truncated string that will not parse, with finishReason of MAX_TOKENS rather than STOP. Always check it — see what finishReason returns.
  • An empty response with no candidate. A safety block returns no content regardless of the MIME type, and your JSON parse fails on an empty string. That is a different failure with a different fix.