> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.beatapi.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.beatapi.io/_mcp/server.

# Gemini native

POST https://direct.beatapi.io/v1beta/models/{model}:generateContent
Content-Type: application/json

Call Gemini 4 Argon, Gemini 3.8 Flash and Gemini 3.1 Pro with Gemini generateContent requests and one BeatAPI key.- `POST /v1beta/models/{model}:generateContent`, and `:streamGenerateContent?alt=sse` for streaming, for every current Gemini model.
- Text and image input, text output, streaming, function calling and thinking.
- Send the key in the `x-goog-api-key` header or as a Bearer token.
- The model is in the URL, not in the body.Use `https://direct.beatapi.io` as the base URL for text requests: it is not subject to Cloudflare's 100-second limit, so a long non-streaming request is not cut off. `https://api.beatapi.io` also works and is the fallback if `direct.beatapi.io` is unreachable from your network. The key, models and prices are the same on both. Image and video APIs use `https://api.beatapi.io` only.POST/v1beta/models/{model}:generateContentTry itOpens this endpoint in the API Explorer. Enter your BeatAPI API key and send: the call is real and is billed to your own balance.## ModelsPut one of these IDs in the URL, in place of `{model}`.| Model ID                 | Context (tokens) | Max output (tokens) | Positioning                                                                                                                                  | Input, USD per 1M tokens | Output, USD per 1M tokens |
| ------------------------ | ---------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | ------------------------- |
| `gemini-4-argon`         | —                | 1,000,000           | Google's Gemini 4 flagship model, with an output limit of up to 1M tokens.                                                                   | \$1.00                   | \$5.00                    |
| `gemini-3.8-flash`       | —                | —                   | Google's most intelligent Flash model, engineered for long-horizon software engineering, autonomous agents, and complex enterprise workflows | \$0.375                  | \$1.875                   |
| `gemini-3.1-pro-preview` | 1,048,576        | 65,536              | Reasoning-first Gemini preview for agentic coding and complex problem solving                                                                | \$1.00                   | \$6.00                    |- Prices are the base tier, discount already applied. A long-context tier, cached-input rates and cache writes are not in this table; see the [price table](https://beatapi.io/pricing).
- `—` means the catalogue does not publish the number.Older IDs of this family still work and are listed on [Legacy models](/text-api/legacy-models).## Quick startKeep the key in `BEATAPI_API_KEY` and never put it in browser code. The model ID goes in the URL, so the body has no `model` field. These are request examples, not recorded model outputs.Read the answer from `candidates[0].content.parts[0].text`, then check `candidates[0].finishReason` and `usageMetadata`. An HTTP 200 alone does not prove the answer satisfies your task: validate it in your application. Text requests return directly; do not poll `/v1/tasks` for them.```bash title="cURL"
curl --request POST \
  --url https://direct.beatapi.io/v1beta/models/gemini-3.8-flash:generateContent \
  --header "x-goog-api-key: $BEATAPI_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "text": "Design a resilient webhook retry strategy for a payments API."
        }
      ]
    }
  ]
}'
``````python title="Python"
import os
import requests

