Skip to content
Sign Up Free
API Reference

Gemini API: text and video with BetterToken

Call Gemini through BetterToken with OpenAI Chat Completions or the native Gemini API. Includes authentication, SDKs, streaming, tools, video input, and troubleshooting.

Use gemini-3.8-flash and gemini-4-argon with your BetterToken API Key. Both interfaces support text, video, streaming, and tool calls with tool results.

Choose an interface

InterfaceBase URLWhen to use it
OpenAI-compatiblehttps://bettertoken.ai/v1Your application uses Chat Completions or the OpenAI SDK.
Gemini nativehttps://bettertoken.aiYour application uses Gemini request fields or Google GenAI SDKs.

All examples use gemini-3.8-flash. Replace it with gemini-4-argon to use the other model. For current pricing, see the model plaza. For image generation, see the separate Nano Banana guide.

Authentication

Create a BetterToken API Key, then replace YOUR_API_KEY below. Run this in the same terminal as the examples.

Terminal window
export BETTERTOKEN_API_KEY="YOUR_API_KEY"
InterfaceAuthentication
OpenAI-compatibleAuthorization: Bearer $BETTERTOKEN_API_KEY
Gemini nativex-goog-api-key: $BETTERTOKEN_API_KEY (recommended), or Authorization: Bearer $BETTERTOKEN_API_KEY

A Google AI Studio key does not work here. Use your BetterToken API Key. The native interface also accepts ?key=, but avoid it because URLs can appear in logs.

OpenAI-compatible interface

Send requests to POST https://bettertoken.ai/v1/chat/completions. SDKs use the Base URL https://bettertoken.ai/v1 and append /chat/completions themselves.

curl: basic request

Terminal window
curl --fail-with-body "https://bettertoken.ai/v1/chat/completions" \
-H "Authorization: Bearer $BETTERTOKEN_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"model": "gemini-3.8-flash",
"messages": [{"role": "user", "content": "Explain why the sky is blue."}]
}'

Read text from choices[0].message.content. For curl streaming, add "stream": true to the JSON body and use curl --no-buffer.

Python: basic request and streaming

Install the OpenAI SDK in your Python environment, then run the Python example.

Terminal window
python -m pip install openai

The streaming request uses stream=True. Read text from each chunk’s choices[0].delta.content.

import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["BETTERTOKEN_API_KEY"],
base_url="https://bettertoken.ai/v1",
)
messages = [{"role": "user", "content": "Explain why the sky is blue."}]
response = client.chat.completions.create(
model="gemini-3.8-flash",
messages=messages,
)
print(response.choices[0].message.content)
stream = client.chat.completions.create(
model="gemini-3.8-flash",
messages=messages,
stream=True,
)
for chunk in stream:
if chunk.choices:
print(chunk.choices[0].delta.content or "", end="", flush=True)
print()

Tool calling

Declare functions in tools with type: "function", a function name, and a JSON Schema in parameters. When the assistant returns tool_calls, run the requested functions in your application.

Keep the complete assistant message, including tool_calls, in the conversation. Append a role: "tool" message for each result. Set its tool_call_id to the matching call ID and put the result in content. Send the updated messages and tools to Chat Completions again.

For image input on this interface, use an image_url content part with an HTTP URL or a data URL, as with other models.

Gemini native interface

For Google GenAI SDKs, set Base URL to https://bettertoken.ai. Do not add /v1beta: the SDK appends it. Raw HTTP requests use the full paths below.

curl: generateContent

Terminal window
curl --fail-with-body \
"https://bettertoken.ai/v1beta/models/gemini-3.8-flash:generateContent" \
-H "x-goog-api-key: $BETTERTOKEN_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"contents": [{"role": "user", "parts": [{"text": "Explain why the sky is blue."}]}]
}'

Read text from candidates[].content.parts[].text.

curl: streaming

streamGenerateContent?alt=sse returns Server-Sent Events (SSE). --no-buffer displays events as they arrive.

Terminal window
curl --fail-with-body --no-buffer \
"https://bettertoken.ai/v1beta/models/gemini-3.8-flash:streamGenerateContent?alt=sse" \
-H "x-goog-api-key: $BETTERTOKEN_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"contents": [{"role": "user", "parts": [{"text": "Explain why the sky is blue."}]}]
}'

Python: Google GenAI SDK

Install google-genai in your Python environment. The example makes a basic request followed by a streaming request.

