curl --request POST \
--url https://direct.evolink.ai/v1beta/models/{model}:generateContent \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"contents": [
{
"role": "user",
"parts": [
{
"text": "What is the weather in Shanghai today?"
}
]
}
],
"tools": [
{
"googleSearch": {}
}
]
}
'{
"candidates": [
{
"content": {
"role": "model",
"parts": [
{
"text": "Hello! I'm pleased to introduce myself.\n\nI'm a large language model, trained and developed by Google...",
"thought": true,
"thoughtSignature": "<Signature_A>"
}
]
},
"finishReason": "STOP",
"continuationToken": "<string>",
"index": 0,
"safetyRatings": [
{}
]
}
],
"promptFeedback": {
"safetyRatings": [
{}
]
},
"usageMetadata": {
"promptTokenCount": 4,
"candidatesTokenCount": 611,
"totalTokenCount": 2422,
"thoughtsTokenCount": 1807,
"promptTokensDetails": [
{
"modality": "TEXT",
"tokenCount": 4
}
],
"cachedContentTokenCount": 0
},
"modelVersion": "gemini-3.6-flash",
"responseId": "l-LoaPu0BPmo1dkP6ZPHiQc"
}{
"error": {
"code": 400,
"message": "Invalid request parameters",
"type": "invalid_request_error"
}
}{
"error": {
"code": 401,
"message": "Invalid or expired token",
"type": "authentication_error"
}
}{
"error": {
"code": 402,
"message": "Insufficient quota",
"type": "insufficient_quota_error",
"fallback_suggestion": "https://evolink.ai/dashboard/credits"
}
}{
"error": {
"code": 403,
"message": "Access denied for this model",
"type": "permission_error"
}
}{
"error": {
"code": 404,
"message": "Model not found",
"type": "not_found_error"
}
}{
"error": {
"code": 413,
"message": "Request body too large",
"type": "request_too_large_error",
"fallback_suggestion": "reduce file size"
}
}{
"error": {
"code": 429,
"message": "Rate limit exceeded",
"type": "rate_limit_error",
"fallback_suggestion": "retry after 60 seconds"
}
}{
"error": {
"code": 500,
"message": "Internal server error",
"type": "internal_server_error",
"fallback_suggestion": "try again later"
}
}{
"error": {
"code": 502,
"message": "Upstream AI service unavailable",
"type": "upstream_error",
"fallback_suggestion": "try again later"
}
}{
"error": {
"code": 503,
"message": "Service temporarily unavailable",
"type": "service_unavailable_error",
"fallback_suggestion": "retry after 30 seconds"
}
}Gemini All-Model API - Native API Format
Select the Gemini text model to call via {model} in the path (see the reference table for the model parameter for all available values).
- Uses the Google native API format and returns conversation content synchronously
- Plain text / multimodal input: mixed text + image / audio / video input
- Streaming: replace
generateContentin the path withstreamGenerateContent(append?alt=sseto receive SSE)
Model specs and differences
- 3.8 behavior: compared with 3.7, it improves software engineering, agents, multi-step reasoning, and multimodal accuracy; it may consume more reasoning / output tokens, especially at
high. Uselowfor latency-sensitive workloads, the defaultmediumfor general use, andhighfor complex code, long video, or multi-step reasoning. - Gemini 4 Argon behavior: thinking is controlled only through
thinkingConfig.thinkingLevel, withlow/medium/highavailable; when omitted, the model determines how much to think.minimalis not supported (returns 400; uselowinstead), and neither isthinkingBudget(returns 400).temperature/topPoutside the valid range return 400. In multi-turn function calling, thethoughtSignaturereturned in the previous turn must be sent back unchanged, otherwise the request returns 400. Input supports text / images / audio / video / PDF. - Sampling parameters
temperature/topP/topK: consistent across the entire Gemini 3.x series, custom values do not affect the output;topKis ignored and has no effect, and atemperature/topPvalue outside the valid range returns a 400. - Thinking control: the Gemini 3.x / 4 series uses
thinkingConfig.thinkingLevel(see thethinkingLevelparameter for the levels supported and the default of each model); the Gemini 2.5 series usesthinkingConfig.thinkingBudget(an integer,0=off). The two are mutually exclusive.gemini-3.8-flash/gemini-3.7-flashand the Pro models do not supportminimal; a passed value is automatically downgraded tolow. - Function calling: for Gemini 3.x, the
FunctionResponsemust echo back theidandnamematching the correspondingFunctionCall, otherwise the request errors. - Last-turn role: the
roleof the last message must not bemodel(Gemini 3.5+ will error). - Token limits:
gemini-3.8-flash/gemini-3.7-flash/gemini-3.6-flash/gemini-3.5-flash-litehave a 1,048,576-token context and a maximum output of 65,536.gemini-4-argonshares a 1,048,576-token context across input, thinking, and output; each streaming request returns up to 65,536 tokens, or 32,768 non-streaming, including thinking and the answer. Use continuation for longer output; cumulative thinking and answer tokens are limited to the context space remaining after input. See “Long-output continuation” on this page. Other models follow their own specifications. - Gemini 2.5 IDs: from 2026-10-19,
gemini-2.5-pro/gemini-2.5-flash/gemini-2.5-flash-liteare served bygemini-3.8-flash/gemini-3.5-flash-lite/gemini-3.1-flash-lite-previewand billed at their rates; responses show the new model ID, and parameter behavior follows the new model.thinkingBudgetis converted to a level (see thethinkingBudgetparameter).
curl --request POST \
--url https://direct.evolink.ai/v1beta/models/{model}:generateContent \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"contents": [
{
"role": "user",
"parts": [
{
"text": "What is the weather in Shanghai today?"
}
]
}
],
"tools": [
{
"googleSearch": {}
}
]
}
'{
"candidates": [
{
"content": {
"role": "model",
"parts": [
{
"text": "Hello! I'm pleased to introduce myself.\n\nI'm a large language model, trained and developed by Google...",
"thought": true,
"thoughtSignature": "<Signature_A>"
}
]
},
"finishReason": "STOP",
"continuationToken": "<string>",
"index": 0,
"safetyRatings": [
{}
]
}
],
"promptFeedback": {
"safetyRatings": [
{}
]
},
"usageMetadata": {
"promptTokenCount": 4,
"candidatesTokenCount": 611,
"totalTokenCount": 2422,
"thoughtsTokenCount": 1807,
"promptTokensDetails": [
{
"modality": "TEXT",
"tokenCount": 4
}
],
"cachedContentTokenCount": 0
},
"modelVersion": "gemini-3.6-flash",
"responseId": "l-LoaPu0BPmo1dkP6ZPHiQc"
}{
"error": {
"code": 400,
"message": "Invalid request parameters",
"type": "invalid_request_error"
}
}{
"error": {
"code": 401,
"message": "Invalid or expired token",
"type": "authentication_error"
}
}{
"error": {
"code": 402,
"message": "Insufficient quota",
"type": "insufficient_quota_error",
"fallback_suggestion": "https://evolink.ai/dashboard/credits"
}
}{
"error": {
"code": 403,
"message": "Access denied for this model",
"type": "permission_error"
}
}{
"error": {
"code": 404,
"message": "Model not found",
"type": "not_found_error"
}
}{
"error": {
"code": 413,
"message": "Request body too large",
"type": "request_too_large_error",
"fallback_suggestion": "reduce file size"
}
}{
"error": {
"code": 429,
"message": "Rate limit exceeded",
"type": "rate_limit_error",
"fallback_suggestion": "retry after 60 seconds"
}
}{
"error": {
"code": 500,
"message": "Internal server error",
"type": "internal_server_error",
"fallback_suggestion": "try again later"
}
}{
"error": {
"code": 502,
"message": "Upstream AI service unavailable",
"type": "upstream_error",
"fallback_suggestion": "try again later"
}
}{
"error": {
"code": 503,
"message": "Service temporarily unavailable",
"type": "service_unavailable_error",
"fallback_suggestion": "retry after 30 seconds"
}
}generateContent with streamGenerateContent in the URL. Keep the request body unchanged; responses arrive in chunks. Append ?alt=sse to request SSE format.https://direct.evolink.ai, which has better support for text models and long-lived connections. https://api.evolink.ai is the primary endpoint for multimodal services and serves as a fallback address for text models.Long-output continuation (Gemini 4 Argon)
A singlegemini-4-argon streaming request returns up to 65,536 tokens; a non-streaming request returns up to 32,768. Both limits include thinking and answer tokens. Use continuation requests for longer output. Input, thinking, and the answer share a 1,048,576-token context window, so cumulative thinking and answer tokens can only use the space remaining after the input. Only the native API supports continuation; the OpenAI-compatible format does not.
Streaming streamGenerateContent | Non-streaming generateContent | |
|---|---|---|
| Maximum output per request | 65,536 | 32,768 |
| Continuation token at completion | In the final chunk: candidates[0].continuationToken | candidates[0].continuationToken |
- Set
generationConfig.maxOutputTokensabove the per-request cap: above 65,536 for streaming or 32,768 for non-streaming. The parameter accepts up to 1,048,576, but actual output is still limited by the shared context. This is the cumulative thinking and answer budget across all continuation requests. - When
candidates[0].finishReasonisCONTINUATION, generation is not finished. The same candidate includes acontinuationToken. - Resend the original request with the same
contents,systemInstruction,tools, andgenerationConfig. Add only a top-levelcontinuationTokencontaining the latest returned token. - Repeat step 3 only while
finishReasonisCONTINUATION; stop for any other finish reason.STOPmeans normal completion, andMAX_TOKENSmeans the cumulative budget is exhausted. Each response contains only newly generated content; concatenate it in order.
- Do not append partial output to
contentsor send a new prompt such as “continue”. - A request may spend its entire budget on thinking and return empty answer text. Continue if the finish reason is
CONTINUATION. MAX_TOKENSmay also include acontinuationToken. To resume, manually raisemaxOutputTokensand resend the original request with the latest token. Keeping the exhausted budget returns 400. See “Resume after budget exhaustion” below.- For multi-turn conversations, wait for
STOPand then add the combined answer as a singlemodelmessage to the history.
Examples
First request:curl -X POST "https://direct.evolink.ai/v1beta/models/gemini-4-argon:generateContent" \
-H "Authorization: Bearer $EVOLINK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [
{ "role": "user", "parts": [{ "text": "Write a complete design document for a Rust async runtime, including the architecture, scheduler, I/O driver, timers, and complete example code." }] }
],
"generationConfig": {
"maxOutputTokens": 262144,
"thinkingConfig": { "thinkingLevel": "high" }
}
}'
{
"candidates": [
{
"content": {
"role": "model",
"parts": [
{
"text": "# Rust async runtime design\n\n## 1. Architecture\n…"
}
]
},
"finishReason": "CONTINUATION",
"continuationToken": "<a long opaque string; preserve it exactly>"
}
]
}
CONTINUATION, send the same request again with a top-level continuationToken:
curl -X POST "https://direct.evolink.ai/v1beta/models/gemini-4-argon:generateContent" \
-H "Authorization: Bearer $EVOLINK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [
{ "role": "user", "parts": [{ "text": "Write a complete design document for a Rust async runtime, including the architecture, scheduler, I/O driver, timers, and complete example code." }] }
],
"generationConfig": {
"maxOutputTokens": 262144,
"thinkingConfig": { "thinkingLevel": "high" }
},
"continuationToken": "<continuationToken from the previous response>"
}'
CONTINUATION and returns on completion or budget exhaustion. It preserves the latest token and does not raise the budget automatically on MAX_TOKENS:
import os
from copy import deepcopy
import requests
URL = "https://direct.evolink.ai/v1beta/models/gemini-4-argon:generateContent"
HEADERS = {"Authorization": f"Bearer {os.environ['EVOLINK_API_KEY']}"}
def generate_with_continuation(body):
request_body = deepcopy(body)
pieces = []
while True:
# Client read timeout: 1,200 seconds; this does not guarantee a 20-minute server connection.
resp = requests.post(URL, headers=HEADERS, json=request_body, timeout=1200)
resp.raise_for_status()
candidates = resp.json().get("candidates", [])
if not candidates:
raise RuntimeError("No candidates in the response; check promptFeedback.")
candidate = candidates[0]
for part in candidate.get("content", {}).get("parts", []):
if not part.get("thought"):
pieces.append(part.get("text", ""))
reason = candidate.get("finishReason")
token = candidate.get("continuationToken")
if reason == "CONTINUATION":
if not token:
raise RuntimeError("The response requests continuation but has no continuationToken.")
request_body["continuationToken"] = token # Keep all other fields unchanged
continue
return {
"text": "".join(pieces),
"finishReason": reason,
"continuationToken": token,
}
body = {
"contents": [
{"role": "user", "parts": [{"text": "Write a complete design document for a Rust async runtime, including the architecture, scheduler, I/O driver, timers, and complete example code."}]}
],
"generationConfig": {"maxOutputTokens": 262144, "thinkingConfig": {"thinkingLevel": "high"}},
}
result = generate_with_continuation(body)
print(result["text"])
print("finishReason:", result["finishReason"])
if result["finishReason"] == "MAX_TOKENS":
print("The cumulative output budget is exhausted. If a token was returned, you can manually raise maxOutputTokens to resume.")
Resume after budget exhaustion
This example reusesgenerate_with_continuation, URL, and HEADERS above. It generates a number list with a small budget, then explicitly raises the total budget from 64 to 2,048. Keep the original contents and other settings unchanged; add the token and raise the budget to resume at the cutoff.
body = {
"contents": [
{"role": "user", "parts": [{"text": "Output integers 1 through 100, one per line. Start immediately."}]}
],
"generationConfig": {"maxOutputTokens": 64, "thinkingConfig": {"thinkingLevel": "low"}},
}
first = generate_with_continuation(body)
print(first["text"], end="")
if first["finishReason"] == "MAX_TOKENS" and first["continuationToken"]:
body["continuationToken"] = first["continuationToken"]
body["generationConfig"]["maxOutputTokens"] = 2048 # The caller explicitly raises the cumulative budget
resumed = generate_with_continuation(body)
print(resumed["text"], end="")
print("\nfinishReason:", resumed["finishReason"])
else:
print("\nfinishReason:", first["finishReason"])
finishReason: on CONTINUATION, resend the latest token with unchanged settings; on MAX_TOKENS, manually raise the cumulative budget if you want to resume; STOP means normal completion.
Billing and errors
- Each request is billed separately. Continuation requests count the original input and all previously generated content as input again. Portions that hit implicit caching are billed at the cache rate.
- Each response’s
usageMetadatacovers only that request. Add usage across requests for the total. Streaming usage is cumulative within a request: use only the finalusageMetadata, rather than adding cumulative values from the same stream. - For the native API, the output pre-authorization estimate uses the smaller of
maxOutputTokensand 65,536, including for non-streaming requests; input is estimated separately. Non-streaming output is actually capped at 32,768 per request, so budgets above 32,768 may reserve more than an estimate based on the actual per-request cap. Final charges use the response usage. - Invalid tokens return 400. A well-formed but invalid token may return
Invalid continuation token., while malformed tokens may produce another parameter error. Other models ignorecontinuationToken. - Resuming after
MAX_TOKENSwith a token but without raising the exhaustedmaxOutputTokensalso returns 400.
Authorizations
##All APIs require Bearer Token authentication##
Get API Key:
Visit API Key Management Page to get your API Key
Add to request header:
Authorization: Bearer YOUR_API_KEY
Path Parameters
Select the Gemini text model to call:
| Model ID | Series | Positioning |
|---|---|---|
gemini-4-argon | 4 Argon | Long reports and large coding tasks; up to 65,536 tokens per streaming request / 32,768 non-streaming; native API continuation is limited by the shared context |
gemini-3.8-flash | 3.8 Flash | Enhanced software engineering / agents / multi-step reasoning / multimodal accuracy |
gemini-3.7-flash | 3.7 Flash | Pro-level agentic / code generation / terminal execution |
gemini-3.6-flash | 3.6 Flash | Multi-step orchestration / code refactoring / general reasoning |
gemini-3.5-flash | 3.5 Flash | General-purpose Flash |
gemini-3.5-flash-lite | 3.5 Flash-Lite | Low cost / high throughput / lightweight agent |
gemini-3.1-pro-preview | 3.1 Pro (Preview) | Advanced reasoning |
gemini-3.1-pro-preview-customtools | 3.1 Pro · CustomTools | Advanced reasoning + custom tools |
gemini-3.1-flash-lite-preview | 3.1 Flash-Lite (Preview) | Low cost |
gemini-3-pro-preview | 3.0 Pro (Preview) | Advanced reasoning |
gemini-3-flash-preview | 3.0 Flash (Preview) | General-purpose Flash |
gemini-2.5-pro | 2.5 Pro | Legacy ID; from 2026-10-19 served by gemini-3.8-flash and billed at its rates |
gemini-2.5-flash | 2.5 Flash | Legacy ID; from 2026-10-19 served by gemini-3.5-flash-lite and billed at its rates |
gemini-2.5-flash-lite | 2.5 Flash-Lite | Legacy ID; from 2026-10-19 served by gemini-3.1-flash-lite-preview and billed at its rates |
gemini-4-argon, gemini-3.8-flash, gemini-3.7-flash, gemini-3.6-flash, gemini-3.5-flash, gemini-3.5-flash-lite, gemini-3.1-pro-preview, gemini-3.1-pro-preview-customtools, gemini-3.1-flash-lite-preview, gemini-3-pro-preview, gemini-3-flash-preview, gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite "gemini-3.6-flash"
Body
List of conversation contents, supports multi-turn dialogue and multimodal input
1Show child attributes
Show child attributes
System instruction (optional), mainly text content
Show child attributes
Show child attributes
Tools the model may call. Three kinds are supported:
functionDeclarations: function callingcodeExecution: code executiongoogleSearch: web search (Google Search grounding). Pass{"googleSearch": {}}(camelCase; snake_casegoogle_searchreturns 400); available on all Gemini text models.candidates[].groundingMetadatain the response carries the queries and sources; billed per call
[{ "googleSearch": {} }]
Tool calling configuration (optional)
Safety settings list (optional)
Generation configuration parameters (optional)
Show child attributes
Show child attributes
Long-output continuation token (gemini-4-argon only). Put the latest candidates[0].continuationToken at the top level of the request. Preserve the original contents, systemInstruction, and tools; do not append partial output.
CONTINUATION: keep every generation setting unchanged and resend the token.MAX_TOKENS: a token may also be returned; manually raise cumulativemaxOutputTokensbefore resuming, leaving other settings unchanged. Keeping the exhausted budget returns 400.- Invalid tokens return 400.
- Other models ignore this field.
See Native API reference, under “Long-output continuation”.
Cached content name, in the form cachedContents/{cachedContent}
Response
Content generated successfully
Response format description:
- When using the
generateContentendpoint, returnsGenerateContentResponse(returns complete response at once) - When using the
streamGenerateContentendpoint, returnsStreamGenerateContentResponse(streaming response, returns content in chunks)
- Sync Response
- Stream Response