response = requests.post(
    "https://direct.beatapi.io/v1beta/models/gemini-3.8-flash:generateContent",
    headers={"x-goog-api-key": os.environ["BEATAPI_API_KEY"]},
    json={
      "contents": [
        {
          "role": "user",
          "parts": [
            {
              "text": "Design a resilient webhook retry strategy for a payments API."
            }
          ]
        }
      ]
    },
    timeout=120,
)
response.raise_for_status()
print(response.json()["candidates"][0]["content"]["parts"][0]["text"])
``````javascript title="JavaScript"
const response = await fetch("https://direct.beatapi.io/v1beta/models/gemini-3.8-flash:generateContent", {
  method: "POST",
  headers: {
    "x-goog-api-key": process.env.BEATAPI_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "contents": [
      {
        "role": "user",
        "parts": [
          {
            "text": "Design a resilient webhook retry strategy for a payments API."
          }
        ]
      }
    ]
  }),
});
if (!response.ok) throw new Error(await response.text());
const data = await response.json();
console.log(data.candidates[0].content.parts[0].text);
```## Endpoint and authentication`POST https://direct.beatapi.io/v1beta/models/{model}:generateContent`x-goog-api-key
string
RequiredYour BeatAPI key in the `x-goog-api-key` header. `Authorization: Bearer <BEATAPI_API_KEY>` is also accepted.For streaming, call `POST /v1beta/models/{model}:streamGenerateContent?alt=sse`. The key goes in the `x-goog-api-key` header or in `Authorization: Bearer <key>`; both work.`:countTokens` is not available and returns `404`.## Request parametersThese are the fields that take effect. Other Gemini fields are accepted in the request but have no effect: `generationConfig.thinkingConfig`, `generationConfig.responseMimeType`, `generationConfig.responseSchema`, `generationConfig.seed`, `safetySettings`, `toolConfig` and `cachedContent`. Do not rely on them.contents
object[]
RequiredThe conversation, oldest turn first. Each item has a `role` (`user` or `model`) and `parts`. A part is `text`, `inlineData` (`mimeType` and base64 `data`), `fileData` (`mimeType` and `fileUri`), `functionCall` or `functionResponse`.- Image input is supported by every current Gemini model; use `inlineData`, or `fileData` with an image URL. For other media, test your file type before you depend on it.
- An empty or missing `contents` is `400 bad_request`.**Example**```json
[
  {
    "role": "user",
    "parts": [
      { "text": "What is in this image?" },
      { "inlineData": { "mimeType": "image/png", "data": "<base64>" } }
    ]
  }
]
```systemInstruction
object
OptionalSystem prompt, as `{ "parts": [{ "text": "..." }] }`. Only `text` parts are used.**Example**```json
{
  "parts": [{ "text": "Answer in one short paragraph." }]
}
```generationConfig
object
OptionalGeneration options. These subfields take effect: `maxOutputTokens`, `temperature`, `topP`, `topK`, `stopSequences` and `candidateCount`.**Example**```json
{
  "temperature": 0.7,
  "topP": 0.95,
  "maxOutputTokens": 2048,
  "stopSequences": ["END"]
}
```generationConfig.maxOutputTokens
integer
OptionalUpper bound on the generated tokens, thinking included.- The largest accepted value is 1,073,741,823; a larger value is `400 bad_request`. Keep it at or below the max output of the model in the table above.
- Gemini models think by default, and thinking tokens are billed as output and count toward this limit. A small value can be used up by thinking, leaving an empty answer with `finishReason: "MAX_TOKENS"`. Budget at least 1,000 tokens for a short answer.
- `maxOutputTokens` is also used to estimate how much balance a request needs. A very large value can be refused with `402 insufficient_credits` even when the real output would be small. Set it to what you need.generationConfig.temperature
number
OptionalSampling temperature.generationConfig.topP
number
OptionalNucleus sampling. A value of `0` is ignored.generationConfig.topK
integer
OptionalTop-K sampling. A value of `0` is ignored.generationConfig.stopSequences
string[]
OptionalStrings that stop generation. At most 4 are used.generationConfig.candidateCount
integer
OptionalNumber of candidates to return. Leave it unset unless you need more than one.tools
object[]
OptionalFunction declarations the model may call, as `[{ "functionDeclarations": [...] }]`. Each declaration has a `name`, a `description` and `parameters` (JSON Schema). A call comes back as a `functionCall` part; return the result as a `functionResponse` part in the next `user` turn.- Only `functionDeclarations` are used. Built-in tools such as `googleSearch` and `codeExecution` are ignored.**Example**```json
[
  {
    "functionDeclarations": [
      {
        "name": "get_weather",
        "description": "Get the current weather for a city.",
        "parameters": {
          "type": "object",
          "properties": { "city": { "type": "string" } },
          "required": ["city"]
        }
      }
    ]
  }
]
```## ResponseA non-streaming call returns one JSON object. This is an abbreviated example.```json
{
  "candidates": [
    {
      "content": {
        "role": "model",
        "parts": [
          {
            "text": "Retry with exponential backoff and jitter, and make every handler idempotent."
          }
        ]
      },
      "finishReason": "STOP",
      "index": 0
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 19,
    "candidatesTokenCount": 16,
    "totalTokenCount": 120,
    "thoughtsTokenCount": 85
  }
}
```### Response fields| Field                                       | Type      | Description                                                                                                                          |
| ------------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `candidates[].content.parts[].text`         | `string`  | The answer text.                                                                                                                     |
| `candidates[].content.parts[].functionCall` | `object`  | A tool call, with `name` and `args`.                                                                                                 |
| `candidates[].finishReason`                 | `string`  | `STOP` for a complete answer or a tool call, `MAX_TOKENS` when `maxOutputTokens` was reached, `SAFETY` when the answer was filtered. |
| `usageMetadata.promptTokenCount`            | `integer` | Input tokens.                                                                                                                        |
| `usageMetadata.candidatesTokenCount`        | `integer` | Output tokens of the visible answer.                                                                                                 |
| `usageMetadata.thoughtsTokenCount`          | `integer` | Thinking tokens. They are billed as output. The thinking text itself is not returned.                                                |
| `usageMetadata.totalTokenCount`             | `integer` | All tokens of the call.                                                                                                              |## StreamingCall `:streamGenerateContent?alt=sse`. Every event is a line `data: {...}` holding a `candidates` object, in the same shape as a non-streaming answer.- The last event carries `finishReason`, for example `"STOP"`.
- The response is `text/event-stream`. A failure before the model is called is returned as a normal JSON error with an HTTP status, not as a stream event.
- Set explicit timeouts and reconnect a streamed response safely.```text
data: {"candidates":[{"content":{"role":"model","parts":[{"text":"Retry"}]},"index":0}]}

data: {"candidates":[{"content":{"role":"model","parts":[{"text":" with backoff"}]},"finishReason":"STOP","index":0}],"usageMetadata":{"promptTokenCount":19,"candidatesTokenCount":16,"totalTokenCount":120,"thoughtsTokenCount":85}}
```## Errors| Error or symptom                                      | Cause                                                                                                         | Fix                                                                          |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `400`: `contents` is required                         | `contents` is empty or absent.                                                                                | Send at least one turn in `contents`.                                        |
| `400`: `maxOutputTokens` is invalid                   | `generationConfig.maxOutputTokens` is above 1,073,741,823.                                                    | Lower it to what you need.                                                   |
| `402 insufficient_credits`                            | Balance below the price of the request, often because `maxOutputTokens` is very large.                        | Top up, or lower `maxOutputTokens`.                                          |
| `403 forbidden`                                       | The account is on free credit and the model is not on the free list, or the model is outside the key's group. | Top up, use a free model, or use a key whose group can reach the model.      |
| `404 not_found`                                       | Unknown model ID, not enabled for this key, or the `:countTokens` action.                                     | List the enabled models with `GET /v1/models`.                               |
| `429 rate_limit_exceeded`                             | Account or free-model limit reached.                                                                          | Wait `Retry-After`, then retry.                                              |
| `200` with `finishReason: "MAX_TOKENS"` and no `text` | Thinking used up `maxOutputTokens` before the answer was written.                                             | Raise `generationConfig.maxOutputTokens`; at least 1,000 for a short answer. |### HTTP errors at a glanceErrors on the Gemini-native endpoint have one shape, `{"error": {"message", "type": "beatapi_error", "code"}}`: the code is in `error.code`, the request id ends `message`, and there is no `retryable` field. See [Errors](/errors#text-endpoints).| HTTP status | Code                                                       | What to do                                                                                   |
| ----------- | ---------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| 400         | `bad_request`, `content_policy_violation`                  | Fix the request or the input; do not resend it unchanged.                                    |
| 401         | `missing_api_key`, `invalid_api_key`                       | Check the key. Do not retry.                                                                 |
| 402         | `insufficient_credits`                                     | Top up, or raise the key's limit. A very large `max_tokens` can trigger it.                  |
| 403         | `forbidden`                                                | The model is outside the key's group or IP allowlist, or free credit cannot call this model. |
| 404         | `not_found`                                                | Unknown model: list the enabled ones with `GET /v1/models`.                                  |
| 429         | `rate_limit_exceeded`                                      | Wait `Retry-After` or `retry_after_seconds`, then retry with backoff.                        |
| 500         | `internal_error`, `temporary_error`                        | Retry once or twice with backoff.                                                            |
| 503         | `model_unavailable`, `upstream_timeout`, `temporary_error` | Retry with backoff, or use another model.                                                    |Full code table and retry policy: [Errors](/errors#text-endpoints).## Notes- Gemini models also answer on Chat Completions, Responses and Anthropic Messages. See the other Gemini pages.
- Thinking tokens are billed as output tokens. Budget output for thinking plus the answer, not just the answer.
- Keep API keys on trusted servers, log the response request ID, and retry only `429`, `500` and `503`.

Reference: https://docs.beatapi.io/api-reference/text-api/gemini-native

## Authentication

- `Authorization` header (bearer token, required) — Send your API key as `Authorization: Bearer <BEATAPI_API_KEY>`.

## Servers

- `https://direct.beatapi.io` (Direct, default)
- `https://api.beatapi.io` (API)

## Request

### Path parameters

- `model` (enum, required)
  - Allowed values: `gemini-4-argon`, `gemini-3.8-flash`, `gemini-3.1-pro-preview`

### Body (application/json)

This endpoint expects an object.

- `contents` (list of V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaContentsItems, required) — The conversation, oldest turn first. Each item has a `role` (`user` or `model`) and `parts`. A part is `text`, `inlineData` (`mimeType` and base64 `data`), `fileData` (`mimeType` and `fileUri`), `functionCall` or `functionResponse`. Image input is supported by every current Gemini model; use `inlineData`, or `fileData` with an image URL. For other media, test your file type before you depend on it. An empty or missing `contents` is `400 bad_request`.
- `systemInstruction` (V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaSystemInstruction, optional) — System prompt, as `{ "parts": [{ "text": "..." }] }`. Only `text` parts are used.
- `generationConfig` (V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaGenerationConfig, optional) — Generation options. These subfields take effect: `maxOutputTokens`, `temperature`, `topP`, `topK`, `stopSequences` and `candidateCount`.
- `tools` (list of V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaToolsItems, optional) — Function declarations the model may call, as `[{ "functionDeclarations": [...] }]`. Each declaration has a `name`, a `description` and `parameters` (JSON Schema). A call comes back as a `functionCall` part; return the result as a `functionResponse` part in the next `user` turn. Only `functionDeclarations` are used. Built-in tools such as `googleSearch` and `codeExecution` are ignored.

## Response

### 200

A non-streaming call returns one JSON object. This is an abbreviated example.

- `candidates` (list of V1BetaModelsModelGenerateContentPostResponsesContentApplicationJsonSchemaCandidatesItems, optional)
- `usageMetadata` (V1BetaModelsModelGenerateContentPostResponsesContentApplicationJsonSchemaUsageMetadata, optional)

## Errors

### 400 Bad Request Error

`bad_request`, `content_policy_violation` Fix the request or the input; do not resend it unchanged. Errors on the Gemini-native endpoint have one shape, `{"error": {"message", "type": "beatapi_error", "code"}}`: the code is in `error.code`, the request id ends `message`, and there is no `retryable` field. See [Errors](/errors#text-endpoints).

- `map from string to any`

### 401 Unauthorized Error

`missing_api_key`, `invalid_api_key` Check the key. Do not retry. Errors on the Gemini-native endpoint have one shape, `{"error": {"message", "type": "beatapi_error", "code"}}`: the code is in `error.code`, the request id ends `message`, and there is no `retryable` field. See [Errors](/errors#text-endpoints).

- `map from string to any`

### 402 Payment Required Error

`insufficient_credits` Top up, or raise the key's limit. A very large `max_tokens` can trigger it. Errors on the Gemini-native endpoint have one shape, `{"error": {"message", "type": "beatapi_error", "code"}}`: the code is in `error.code`, the request id ends `message`, and there is no `retryable` field. See [Errors](/errors#text-endpoints).

- `map from string to any`

### 403 Forbidden Error

`forbidden` The model is outside the key's group or IP allowlist, or free credit cannot call this model. Errors on the Gemini-native endpoint have one shape, `{"error": {"message", "type": "beatapi_error", "code"}}`: the code is in `error.code`, the request id ends `message`, and there is no `retryable` field. See [Errors](/errors#text-endpoints).

- `map from string to any`

### 404 Not Found Error

`not_found` Unknown model: list the enabled ones with `GET /v1/models`. Errors on the Gemini-native endpoint have one shape, `{"error": {"message", "type": "beatapi_error", "code"}}`: the code is in `error.code`, the request id ends `message`, and there is no `retryable` field. See [Errors](/errors#text-endpoints).

- `map from string to any`

### 429 Too Many Requests Error

`rate_limit_exceeded` Wait `Retry-After` or `retry_after_seconds`, then retry with backoff. Errors on the Gemini-native endpoint have one shape, `{"error": {"message", "type": "beatapi_error", "code"}}`: the code is in `error.code`, the request id ends `message`, and there is no `retryable` field. See [Errors](/errors#text-endpoints).

- `map from string to any`

### 500 Internal Server Error

`internal_error`, `temporary_error` Retry once or twice with backoff. Errors on the Gemini-native endpoint have one shape, `{"error": {"message", "type": "beatapi_error", "code"}}`: the code is in `error.code`, the request id ends `message`, and there is no `retryable` field. See [Errors](/errors#text-endpoints).

- `map from string to any`

### 503 Service Unavailable Error

`model_unavailable`, `upstream_timeout`, `temporary_error` Retry with backoff, or use another model. Errors on the Gemini-native endpoint have one shape, `{"error": {"message", "type": "beatapi_error", "code"}}`: the code is in `error.code`, the request id ends `message`, and there is no `retryable` field. See [Errors](/errors#text-endpoints).

- `map from string to any`

## Types

### V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaContentsItems

- `parts` (list of V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaContentsItemsPartsItems, required)
- `role` (string, optional)

### V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaSystemInstruction

System prompt, as `{ "parts": [{ "text": "..." }] }`. Only `text` parts are used.

### V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaGenerationConfig

Generation options. These subfields take effect: `maxOutputTokens`, `temperature`, `topP`, `topK`, `stopSequences` and `candidateCount`.

- `maxOutputTokens` (integer, optional) — Upper bound on the generated tokens, thinking included. The largest accepted value is 1,073,741,823; a larger value is `400 bad_request`. Keep it at or below the max output of the model in the table above. Gemini models think by default, and thinking tokens are billed as output and count toward this limit. A small value can be used up by thinking, leaving an empty answer with `finishReason: "MAX_TOKENS"`. Budget at least 1,000 tokens for a short answer. `maxOutputTokens` is also used to estimate how much balance a request needs. A very large value can be refused with `402 insufficient_credits` even when the real output would be small. Set it to what you need.
- `temperature` (double, optional) — Sampling temperature.
- `topP` (double, optional) — Nucleus sampling. A value of `0` is ignored.
- `topK` (integer, optional) — Top-K sampling. A value of `0` is ignored.
- `stopSequences` (list of string, optional) — Strings that stop generation. At most 4 are used.
- `candidateCount` (integer, optional) — Number of candidates to return. Leave it unset unless you need more than one.

### V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaToolsItems

### V1BetaModelsModelGenerateContentPostResponsesContentApplicationJsonSchemaCandidatesItems

- `content` (V1BetaModelsModelGenerateContentPostResponsesContentApplicationJsonSchemaCandidatesItemsContent, optional)
- `finishReason` (string, optional) — `STOP` for a complete answer or a tool call, `MAX_TOKENS` when `maxOutputTokens` was reached, `SAFETY` when the answer was filtered.

### V1BetaModelsModelGenerateContentPostResponsesContentApplicationJsonSchemaUsageMetadata

- `promptTokenCount` (integer, optional) — Input tokens.
- `candidatesTokenCount` (integer, optional) — Output tokens of the visible answer.
- `thoughtsTokenCount` (integer, optional) — Thinking tokens. They are billed as output. The thinking text itself is not returned.
- `totalTokenCount` (integer, optional) — All tokens of the call.

### V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaContentsItemsPartsItems

- `text` (string, optional)
- `inlineData` (V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaContentsItemsPartsItemsInlineData, optional)
- `fileData` (V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaContentsItemsPartsItemsFileData, optional)
- `functionCall` (V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaContentsItemsPartsItemsFunctionCall, optional)
- `functionResponse` (V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaContentsItemsPartsItemsFunctionResponse, optional)

### V1BetaModelsModelGenerateContentPostResponsesContentApplicationJsonSchemaCandidatesItemsContent

- `parts` (list of V1BetaModelsModelGenerateContentPostResponsesContentApplicationJsonSchemaCandidatesItemsContentPartsItems, optional)

### V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaContentsItemsPartsItemsInlineData

- `mimeType` (string, optional)
- `data` (string, optional)

### V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaContentsItemsPartsItemsFileData

- `mimeType` (string, optional)
- `fileUri` (string, optional)

### V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaContentsItemsPartsItemsFunctionCall

### V1BetaModelsModelGenerateContentPostRequestBodyContentApplicationJsonSchemaContentsItemsPartsItemsFunctionResponse

### V1BetaModelsModelGenerateContentPostResponsesContentApplicationJsonSchemaCandidatesItemsContentPartsItems

- `text` (string, optional) — The answer text.
- `functionCall` (V1BetaModelsModelGenerateContentPostResponsesContentApplicationJsonSchemaCandidatesItemsContentPartsItemsFunctionCall, optional) — A tool call, with `name` and `args`.

### V1BetaModelsModelGenerateContentPostResponsesContentApplicationJsonSchemaCandidatesItemsContentPartsItemsFunctionCall

A tool call, with `name` and `args`.

## Examples

**Request**

```json
{
  "contents": [
    {
      "parts": [
        {
          "text": "Design a resilient webhook retry strategy for a payments API."
        }
      ],
      "role": "user"
    }
  ]
}
```

**Response**

```json
{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "text": "Retry with exponential backoff and jitter, and make every handler idempotent."
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP",
      "index": 0
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 19,
    "candidatesTokenCount": 16,
    "thoughtsTokenCount": 85,
    "totalTokenCount": 120
  }
}
```

**SDK Code**

```python Quick start
import requests

url = "https://direct.beatapi.io/v1beta/models/gemini-3.8-flash:generateContent"

payload = { "contents": [
        {
            "parts": [{ "text": "Design a resilient webhook retry strategy for a payments API." }],
            "role": "user"
        }
    ] }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Quick start
const url = 'https://direct.beatapi.io/v1beta/models/gemini-3.8-flash:generateContent';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"contents":[{"parts":[{"text":"Design a resilient webhook retry strategy for a payments API."}],"role":"user"}]}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Quick start
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://direct.beatapi.io/v1beta/models/gemini-3.8-flash:generateContent"

	payload := strings.NewReader("{\n  \"contents\": [\n    {\n      \"parts\": [\n        {\n          \"text\": \"Design a resilient webhook retry strategy for a payments API.\"\n        }\n      ],\n      \"role\": \"user\"\n    }\n  ]\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Quick start
require 'uri'
require 'net/http'

url = URI("https://direct.beatapi.io/v1beta/models/gemini-3.8-flash:generateContent")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"contents\": [\n    {\n      \"parts\": [\n        {\n          \"text\": \"Design a resilient webhook retry strategy for a payments API.\"\n        }\n      ],\n      \"role\": \"user\"\n    }\n  ]\n}"

response = http.request(request)
puts response.read_body
```

```java Quick start
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://direct.beatapi.io/v1beta/models/gemini-3.8-flash:generateContent")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"contents\": [\n    {\n      \"parts\": [\n        {\n          \"text\": \"Design a resilient webhook retry strategy for a payments API.\"\n        }\n      ],\n      \"role\": \"user\"\n    }\n  ]\n}")
  .asString();
```

```php Quick start
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://direct.beatapi.io/v1beta/models/gemini-3.8-flash:generateContent', [
  'body' => '{
  "contents": [
    {
      "parts": [
        {
          "text": "Design a resilient webhook retry strategy for a payments API."
        }
      ],
      "role": "user"
    }
  ]
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Quick start
using RestSharp;

var client = new RestClient("https://direct.beatapi.io/v1beta/models/gemini-3.8-flash:generateContent");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"contents\": [\n    {\n      \"parts\": [\n        {\n          \"text\": \"Design a resilient webhook retry strategy for a payments API.\"\n        }\n      ],\n      \"role\": \"user\"\n    }\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Quick start
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["contents": [
    [
      "parts": [["text": "Design a resilient webhook retry strategy for a payments API."]],
      "role": "user"
    ]
  ]] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://direct.beatapi.io/v1beta/models/gemini-3.8-flash:generateContent")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```