Terminal window
python -m pip install google-genai
import os
from google import genai
from google.genai import types
client = genai.Client(
api_key=os.environ["BETTERTOKEN_API_KEY"],
http_options=types.HttpOptions(base_url="https://bettertoken.ai"),
)
response = client.models.generate_content(
model="gemini-3.8-flash",
contents="Explain why the sky is blue.",
)
print(response.text)
for chunk in client.models.generate_content_stream(
model="gemini-3.8-flash",
contents="Explain why the sky is blue.",
):
print(chunk.text or "", end="", flush=True)
print()

Node.js: Google GenAI SDK

Install @google/genai. Save the JavaScript example as gemini.mjs, then run node gemini.mjs.

Terminal window
npm install @google/genai
import { GoogleGenAI } from "@google/genai";
const client = new GoogleGenAI({
apiKey: process.env.BETTERTOKEN_API_KEY,
httpOptions: { baseUrl: "https://bettertoken.ai" },
});
const response = await client.models.generateContent({
model: "gemini-3.8-flash",
contents: "Explain why the sky is blue.",
});
console.log(response.text);
const stream = await client.models.generateContentStream({
model: "gemini-3.8-flash",
contents: "Explain why the sky is blue.",
});
for await (const chunk of stream) {
process.stdout.write(chunk.text ?? "");
}
console.log();

Tool calling

Declare functions in tools[].functionDeclarations. Read the requested function and arguments from functionCall in the model’s response parts, then run the function in your application.

Keep the complete model content in contents. Append a role: "user" content entry whose parts contain functionResponse with the matching function name and a response object holding the result. Send the updated contents and tools to generateContent again.

List models

Use GET https://bettertoken.ai/v1beta/models to list models.

Terminal window
curl --fail-with-body "https://bettertoken.ai/v1beta/models" \
-H "x-goog-api-key: $BETTERTOKEN_API_KEY"

Video input

Before sending either example, replace REPLACE_WITH_VIDEO_BASE64 with your video’s base64 on a single line. The examples use an MP4 clip; for another format, change the MIME type and filename to match.

Accepted MIME types: video/mp4, video/mpeg, video/mpg, video/mov, video/avi, video/wmv, video/flv, video/mpegps.

Send video inline as base64 in the request body. Base64 makes the body about one third larger than the file. Use short or compressed clips; very large requests can return HTTP 413.

The OpenAI-compatible file.file_data includes the data:video/mp4;base64, prefix. Native inlineData.data contains only base64, without that prefix.

Chat Completions: inline file

Terminal window
curl --fail-with-body "https://bettertoken.ai/v1/chat/completions" \
-H "Authorization: Bearer $BETTERTOKEN_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'JSON'
{
"model": "gemini-3.8-flash",
"messages": [{
"role": "user",
"content": [
{"type": "file", "file": {
"filename": "clip.mp4",
"file_data": "data:video/mp4;base64,REPLACE_WITH_VIDEO_BASE64"
}},
{"type": "text", "text": "Describe what happens in this video."}
]
}]
}
JSON

Gemini native: inlineData

Terminal window
curl --fail-with-body \
"https://bettertoken.ai/v1beta/models/gemini-3.8-flash:generateContent" \
-H "x-goog-api-key: $BETTERTOKEN_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @- <<'JSON'
{
"contents": [{
"role": "user",
"parts": [
{"inlineData": {"mimeType": "video/mp4", "data": "REPLACE_WITH_VIDEO_BASE64"}},
{"text": "Describe what happens in this video."}
]
}]
}
JSON

Usage and billing

Chat Completions: reasoning/thinking tokens are included in completion_tokens and billed as output.

Gemini native: usageMetadata.thoughtsTokenCount is billed as output. cachedContentTokenCount reports cached input. Video counts as input tokens; promptTokensDetails identifies it with modality VIDEO.

Limitations

  • POST /v1/responses does not support these Gemini models. Codex CLI and other clients that only use the Responses API cannot call them. Use Chat Completions or the native interface.
  • file_id references and Google File API uploads using fileData.fileUri are not supported. Send video inline as base64.

Troubleshooting

ErrorWhat to do
401Check the BetterToken API Key and authentication header. Replace a wrong or missing Key.
413The request body is too large. Shorten or compress the video.
429Rate limiting or temporary upstream capacity. Retry with increasing delays (backoff).
503 with model_not_foundNo capacity is available right now. Retry later.

For other errors, see API errors.