curl --request POST \
--url https://api.cloro.dev/v1/monitor/google/news \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"query": "climate change",
"country": "US",
"gl": "us",
"hl": "en",
"device": "desktop",
"pages": 1,
"include": {
"html": false
}
}
'import requests
url = "https://api.cloro.dev/v1/monitor/google/news"
payload = {
"query": "climate change",
"country": "US",
"gl": "us",
"hl": "en",
"device": "desktop",
"pages": 1,
"include": { "html": False }
}
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({
query: 'climate change',
country: 'US',
gl: 'us',
hl: 'en',
device: 'desktop',
pages: 1,
include: {html: false}
})
};
fetch('https://api.cloro.dev/v1/monitor/google/news', 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/google/news",
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([
'query' => 'climate change',
'country' => 'US',
'gl' => 'us',
'hl' => 'en',
'device' => 'desktop',
'pages' => 1,
'include' => [
'html' => false
]
]),
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/google/news"
payload := strings.NewReader("{\n \"query\": \"climate change\",\n \"country\": \"US\",\n \"gl\": \"us\",\n \"hl\": \"en\",\n \"device\": \"desktop\",\n \"pages\": 1,\n \"include\": {\n \"html\": false\n }\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/google/news")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"query\": \"climate change\",\n \"country\": \"US\",\n \"gl\": \"us\",\n \"hl\": \"en\",\n \"device\": \"desktop\",\n \"pages\": 1,\n \"include\": {\n \"html\": false\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloro.dev/v1/monitor/google/news")
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 \"query\": \"climate change\",\n \"country\": \"US\",\n \"gl\": \"us\",\n \"hl\": \"en\",\n \"device\": \"desktop\",\n \"pages\": 1,\n \"include\": {\n \"html\": false\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"result": {
"newsResults": [
{
"position": 1,
"title": "Major Climate Summit Reaches Historic Agreement",
"link": "https://example.com/climate-summit-agreement",
"snippet": "World leaders agreed on new climate targets at the summit...",
"source": "The Guardian",
"date": "2 hours ago",
"page": 1,
"thumbnail": "https://example.com/images/climate-summit.jpg",
"redirectLink": "https://www.google.com/goto?url=CAESaAHrOzAVev0pi_wnTxm1qpiZTmMyAllabLr1or10ZCfvJKPk"
}
],
"html": [
"https://cdn.cloro.dev/results/a12b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6/page-1.html"
]
}
}{
"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 Google News
Extract structured news articles from Google News including titles, links, snippets, sources, dates, and thumbnails
curl --request POST \
--url https://api.cloro.dev/v1/monitor/google/news \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"query": "climate change",
"country": "US",
"gl": "us",
"hl": "en",
"device": "desktop",
"pages": 1,
"include": {
"html": false
}
}
'import requests
url = "https://api.cloro.dev/v1/monitor/google/news"
payload = {
"query": "climate change",
"country": "US",
"gl": "us",
"hl": "en",
"device": "desktop",
"pages": 1,
"include": { "html": False }
}
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({
query: 'climate change',
country: 'US',
gl: 'us',
hl: 'en',
device: 'desktop',
pages: 1,
include: {html: false}
})
};
fetch('https://api.cloro.dev/v1/monitor/google/news', 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/google/news",
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([
'query' => 'climate change',
'country' => 'US',
'gl' => 'us',
'hl' => 'en',
'device' => 'desktop',
'pages' => 1,
'include' => [
'html' => false
]
]),
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/google/news"
payload := strings.NewReader("{\n \"query\": \"climate change\",\n \"country\": \"US\",\n \"gl\": \"us\",\n \"hl\": \"en\",\n \"device\": \"desktop\",\n \"pages\": 1,\n \"include\": {\n \"html\": false\n }\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/google/news")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"query\": \"climate change\",\n \"country\": \"US\",\n \"gl\": \"us\",\n \"hl\": \"en\",\n \"device\": \"desktop\",\n \"pages\": 1,\n \"include\": {\n \"html\": false\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloro.dev/v1/monitor/google/news")
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 \"query\": \"climate change\",\n \"country\": \"US\",\n \"gl\": \"us\",\n \"hl\": \"en\",\n \"device\": \"desktop\",\n \"pages\": 1,\n \"include\": {\n \"html\": false\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"result": {
"newsResults": [
{
"position": 1,
"title": "Major Climate Summit Reaches Historic Agreement",
"link": "https://example.com/climate-summit-agreement",
"snippet": "World leaders agreed on new climate targets at the summit...",
"source": "The Guardian",
"date": "2 hours ago",
"page": 1,
"thumbnail": "https://example.com/images/climate-summit.jpg",
"redirectLink": "https://www.google.com/goto?url=CAESaAHrOzAVev0pi_wnTxm1qpiZTmMyAllabLr1or10ZCfvJKPk"
}
],
"html": [
"https://cdn.cloro.dev/results/a12b3c4d-5e6f-7g8h-9i0j-k1l2m3n4o5p6/page-1.html"
]
}
}{
"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"
}
}Request parameters
Required parameters:query(string): The search query to execute on Google News (1-10,000 characters)country(string): ISO 3166-1 alpha-2 country code (uppercase) for localized news results. Required — there is no default
hl(string): Interface language, as Google’s ownhlparameter (en,de,pt-BR, …). Overrides the language cloro derives from the country, so the interface language and the result geography can differ. Free-form — Google owns the list of codesgl(string): Alternative tocountry, using Google’s own parameter name. Same country codes, accepted in either case. Providecountryorgl; sending both with different values is a400device(string): Device the search is run from. Options:desktop(default),ios,android, andmobile(an alias forandroid).iosemulates Safari on iPhone andandroidemulates Chrome on Android; all three phone values return the mobile news SERP layoutpages(integer): Number of news results pages to scrape (1-10). Defaults to1include.html(boolean): Include raw HTML response. Defaults tofalse
Response schema
Includes common response fields plus:Google News results
| Field | Type | Description |
|---|---|---|
result.newsResults | array | News articles from Google News |
result.html | array | Array of URLs to the full HTML, one per scraped page (if requested, expires after 24 hours) |
Response objects
| Section | Description |
|---|---|
| News articles | Article titles, links, snippets, sources, publication dates, and thumbnails |
Usage examples
Basic news search
{
"query": "climate change",
"country": "US"
}
Multi-page news search
{
"query": "artificial intelligence",
"pages": 3,
"country": "GB"
}
Mobile news results
The mobile news SERP as seen from an iPhone. Use"device": "android" for Chrome on Android instead:
{
"query": "technology news",
"device": "ios",
"country": "US"
}
Include HTML response
Raw HTML alongside the structured data:{
"query": "sports news",
"country": "US",
"include": {
"html": true
}
}
Authorizations
Body
Request parameters for monitoring Google News results
- Option 1
- Option 2
The search query to execute on Google News
1 - 10000"climate change"
ISO 3166-1 alpha-2 country code for localized news results. See List of countries for the codes each provider supports.
AD, AE, AF, AG, AI, AL, AM, AO, AQ, AR, AS, AT, AU, AW, AX, AZ, BA, BB, BD, BE, BF, BG, BH, BI, BJ, BL, BM, BN, BO, BQ, BR, BS, BT, BV, BW, BY, BZ, CA, CC, CD, CF, CG, CH, CI, CK, CL, CM, CN, CO, CR, CU, CV, CW, CX, CY, CZ, DE, DJ, DK, DM, DO, DZ, EC, EE, EG, EH, ER, ES, ET, FI, FJ, FK, FM, FO, FR, GA, GB, GD, GE, GF, GG, GH, GI, GL, GM, GN, GP, GQ, GR, GS, GT, GU, GW, GY, HK, HM, HN, HR, HT, HU, ID, IE, IL, IM, IN, IO, IQ, IR, IS, IT, JE, JM, JO, JP, KE, KG, KH, KI, KM, KN, KP, KR, KW, KY, KZ, LA, LB, LC, LI, LK, LR, LS, LT, LU, LV, LY, MA, MC, MD, ME, MF, MG, MH, MK, ML, MM, MN, MO, MP, MQ, MR, MS, MT, MU, MV, MW, MX, MY, MZ, NA, NC, NE, NF, NG, NI, NL, NO, NP, NR, NU, NZ, OM, PA, PE, PF, PG, PH, PK, PL, PM, PN, PR, PS, PT, PW, PY, QA, RE, RO, RS, RU, RW, SA, SB, SC, SD, SE, SG, SH, SI, SJ, SK, SL, SM, SN, SO, SR, SS, ST, SV, SX, SY, SZ, TC, TD, TF, TG, TH, TJ, TK, TL, TM, TN, TO, TR, TT, TV, TW, TZ, UA, UG, UM, US, UY, UZ, VA, VC, VE, VG, VI, VN, VU, WF, WS, XK, YE, YT, ZA, ZM, ZW "US"
Alternative to country, using Google's own parameter name for the result geography. Same ISO 3166-1 alpha-2 codes, accepted in either case (us or US), and must be a country the endpoint supports — see GET /v1/countries. Provide country or gl; sending both with different values is a 400.
"us"
Interface language, as Google's own hl parameter (e.g. en, de, pt-BR). Free-form and case-insensitive — Google owns the list of codes. Overrides the language cloro derives from the country, so the interface language and the result geography can differ.
"en"
Device the search is run from. 'desktop' returns the desktop news SERP; 'ios' (Safari on iPhone), 'android' (Chrome on Android) and 'mobile' (alias for 'android') all return the mobile news SERP.
desktop, mobile, ios, android "desktop"
Number of news results pages to scrape (1-10)
1 <= x <= 101
Optional flags for including additional response data
Show child attributes
Show child attributes
Was this page helpful?