Gemini Native
Stream Generate Content
Streams content generation using Google Gemini API format
SSE version of Gemini generateContent. Events may contain only metadata or intermediate content without finishReason. The stream ends at natural EOF and does not append a [DONE] marker.
Path Parameters
Model name (e.g., gemini-2.5-pro, gemini-3.5-flash).
Query Parameters
API key (alternative to header authentication).
Request Body
Same as Generate Content. This includes multimodal parts arrays with structured inline_data image parts for vision requests.
Support for generationConfig.candidateCount, tools, media types, and other optional fields depends on the selected model.
Response
Returns Gemini Server-Sent Events. Metadata-only events, intermediate chunks without finishReason, and natural EOF are valid. The stream does not append Chat Completions' [DONE] sentinel.
Request
curl -N -X POST "https://api.tokenlab.sh/v1beta/models/gemini-2.5-pro:streamGenerateContent?key=sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"contents": [
{
"parts": [{"text": "Tell me a story"}]
}
]
}'import google.generativeai as genai
genai.configure(
api_key="sk-your-api-key",
transport="rest",
client_options={"api_endpoint": "api.tokenlab.sh"}
)
model = genai.GenerativeModel("gemini-2.5-pro")
response = model.generate_content("Tell me a story", stream=True)
for chunk in response:
for candidate in chunk.candidates:
for part in candidate.content.parts:
if part.text:
print(part.text, end="")const response = await fetch(
'https://api.tokenlab.sh/v1beta/models/gemini-2.5-pro:streamGenerateContent?key=sk-your-api-key',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
contents: [{ parts: [{ text: 'Tell me a story' }] }]
})
}
);
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
console.log(decoder.decode(value, { stream: true }));
}package main
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
payload := map[string]interface{}{
"contents": []map[string]interface{}{
{"parts": []map[string]string{{"text": "Tell me a story"}}},
},
}
jsonData, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST",
"https://api.tokenlab.sh/v1beta/models/gemini-2.5-pro:streamGenerateContent?key=sk-your-api-key",
bytes.NewBuffer(jsonData))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
scanner := bufio.NewScanner(resp.Body)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
}<?php
$payload = [
'contents' => [
['parts' => [['text' => 'Tell me a story']]]
]
];
$ch = curl_init('https://api.tokenlab.sh/v1beta/models/gemini-2.5-pro:streamGenerateContent?key=sk-your-api-key');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_WRITEFUNCTION => function($ch, $data) {
echo $data;
return strlen($data);
}
]);
curl_exec($ch);
curl_close($ch);Vision Input Example
Streaming vision requests use the same contents[].parts[] structure as the non-streaming endpoint.
{
"contents": [
{
"role": "user",
"parts": [
{ "text": "Please describe this image." },
{
"inline_data": {
"mime_type": "image/jpeg",
"data": "/9j/4AAQSkZJRgABAQ..."
}
}
]
}
]
}Response
{
"candidates": [
{
"content": {
"role": "model",
"parts": [
{"text": "Once upon a time"}
]
}
}
]
}Authorization
BearerAuth API Key authentication. Create or manage API keys in Dashboard > API > API Keys.
In: header
Path Parameters
Model name (e.g., gemini-2.5-pro)
Query Parameters
API key (alternative to header auth)
Headers
Per-request Delivery policy. Overrides the API key and Workspace defaults. Auto tries TokenLab Verified first and may switch once to Official only before output, request acceptance, or persistent resource creation.
Value in
- "auto"
- "verified"
- "official"
Request Body
application/json
Native Gemini GenerateContent request. ProtoJSON lowerCamelCase and original proto snake_case names are both accepted and preserved, including mixed requests. If both spellings of one field are present, TokenLab does not merge them or choose a local precedence. Unknown fields are forwarded on a best-effort basis.
Response
text/event-stream
application/json
application/json
application/json
application/json
application/json