> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bananahub.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Gemini-compatible API

> Use the official Google Gemini SDK against BananaHub by overriding the base URL.

BananaHub speaks the Google Gemini `generateContent` wire format. You can keep using Google's official [`google-genai`](https://pypi.org/project/google-genai/) SDK — or any Gemini-compatible client — and just point it at BananaHub.

<Card title="Base URL" icon="link">
  Pass this as the SDK's `base_url`:

  ```text theme={null}
  https://bananahub.io/api/gemini
  ```

  The SDK appends `/v1beta/models/...` itself, so keep the `/api/gemini` suffix.
</Card>

## How it differs from the native API

The Gemini-compatible endpoint is **synchronous**: a single request returns the image inline, in Gemini JSON. There are no jobs to poll and no webhooks.

|             | Native API                          | Gemini-compatible API               |
| ----------- | ----------------------------------- | ----------------------------------- |
| Style       | Asynchronous (`202` + poll `/jobs`) | Synchronous (image returned inline) |
| Auth header | `Authorization: Bearer <key>`       | `x-goog-api-key: <key>`             |
| Client      | cURL / your HTTP client             | Official `google-genai` SDK         |
| Result      | Presigned `image_url`               | Base64 image in the response        |
| Webhooks    | Supported                           | Not applicable                      |

<Tip>
  Both APIs use the **same** BananaHub API key and the same balance. Pick whichever fits your stack.
</Tip>

## Authentication

Send your BananaHub API key as `x-goog-api-key`. When you set `api_key` on the SDK client, it adds this header for you. A `?key=` query parameter is also accepted.

The key must be scoped for the model you request — see [Authentication](/authentication). A key without permission for the model returns `403 PERMISSION_DENIED`.

## Models

Use any of the supported Gemini model IDs:

| BananaHub model | Gemini model IDs                                            | Resolutions                  |
| --------------- | ----------------------------------------------------------- | ---------------------------- |
| NanoBanana      | `gemini-2.5-flash-image` · `gemini-2.5-flash-image-preview` | `1K`                         |
| NanoBanana 2    | `gemini-3.1-flash-image` · `gemini-3.1-flash-image-preview` | `512px` · `1K` · `2K` · `4K` |
| NanoBanana Pro  | `gemini-3-pro-image` · `gemini-3-pro-image-preview`         | `1K` · `2K` · `4K`           |

Set the aspect ratio and size through `imageConfig` (`aspectRatio`, `imageSize`). `imageSize` is passed through to and validated by the model: supported values are `1K` (default), `2K`, `4K`, plus `512px` on NanoBanana 2. An unsupported value returns `400 INVALID_ARGUMENT`. See [Aspect ratios](/concepts/aspect-ratios).

<Note>
  Billing is per the requested size, with `1K` as the floor: `512px` is billed at the `1K` rate. `2K` and `4K` are billed at their own rates.
</Note>

## Supported methods

| Method                     | Supported | Notes                                                  |
| -------------------------- | --------- | ------------------------------------------------------ |
| `generateContent`          | ✅         | Image returned inline as base64.                       |
| `streamGenerateContent`    | ✅         | SSE (`alt=sse`) frames, exactly what the SDK consumes. |
| `countTokens`              | ✅         | Proxied to Google for a real token count.              |
| `models.list` (ListModels) | ❌         | Reference models by id directly (see the table above). |

Both directions are a **full passthrough**: any `generationConfig`, `safetySettings`, `systemInstruction`, or `tools` fields you send reach the model unchanged, and the complete Gemini response — including `usageMetadata`, `finishReason`, and `safetyRatings` — is returned verbatim. The only request-shaping is the `imageSize` validation described above (and NanoBanana being fixed at `1K`).

## Billing

You're billed per generated image, at the same price as the native API. A prompt blocked for safety returns `200` with `finishReason: IMAGE_SAFETY` and **no** image, and is not charged.

## Limits

The request body — prompt plus any base64 input images under `inlineData` — must not exceed **200 MB**. A larger request returns `400 INVALID_ARGUMENT`.

## Next steps

<CardGroup cols={2}>
  <Card title="SDK quickstart" icon="rocket" href="/gemini/SDK">
    Generate, edit, and stream images with the `google-genai` SDK.
  </Card>

  <Card title="Errors" icon="circle-x" href="/concepts/errors#gemini-compatible-api">
    The Gemini error envelope and status codes.
  </Card>
</CardGroup>
