Gemini Scraper API
Send a prompt to Google Gemini and get the assistant reply, grounding sources, and model label as structured JSON
The Gemini API takes a single text prompt and returns Gemini's reply from gemini.google.com as structured JSON. One GET request, no Google account, no cookies, and no browser automation on your side.
curl "https://api.scrape.do/plugin/gemini/chat?token=$TOKEN&q=ping"Credit Usage: Each successful request costs 25 credits. Failed requests are not charged, and there is no render fee.
Key Features
- One-shot prompt-to-reply: send a prompt, get the full reply back in a single HTTP call.
- Markdown-clean output:
output.textis the reply as Markdown — headings, tables, lists, and code blocks are preserved, while frontend-only placeholders (inline image widgets, card references) are stripped. - Grounding sources: when Gemini grounds an answer on the web, the external links it used come back as a flat
sources[]array. - Prompt language sets reply language: Gemini answers in the language your prompt is written in, so ask in German to get a German reply.
- Stateless from your side: every call is an independent, fresh conversation. No login, no token refresh, nothing to keep between calls.
- No render fee: the per-call price covers everything; you do not pay a rendering surcharge.
Endpoint
GET https://api.scrape.do/plugin/gemini/chatBasic Example
curl --location --request GET 'https://api.scrape.do/plugin/gemini/chat?token=<SDO-token>&q=Explain+quantum+entanglement+in+one+sentence'import requests
import json
token = "<SDO-token>"
url = f"https://api.scrape.do/plugin/gemini/chat?token={token}&q=Explain+quantum+entanglement+in+one+sentence"
response = requests.request("GET", url)
print(json.dumps(response.json(), indent=2))const axios = require('axios');
const token = "<SDO-token>";
const url = `https://api.scrape.do/plugin/gemini/chat?token=${token}&q=Explain+quantum+entanglement+in+one+sentence`;
axios.get(url)
.then(response => {
console.log(JSON.stringify(response.data, null, 2));
})
.catch(error => {
console.error(error);
});package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
token := "<SDO-token>"
url := fmt.Sprintf(
"https://api.scrape.do/plugin/gemini/chat?token=%s&q=Explain+quantum+entanglement+in+one+sentence",
token,
)
resp, err := http.Get(url)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println(string(body))
}require 'net/http'
require 'json'
token = "<SDO-token>"
url = URI("https://api.scrape.do/plugin/gemini/chat?token=#{token}&q=Explain+quantum+entanglement+in+one+sentence")
response = Net::HTTP.get(url)
puts JSON.pretty_generate(JSON.parse(response))import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class GeminiChat {
public static void main(String[] args) throws Exception {
String token = "<SDO-token>";
String url = String.format(
"https://api.scrape.do/plugin/gemini/chat?token=%s&q=Explain+quantum+entanglement+in+one+sentence",
token
);
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestMethod("GET");
BufferedReader reader = new BufferedReader(
new InputStreamReader(conn.getInputStream())
);
String line;
StringBuilder response = new StringBuilder();
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
System.out.println(response.toString());
}
}using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
string token = "<SDO-token>";
string url = $"https://api.scrape.do/plugin/gemini/chat?token={token}&q=Explain+quantum+entanglement+in+one+sentence";
using HttpClient client = new HttpClient();
string response = await client.GetStringAsync(url);
Console.WriteLine(response);
}
}<?php
$token = "<SDO-token>";
$url = "https://api.scrape.do/plugin/gemini/chat?token={$token}&q=Explain+quantum+entanglement+in+one+sentence";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo json_encode(json_decode($response), JSON_PRETTY_PRINT);
?>curl "https://api.scrape.do/plugin/gemini/chat?token=$TOKEN&q=Explain+quantum+entanglement+in+one+sentence"Request Parameters
Required
| Parameter | Type | Description |
|---|---|---|
token | string | Your Scrape.do API authentication token |
q | string | Prompt text to send to Gemini. Maximum 4000 characters. URL-encode multi-word prompts |
Parameter names are case-insensitive, so Q works the same as q.
Example Requests
# Basic prompt
curl "https://api.scrape.do/plugin/gemini/chat?q=hello&token=$TOKEN"
# Multi-word prompt (URL-encode)
curl --get "https://api.scrape.do/plugin/gemini/chat" \
--data-urlencode "q=Write a haiku about the ocean" \
--data-urlencode "token=$TOKEN"
# German prompt gets a German reply
curl --get "https://api.scrape.do/plugin/gemini/chat" \
--data-urlencode "q=Was sind die wichtigsten Nachrichten heute" \
--data-urlencode "token=$TOKEN"
# Prompt that tends to produce grounded answers with sources
curl --get "https://api.scrape.do/plugin/gemini/chat" \
--data-urlencode "q=Latest developments in AI with sources" \
--data-urlencode "token=$TOKEN"Response
Top-Level Structure
{
"prompt": "Latest developments in AI with sources",
"output": {
"text": "AI development has shifted toward autonomous agents...\n\n## 1. Agentic AI\n..."
},
"sources": [
"https://openai.com/index/...",
"https://www.whitehouse.gov/presidential-actions/2026/06/..."
],
"model": "3.5 Flash"
}Fields
| Field | Type | Description |
|---|---|---|
prompt | string | Echo of the prompt you submitted |
output.text | string | The reply as Markdown — headings, tables, lists, and code blocks are preserved for rich answers (comparisons, recipes, product round-ups). Frontend-only placeholders such as inline image widgets and card references are removed |
sources | string[] | External links Gemini grounded the answer on, deduplicated and in the order they appear. Best-effort; omitted entirely when the answer was not grounded on external pages |
model | string | Label of the model that produced the reply, such as "3.5 Flash". Omitted when Gemini does not report it |
prompt and output.text are always present on a 200. sources and model are omitted rather than returned empty, so treat both as optional in your parser.
Example
{
"prompt": "Explain quantum entanglement in one sentence",
"output": {
"text": "Quantum entanglement is a phenomenon where two or more particles share a single quantum state, so measuring one instantly determines the corresponding property of the other, no matter how far apart they are."
},
"model": "3.5 Flash"
}A grounded answer additionally carries sources:
{
"prompt": "Who won the last Formula 1 race and where",
"output": {
"text": "## Latest Race Result\n\n| Position | Driver | Team |\n|---|---|---|\n| 1 | ... | ... |\n\nThe race was held at ..."
},
"sources": [
"https://www.formula1.com/en/results/...",
"https://www.autosport.com/f1/news/..."
],
"model": "3.5 Flash"
}Notes
- Prompt limit is 4000 characters. Longer prompts are rejected before the call runs, so no credits are spent on them.
- No multi-turn state. One call returns one reply; to follow up, include the prior context inside the new
q. - Reply language follows the prompt. The reply is written in the language of your prompt. Grounding sources may still be a globally mixed set, because Gemini decides which pages to cite.
- Markdown, not HTML.
output.textis Markdown. Render it with any Markdown renderer; there is no separate HTML field. sourcesis best-effort. It collects the external links present in the reply payload and filters out platform infrastructure links, capped at 30 entries. An answer with nosourcesfield is a normal answer that was not web-grounded, not a failure.- Response variance. Gemini A/B-tests its answers, so the same prompt can return different wording, formatting, or a different
modellabel across calls. Do not treat exact text as stable. - Typical latency is a few seconds and depends on prompt complexity and reply length. The endpoint waits for the complete reply and does not stream partial output.
- Per-call timeout is 45 seconds. If you hit it, shorten unusually long prompts or retry.
- Retry on
502. Both502bodies are transient conditions; a retry a few seconds later normally succeeds and you are not charged for the failed call.
Error Responses
| Status | Body | Cause |
|---|---|---|
400 | { "error": "token is required" } | Missing token parameter |
400 | { "error": "q (prompt) is required" } | Missing or empty q parameter |
400 | { "error": "q is too long (max 4000 characters)", "message": "..." } | Prompt exceeds the 4000-character limit |
502 | { "error": "no warm session available", "message": "..." } | Capacity is being prepared; retry shortly |
502 | { "error": "failed to get a response from Gemini", "message": "..." } | Upstream did not return a usable reply; retry, and contact support if it persists |
500 | { "error": "internal server error" } | Unexpected internal failure |

