# Gemini 4 Carbon

Use `gemini-4-carbon` with the native Gemini format. The [model page](https://seedrouter.ai/models/gemini-4-carbon#playground) includes the Playground and current prices. Gemini 4 Carbon uses the same request format as [Gemini 4 Argon](https://seedrouter.ai/docs/gemini-4-argon); Google's guide says moving between them needs only a model ID change.

## Model ID

| Model ID          | Context window                                         | Default effort |
| ----------------- | ------------------------------------------------------ | -------------- |
| `gemini-4-carbon` | 1,048,576 tokens, shared by input, thinking and output | `medium`       |

## Quick example

```bash
curl https://api.seedrouter.ai/v1beta/models/gemini-4-carbon:generateContent \
  -H "Authorization: Bearer $SEEDROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"contents":[{"role":"user","parts":[{"text":"Find the race condition in a retry loop that re-reads a balance before locking it."}]}],"generationConfig":{"thinkingConfig":{"thinkingLevel":"medium"},"maxOutputTokens":32768}}'
```

```python
import json
import os
from urllib.request import Request, urlopen

body = {
    "contents": [{"role": "user", "parts": [{"text": "Find the race condition in a retry loop that re-reads a balance before locking it."}]}],
    "generationConfig": {"thinkingConfig": {"thinkingLevel": "medium"}, "maxOutputTokens": 32768},
}
request = Request(
    "https://api.seedrouter.ai/v1beta/models/gemini-4-carbon:generateContent",
    data=json.dumps(body).encode(),
    headers={"Authorization": f"Bearer {os.environ['SEEDROUTER_API_KEY']}", "Content-Type": "application/json"},
    method="POST",
)
with urlopen(request, timeout=900) as response:
    print(json.load(response))
```

```javascript
const response = await fetch(
  "https://api.seedrouter.ai/v1beta/models/gemini-4-carbon:generateContent",
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SEEDROUTER_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      contents: [{ role: "user", parts: [{ text: "Find the race condition in a retry loop that re-reads a balance before locking it." }] }],
      generationConfig: { thinkingConfig: { thinkingLevel: "medium" }, maxOutputTokens: 32768 },
    }),
  },
);
if (!response.ok) throw new Error(await response.text());
console.log(await response.json());
```

```go
package main

import (
    "bytes"
    "fmt"
    "io"
    "net/http"
    "os"
    "time"
)

func main() {
    body := []byte(`{"contents":[{"role":"user","parts":[{"text":"Find the race condition in a retry loop that re-reads a balance before locking it."}]}],"generationConfig":{"thinkingConfig":{"thinkingLevel":"medium"},"maxOutputTokens":32768}}`)
    req, err := http.NewRequest("POST", "https://api.seedrouter.ai/v1beta/models/gemini-4-carbon:generateContent", bytes.NewReader(body))
    if err != nil { panic(err) }
    req.Header.Set("Authorization", "Bearer " + os.Getenv("SEEDROUTER_API_KEY"))
    req.Header.Set("Content-Type", "application/json")
    client := &http.Client{Timeout: 15 * time.Minute}
    resp, err := client.Do(req)
    if err != nil { panic(err) }
    defer resp.Body.Close()
    out, err := io.ReadAll(resp.Body)
    if err != nil { panic(err) }
    fmt.Println(string(out))
}
```

The model belongs in the URL. `contents` is required. An answer includes native `candidates`, `finishReason` and `usageMetadata`; retain complete content parts, including `thoughtSignature`, for conversation history. Hard prompts can run for several minutes. A non-streaming request that runs longer than about 100 seconds can end with HTTP 524 before the answer arrives, so use `streamGenerateContent` for long tasks; the examples also set a 15-minute client timeout, as Google recommends.

## Endpoints

| Operation          | Endpoint                                                            |
| ------------------ | ------------------------------------------------------------------- |
| JSON response      | `POST /v1beta/models/gemini-4-carbon:generateContent`               |
| Server-sent events | `POST /v1beta/models/gemini-4-carbon:streamGenerateContent?alt=sse` |

The [OpenAPI specification](https://seedrouter.ai/docs/gemini-4-carbon.openapi.json) includes every nested request and response schema. Optional fields use API defaults when omitted. SeedRouter forwards the submitted body without filtering unknown fields, removing unsupported fields or validating model parameter values. The Gemini API decides whether a request is accepted.

## Request parameters

The URL fixes the model to `gemini-4-carbon`. The request contract contains 11 top-level fields. Fields are optional unless marked required; omission differs from JSON `null`. Nullable arbitrary JSON is preserved where the official schema permits it.

| Field               | Type      | Required | Default and constraints                                                                                     |
| ------------------- | --------- | -------- | ----------------------------------------------------------------------------------------------------------- |
| `contents`          | object\[] | Yes      | Nonempty conversation; each content has nonempty `parts`                                                    |
| `systemInstruction` | object    | No       | Text-only parts; no automatic user identity is inserted                                                     |
| `generationConfig`  | object    | No       | Generation parameters in the next table                                                                     |
| `tools`             | object\[] | No       | Function declarations and built-in tool configurations                                                      |
| `toolConfig`        | object    | No       | Function selection and retrieval configuration                                                              |
| `safetySettings`    | object\[] | No       | One setting per category; no duplicate categories                                                           |
| `serviceTier`       | string    | No       | `unspecified`, `standard`, `flex`, `priority`; ordinary processing is standard                              |
| `continuationToken` | string    | No       | Token returned with `finishReason: CONTINUATION`; resend the same request with it to continue a long answer |
| `labels`            | object    | No       | String values; lowercase keys/values, maximum 63 Unicode codepoints each                                    |
| `model`             | string    | No       | Optional resource name; the URL determines the actual model                                                 |
| `store`             | boolean   | No       | Generic request storage preference; model-specific effect unverified                                        |

Explicit context caching (`cachedContent` and `cachedContents` resources) is not supported on Gemini 4 Carbon. Implicit caching is on by default for prompts of at least 4,096 tokens.

### Generation parameters

| Field in `generationConfig`  | Type      | Default and constraints                                                                                                                                                                |
| ---------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `maxOutputTokens`            | integer   | Default 65,536, including thinking. Up to 1,048,576 minus input with continuation. Google documents a 400 for a non-streaming request above 32,768 without `continuationToken`         |
| `thinkingConfig`             | object    | `thinkingLevel`: `low`, `medium`, `high` (default `medium`); uppercase spellings accepted. `includeThoughts`: boolean, default false. Use `thinkingLevel` rather than `thinkingBudget` |
| `stopSequences`              | string\[] | Maximum five sequences                                                                                                                                                                 |
| `responseMimeType`           | string    | Default `text/plain`; legacy JSON schema output requires `application/json`                                                                                                            |
| `responseSchema`             | object    | Official schema dialect; mutually exclusive with `responseJsonSchema`                                                                                                                  |
| `responseJsonSchema`         | JSON      | JSON Schema; mutually exclusive with `responseSchema`                                                                                                                                  |
| `responseFormat`             | object    | Text format configuration; `text.mimeType` and optional `text.schema`. Schema requires JSON MIME type                                                                                  |
| `responseModalities`         | string\[] | Text only: `TEXT`; empty means text                                                                                                                                                    |
| `mediaResolution`            | enum      | `MEDIA_RESOLUTION_UNSPECIFIED`, `LOW`, `MEDIUM`, `HIGH` with the `MEDIA_RESOLUTION_` prefix                                                                                            |
| `seed`                       | integer   | Signed 32-bit value; model-specific deterministic behavior unverified                                                                                                                  |
| `presencePenalty`            | number    | Generic field; model-specific effect/range unverified                                                                                                                                  |
| `frequencyPenalty`           | number    | Generic field; model-specific effect/range unverified                                                                                                                                  |
| `responseLogprobs`           | boolean   | Generic field; model-specific availability unverified                                                                                                                                  |
| `logprobs`                   | integer   | 0–20; requires `responseLogprobs: true`; model support unverified                                                                                                                      |
| `enableEnhancedCivicAnswers` | boolean   | Generic field; model support unverified                                                                                                                                                |
| `enableAffectiveDialog`      | boolean   | Generic field; model support unverified                                                                                                                                                |
| `audioTranscriptionConfig`   | object    | Generic field; model-specific options unverified                                                                                                                                       |
| `translationConfig`          | object    | Generic field; model-specific options unverified                                                                                                                                       |

The [OpenAPI document](https://seedrouter.ai/docs/gemini-4-carbon.openapi.json) lists nested types, enums, required properties and documented bounds for every message. The schemas describe official parameters; they are not a SeedRouter request allowlist. Caller-supplied fields and values are preserved. A field accepted by the schema is not proof of support for every account. `minimal` thinking is not a listed level. Google says `temperature`, `topP` and `topK` are ignored on this model; `candidateCount` is not an official control. If submitted in native JSON, they still pass through unchanged for the Gemini API to handle. End the conversation with user content; function-response-only user turns remain valid.

## Long decode

One Gemini 4 Carbon response returns up to 65,536 tokens when streaming and up to 32,768 tokens without streaming. To go further, set `maxOutputTokens` above 65,536 and continue the answer yourself:

1. Send the request. If the response ends with `finishReason: "CONTINUATION"`, read `candidates[0].continuationToken`.
2. Send the **same** request again with that value in the top-level `continuationToken` field. Do not append the partial output to `contents`; the token carries the model's state, including its thinking.
3. Repeat until `finishReason` is `STOP` or `MAX_TOKENS`.

```json
{
  "contents": [{"role": "user", "parts": [{"text": "Write a complete, rigorous proof of the prime number theorem."}]}],
  "generationConfig": {"thinkingConfig": {"thinkingLevel": "high"}, "maxOutputTokens": 262144},
  "continuationToken": "TOKEN_FROM_THE_PREVIOUS_RESPONSE"
}
```

A hop spent entirely on thinking can return empty text with `CONTINUATION`; that is normal progress. Each hop sends your prompt plus everything generated so far back to the model, so input tokens are counted again in every later hop. SeedRouter bills each hop as its own request. The Interactions API's server-side `background` mode is not part of this endpoint.

## Structured output

```json
{
  "contents": [{"parts": [{"text": "Return a JSON object with ok set to true."}]}],
  "generationConfig": {
    "thinkingConfig": {"thinkingLevel": "low"},
    "maxOutputTokens": 32768,
    "responseMimeType": "application/json",
    "responseJsonSchema": {
      "type": "object",
      "properties": {"ok": {"type": "boolean"}},
      "required": ["ok"]
    }
  }
}
```

The legacy `responseSchema` and `responseJsonSchema` fields cannot be used together. Both require `responseMimeType: "application/json"`. The newer `responseFormat.text` schema must likewise specify JSON. Use REST enum spellings (`APPLICATION_JSON` and `TEXT_PLAIN`) in that message. Requests pass through unchanged; media MIME types and arbitrary function JSON are not rewritten.

## Functions and built-in tools

Use `tools[].functionDeclarations` with a name and either `parameters` or `parametersJsonSchema`, not both. Function selection lives in `toolConfig.functionCallingConfig`; `allowedFunctionNames` requires `ANY` or `VALIDATED` and declared names.

Your application executes returned functions and supplies their results in the next conversation turn. Preserve each original `thoughtSignature`, function call and function response. Do not round numeric identifiers when serializing opaque function arguments.

Google lists Search, Maps, code execution, URL context, File Search and Computer Use for this model. File Search resources require access under the credentials serving the request. Native MCP configuration appears in the generic schema, but its availability for this model is not established. Google Maps requires text-only input; check the official API restrictions before combining Maps with media. With grounding, Google counts internal tool instructions and function declarations as input tokens. The Playground does not execute your custom functions.

## Multimodal input and safety

A `contents[].parts[]` item contains exactly one payload: text, inline media, a file reference, a function call/response, or an execution part. It may also carry a signature or media metadata. Input supports text, images, audio, video and PDFs; output is text only. The model has no image or audio generation and no Live API.

For inline bytes, use `inlineData.mimeType` and base64 `data`. For file references, use `fileData.mimeType` and `fileUri`. A syntactically valid URL is not proof the model can retrieve it. Video metadata can specify start/end offsets and a positive `fps` no greater than 24. Agentic video understanding is selected per part with `mediaProcessing: "AGENTIC"` next to the video's `fileData` or `inlineData`; static processing is the default. `videoMetadata` holds only `startOffset`, `endOffset` and `fps`.

Safety settings use the official native format and pass through the API unchanged. In the Playground, all four categories must be set to `BLOCK_MEDIUM_AND_ABOVE` or stricter; lower thresholds are available through the API only.

## JSON responses and streaming

`generateContent` returns native JSON. `streamGenerateContent?alt=sse` emits native JSON in SSE `data:` events. Important fields include `candidates[].content.parts`, `finishReason`, `continuationToken`, `safetyRatings`, `groundingMetadata`, `promptFeedback`, `modelVersion`, `responseId` and `usageMetadata`.

Retain complete native content in conversation history. Thinking summaries are not the same as thought signatures. A disconnect does not prove generation failed or completed; inspect the partial result and account record before sending another request. Stream usage is cumulative, so use the latest counters instead of summing every chunk.

## Usage and pricing

`promptTokenCount` includes cached input. `cachedContentTokenCount` is charged at the cached-input rate, rather than charged again as uncached input. Billable output includes `candidatesTokenCount` plus `thoughtsTokenCount`. Gemini 4 Carbon spends more thinking tokens per turn than Gemini 4 Argon, so expect higher output usage on the same prompt.

There is no context-length price step for this model. Flex and Priority are separate processing tiers. A reported Standard result must not incur a Priority surcharge; if a requested Priority response does not establish its actual tier, Standard token rates apply. Google Search and Maps grounding are billed per query, separately from generation tokens. Failed requests are not charged. See the [live pricing table](https://seedrouter.ai/models/gemini-4-carbon#pricing).

## Account groups

Select an available group in the Playground, or use the optional API header with the exact group name:

```http
X-SeedRouter-Group: GROUP_NAME
```

The chosen group determines the price and available capacity; an explicit selection does not silently switch to another group. Omit the header or use `auto` to keep the API key's default behavior.

Check your API key's available groups without generating a response:

```bash
curl "https://api.seedrouter.ai/api/seedrouter/llm/groups?model=gemini-4-carbon" \
  -H "Authorization: Bearer YOUR_SEEDROUTER_KEY"
```

## Verification status

The controls and documentation follow the official native format. Parameter validation belongs to the Gemini API. Production requests on November 11, 2026 (one attempt each) observed:

| Area                                                                                                      | Result                                                                                          |
| --------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| Text, system instruction, stop sequences, seed, `responseModalities`                                      | Answered as requested                                                                           |
| `thinkingLevel` low / medium / high (also uppercase)                                                      | Accepted; thinking usage grew with the level. `includeThoughts` returned a thought summary part |
| `minimal` thinking, `candidateCount: 2`, `presencePenalty` / `frequencyPenalty`, final model-prefill turn | HTTP 400 from the Gemini API                                                                    |
| `thinkingBudget`, `temperature` / `topP` / `topK`                                                         | Accepted; sampling values have no documented effect                                             |
| `responseJsonSchema`, legacy `responseSchema`                                                             | Schema-valid JSON                                                                               |
| Function calling, including `mode: ANY`                                                                   | `functionCall` parts with arguments and call IDs                                                |
| Code execution, Google Search, Google Maps                                                                | Tool parts and grounding metadata returned                                                      |
| URL context                                                                                               | Tool ran, but both tested pages were reported as unreachable                                    |
| Image (URL, low media resolution), inline PDF, video, audio (streaming)                                   | Understood correctly; a non-streaming audio request ended with HTTP 524                         |
| `responseLogprobs` with `logprobs`                                                                        | `logprobsResult` returned                                                                       |
| `maxOutputTokens: 40000` without streaming                                                                | Accepted for a short answer                                                                     |

Processing tiers, `mediaProcessing: "AGENTIC"` and continuation tokens need a follow-up check after the current release reaches production. No measured quality or latency comparison with Gemini 4 Argon is claimed.

## References

* [Google model specification](https://aistudio.google.com/docs/models/gemini-4-carbon)
* [What's new in Gemini 4 Carbon](https://aistudio.google.com/docs/whats-new-gemini-4-carbon)
* [Long decode with generateContent](https://aistudio.google.com/docs/long-decode?generate-content=true)
* [Thinking](https://aistudio.google.com/docs/thinking)
* [Pricing](https://aistudio.google.com/docs/pricing#gemini-4-carbon)
* [GenerateContent REST reference](https://ai.google.dev/api/generate-content)
