Monitor Gemini Responses
curl --request POST \
--url https://api.cloro.dev/v1/monitor/gemini \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"prompt": "Explain quantum computing",
"country": "US",
"include": {
"markdown": true,
"html": false,
"rawResponse": false
},
"state": "CA"
}
'import requests
url = "https://api.cloro.dev/v1/monitor/gemini"
payload = {
"prompt": "Explain quantum computing",
"country": "US",
"include": {
"markdown": True,
"html": False,
"rawResponse": False
},
"state": "CA"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
prompt: 'Explain quantum computing',
country: 'US',
include: {markdown: true, html: false, rawResponse: false},
state: 'CA'
})
};
fetch('https://api.cloro.dev/v1/monitor/gemini', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cloro.dev/v1/monitor/gemini",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'prompt' => 'Explain quantum computing',
'country' => 'US',
'include' => [
'markdown' => true,
'html' => false,
'rawResponse' => false
],
'state' => 'CA'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.cloro.dev/v1/monitor/gemini"
payload := strings.NewReader("{\n \"prompt\": \"Explain quantum computing\",\n \"country\": \"US\",\n \"include\": {\n \"markdown\": true,\n \"html\": false,\n \"rawResponse\": false\n },\n \"state\": \"CA\"\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(string(body))
}HttpResponse<String> response = Unirest.post("https://api.cloro.dev/v1/monitor/gemini")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"Explain quantum computing\",\n \"country\": \"US\",\n \"include\": {\n \"markdown\": true,\n \"html\": false,\n \"rawResponse\": false\n },\n \"state\": \"CA\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloro.dev/v1/monitor/gemini")
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 \"prompt\": \"Explain quantum computing\",\n \"country\": \"US\",\n \"include\": {\n \"markdown\": true,\n \"html\": false,\n \"rawResponse\": false\n },\n \"state\": \"CA\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"result": {
"text": "Quantum computing is a type of computation...",
"markdown": "**Quantum computing** is a type of computation...",
"html": "https://cdn.cloro.dev/results/c45a5081-808d-4ed3-9c86-e4baf16c8ab8/page-1.html",
"sources": [
{
"position": 1,
"label": "Wikipedia - Quantum Computing",
"url": "https://en.wikipedia.org/wiki/Quantum_computing",
"description": "Quantum computing is a multidisciplinary field..."
}
],
"citationPills": [
{
"label": "Quantum computing — Wikipedia",
"citationPillId": 1,
"url": "https://en.wikipedia.org/wiki/Quantum_computing",
"domain": "en.wikipedia.org",
"description": "Quantum computing is a multidisciplinary field...",
"position": 1
},
{
"label": "IBM Quantum",
"citationPillId": 1,
"url": "https://www.ibm.com/quantum",
"domain": "ibm.com",
"position": 3
}
],
"rawResponse": [
"<unknown>"
]
}
}{
"success": false,
"error": "Request validation failed",
"details": [
{
"field": "prompt",
"message": "Prompt cannot be empty"
}
]
}{
"error": {
"code": "MISSING_API_KEY",
"message": "Missing or invalid API key",
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"error": {
"code": "INSUFFICIENT_PERMISSIONS",
"message": "Insufficient permissions",
"details": {
"requiredScopes": [
"read:monitor",
"write:monitor"
]
},
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "Route not found",
"details": {
"id": "/v1/invalid-endpoint"
},
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"error": {
"code": "RESOURCE_CONFLICT",
"message": "Resource conflict",
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"error": {
"code": "CONCURRENT_LIMIT_EXCEEDED",
"message": "Concurrent limit exceeded",
"details": {
"limit": 10
},
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"success": false,
"error": "Request was canceled"
}{
"success": false,
"error": "Maximum retries exceeded"
}{
"error": {
"code": "EXTERNAL_SERVICE_ERROR",
"message": "External service error: OpenAI",
"details": {
"service": "OpenAI"
},
"timestamp": "2025-01-15T12:00:00.000Z"
}
}Gemini
Extract Google Gemini
Extract structured data from Google Gemini — generated answer text and cited sources for any prompt, with Markdown and HTML export formats
POST
/
v1
/
monitor
/
gemini
Monitor Gemini Responses
curl --request POST \
--url https://api.cloro.dev/v1/monitor/gemini \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"prompt": "Explain quantum computing",
"country": "US",
"include": {
"markdown": true,
"html": false,
"rawResponse": false
},
"state": "CA"
}
'import requests
url = "https://api.cloro.dev/v1/monitor/gemini"
payload = {
"prompt": "Explain quantum computing",
"country": "US",
"include": {
"markdown": True,
"html": False,
"rawResponse": False
},
"state": "CA"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
prompt: 'Explain quantum computing',
country: 'US',
include: {markdown: true, html: false, rawResponse: false},
state: 'CA'
})
};
fetch('https://api.cloro.dev/v1/monitor/gemini', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.cloro.dev/v1/monitor/gemini",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'prompt' => 'Explain quantum computing',
'country' => 'US',
'include' => [
'markdown' => true,
'html' => false,
'rawResponse' => false
],
'state' => 'CA'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.cloro.dev/v1/monitor/gemini"
payload := strings.NewReader("{\n \"prompt\": \"Explain quantum computing\",\n \"country\": \"US\",\n \"include\": {\n \"markdown\": true,\n \"html\": false,\n \"rawResponse\": false\n },\n \"state\": \"CA\"\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(string(body))
}HttpResponse<String> response = Unirest.post("https://api.cloro.dev/v1/monitor/gemini")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"Explain quantum computing\",\n \"country\": \"US\",\n \"include\": {\n \"markdown\": true,\n \"html\": false,\n \"rawResponse\": false\n },\n \"state\": \"CA\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloro.dev/v1/monitor/gemini")
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 \"prompt\": \"Explain quantum computing\",\n \"country\": \"US\",\n \"include\": {\n \"markdown\": true,\n \"html\": false,\n \"rawResponse\": false\n },\n \"state\": \"CA\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"result": {
"text": "Quantum computing is a type of computation...",
"markdown": "**Quantum computing** is a type of computation...",
"html": "https://cdn.cloro.dev/results/c45a5081-808d-4ed3-9c86-e4baf16c8ab8/page-1.html",
"sources": [
{
"position": 1,
"label": "Wikipedia - Quantum Computing",
"url": "https://en.wikipedia.org/wiki/Quantum_computing",
"description": "Quantum computing is a multidisciplinary field..."
}
],
"citationPills": [
{
"label": "Quantum computing — Wikipedia",
"citationPillId": 1,
"url": "https://en.wikipedia.org/wiki/Quantum_computing",
"domain": "en.wikipedia.org",
"description": "Quantum computing is a multidisciplinary field...",
"position": 1
},
{
"label": "IBM Quantum",
"citationPillId": 1,
"url": "https://www.ibm.com/quantum",
"domain": "ibm.com",
"position": 3
}
],
"rawResponse": [
"<unknown>"
]
}
}{
"success": false,
"error": "Request validation failed",
"details": [
{
"field": "prompt",
"message": "Prompt cannot be empty"
}
]
}{
"error": {
"code": "MISSING_API_KEY",
"message": "Missing or invalid API key",
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"error": {
"code": "INSUFFICIENT_PERMISSIONS",
"message": "Insufficient permissions",
"details": {
"requiredScopes": [
"read:monitor",
"write:monitor"
]
},
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "Route not found",
"details": {
"id": "/v1/invalid-endpoint"
},
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"error": {
"code": "RESOURCE_CONFLICT",
"message": "Resource conflict",
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"error": {
"code": "CONCURRENT_LIMIT_EXCEEDED",
"message": "Concurrent limit exceeded",
"details": {
"limit": 10
},
"timestamp": "2025-01-15T12:00:00.000Z"
}
}{
"success": false,
"error": "Request was canceled"
}{
"success": false,
"error": "Maximum retries exceeded"
}{
"error": {
"code": "EXTERNAL_SERVICE_ERROR",
"message": "External service error: OpenAI",
"details": {
"service": "OpenAI"
},
"timestamp": "2025-01-15T12:00:00.000Z"
}
}Extract structured data from Google’s Gemini AI: the generated text response, citations and sources, with Markdown and HTML export formats.
Retrying once resolves roughly 60% of them overall, which brings the effective rate to well under
1%. Age-restricted refusals are the exception — they follow the subject of the prompt, so retrying
converts far fewer of them.
Web search behaviorThis endpoint uses Gemini’s default interface. Gemini decides for itself whether a query needs current information, so web search and source citations may or may not appear.
Request parameters
Uses common parameters. Endpoint-specific options:include.rawResponse(boolean): Include raw streaming response events. Defaults tofalse
Response objects
| Section | Description |
|---|---|
| Sources | Source citations with contextual descriptions |
Response schema
Includes common response fields plus:| Field | Type | Description |
|---|---|---|
result.text | string | The main text content of the response |
result.sources | array | Array of sources cited in the response |
result.markdown | string | Response formatted in Markdown (included when include.markdown is true) |
result.html | string | A URL to the full HTML of the response (included when include.html is true, expires after 24 hours) |
result.rawResponse | array | Array of Gemini’s streamed response events (included when include.rawResponse is true) |
Example usage
{
"prompt": "Explain quantum entanglement",
"country": "US",
"include": {
"markdown": true
}
}
Common questions
Some responses come back with no answer. How often, and what should I do?
Under 2% of successful Gemini responses contain no usable answer — Gemini returns a short canned message instead of content, with an emptysources array. See
empty responses from AI providers for
how to detect them and why matching on the message text does not work.
The breakdown below comes from our own continuous Gemini monitoring. “Success on retry” is how
often the same prompt returned a full answer on a later run:
| Type | Share of empty responses | Success on retry |
|---|---|---|
| Safety refusal | 73% | 62% |
| Age-restricted or policy refusal | 18% | 36% |
| Truncated answer | 5% | 89% |
| Capability refusal | 2% | 96% |
| Provider error | 1% | 98% |
| Account notice | 1% | 93% |
These figures move as Google changes Gemini’s models and safety policies. Use them to size a
retry budget, not as a guarantee.
How does cloro retrieve Gemini responses?
cloro does not call the Gemini API. Each request runs through a real browser session against Gemini’s web interface, routed through a proxy in the country you specify. Theresult.* fields are extracted from that page; the raw streamed events are available via include.rawResponse: true. See How does cloro retrieve data from AI providers? for the implications (model routing, auth walls, geo behaviour).Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
application/json
Request parameters for monitoring Gemini responses
The prompt to send to Gemini
Required string length:
1 - 10000Example:
"Explain quantum computing"
Country/region code for localized response
Example:
"US"
Optional flags for including additional response formats
Show child attributes
Show child attributes
Example:
{
"markdown": true,
"html": false,
"rawResponse": false
}
State code for sub-country geo-targeting (e.g., "CA"). Only valid with country "US".
Required string length:
2Pattern:
^[A-Z]{2}$Example:
"CA"
Was this page helpful?
⌘I