Skip to content

API reference

Google Search API

Google results as clean JSON: web results, images, videos, news, shopping, places and Google Maps, including reviews for any place.

POST/api/v1/googleJSON body: {"endpoint", "params"}10 credits per request
Only successful calls are chargedTimes out after 15 seconds

Every call is a POST with a JSON body naming the endpoint and its params. Each endpoint costs 10 credits:

endpointReturnsRequired
/searchWeb results, People also ask, related searchesq
/imagesImage results with full-size and thumbnail URLsq
/videosVideo results with channel, length and thumbnailq
/newsNews articles with source and dateq
/shoppingProducts with price, store and ratingq
/placesLocal businesses with rating and coordinatesq
/mapsGoogle Maps results, or one place by IDq or cid / placeId
/reviewsReviews for a placecid, fid or placeId

Any other endpoint value runs a web search, as it always has. Below: the web search parameters, which the other search endpoints share.

Parameters in params

  • qstringRequired
    The search query. Operators such as site:, quotes and - work as they do on Google.
  • glstring
    Country code, for example us, gb, de.
  • hlstring
    Interface language, for example en, es, fr.
  • locationstring
    Passed through as given, but city-level targeting is not reliable. Use gl and hl to choose the market.
  • numintegerDefault 10
    Results per page, up to 10 (Google returns at most 10 per page). Use page for more.
  • pageintegerDefault 1
    Results page, starting at 1.
  • startinteger
    Result offset, as an alternative to page.
  • tbsstring
    Time filter: qdr:h, qdr:d, qdr:w, qdr:m or qdr:y.
  • autocorrectbooleanDefault true
    Let Google correct the spelling of the query.
  • safeboolean
    SafeSearch filtering.
  • filter0 | 1
    Google's duplicate-result filter.
  • lr, cr, sort, as_q, as_epq, as_oq, as_eq, as_sitesearch, as_filetype, as_rightsstring
    Advanced Google parameters, passed through as given.

Response

searchParameters echoes your query and the parameters you sent; organic lists results with position, title, link, snippet and sometimes date; then peopleAlsoAsk, relatedSearches, duration, statusCode and creditsUsed. A missing q returns 400 with Missing required parameter: q (search query).

Request

curl -X POST "https://scrapingbot.io/api/v1/google" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/search",
    "params": {"q": "best espresso machine", "gl": "us"}
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/google",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/search",
        "params": {"q": "best espresso machine", "gl": "us"},
    },
    timeout=60,
)
data = response.json()
print(data["organic"][0]["title"])
const response = await fetch("https://scrapingbot.io/api/v1/google", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/search",
    params: { q: "best espresso machine", gl: "us" },
  }),
});
const data = await response.json();
console.log(data.organic[0].title);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/google");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/search",
        "params" => ["q" => "best espresso machine", "gl" => "us"],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data["organic"][0]["title"]);

Response

200 OK
{
  "success": true,
  "searchParameters": {
    "q": "best espresso machine",
    "engine": "google",
    "gl": "us",
    "type": "search"
  },
  "organic": [
    {
      "position": 1,
      "title": "The 7 Greatest Espresso Machines in 2026 [No *BS Guide]",
      "link": "https://coffeechronicler.com/gear/espresso-machines/",
      "snippet": "My top picks for espresso machines are the The Breville Ba…",
      "date": "Jul 11, 2026"
    },
    …
  ],
  "peopleAlsoAsk": [
    {
      "question": "What is the highest rated espresso machine for home use?"
    },
    …
  ],
  "relatedSearches": [
    {
      "query": "Best espresso machine for home"
    },
    …
  ],
  "duration": "1.64",
  "statusCode": 200,
  "creditsUsed": 10
}

Images

Google Images results: title, source page, full-size image URL and dimensions, and a thumbnail.

POST/api/v1/googleendpoint "/images"10 credits

Parameters in params

  • qstringRequired
    The search query.
  • gl, hlstring
    Country and language, as for web search.
  • num, pageinteger
    Page size and page number.
  • tbsstring
    Time or tool filter, for example qdr:w.
  • aspectstring
    Aspect ratio filter, for example wide or square.

Request

curl -X POST "https://scrapingbot.io/api/v1/google" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/images",
    "params": {"q": "espresso machine", "gl": "us"}
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/google",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/images",
        "params": {"q": "espresso machine", "gl": "us"},
    },
    timeout=60,
)
data = response.json()
print(data["images"][0]["imageUrl"])
const response = await fetch("https://scrapingbot.io/api/v1/google", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/images",
    params: { q: "espresso machine", gl: "us" },
  }),
});
const data = await response.json();
console.log(data.images[0].imageUrl);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/google");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/images",
        "params" => ["q" => "espresso machine", "gl" => "us"],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data["images"][0]["imageUrl"]);

Response

200 OK
{
  "success": true,
  "searchParameters": {
    "q": "espresso machine",
    "gl": "us",
    "type": "images",
    "engine": "google"
  },
  "images": [
    {
      "domain": "www.seriouseats.com",
      "googleUrl": "https://www.google.com/imgres?imgurl=https%3A%2F%2Fwww.ser…",
      "imageHeight": 1001,
      "imageUrl": "https://www.seriouseats.com/thmb/CX83sjooTcA6DdW3oqP7_MY4l…",
      "imageWidth": 1500,
      "link": "https://www.seriouseats.com/breville-barista-express-impre…",
      "position": 1,
      "source": "Serious Eats",
      "thumbnailHeight": 452,
      "thumbnailUrl": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQmXk…",
      "thumbnailWidth": 678,
      "title": "Breville Barista Express Impress Espresso Machine Review"
    },
    …
  ],
  "duration": "0.89",
  "statusCode": 200,
  "creditsUsed": 10
}

images lists results with position, title, imageUrl, imageWidth, imageHeight, thumbnailUrl, source, domain and link (the page the image is on).

Videos

Google video results from YouTube and other sites, with channel, length, date and thumbnail.

POST/api/v1/googleendpoint "/videos"10 credits

Parameters in params

  • qstringRequired
    The search query.
  • gl, hlstring
    Country and language, as for web search.
  • num, pageinteger
    Page size and page number.
  • tbsstring
    Time filter, for example qdr:m for the past month.

Request

curl -X POST "https://scrapingbot.io/api/v1/google" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/videos",
    "params": {"q": "espresso tutorial"}
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/google",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/videos",
        "params": {"q": "espresso tutorial"},
    },
    timeout=60,
)
data = response.json()
print(data["videos"][0]["title"])
const response = await fetch("https://scrapingbot.io/api/v1/google", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/videos",
    params: { q: "espresso tutorial" },
  }),
});
const data = await response.json();
console.log(data.videos[0].title);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/google");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/videos",
        "params" => ["q" => "espresso tutorial"],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data["videos"][0]["title"]);

Response

200 OK
{
  "success": true,
  "searchParameters": {
    "q": "espresso tutorial",
    "type": "videos",
    "engine": "google"
  },
  "videos": [
    {
      "channel": "Joshua Weissman",
      "date": "Oct 24, 2019",
      "duration": "7:36",
      "imageUrl": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTcbo…",
      "link": "https://www.youtube.com/watch?v=ZuQu12vMQZM",
      "position": 1,
      "snippet": "Me and my dad got an espresso machine a few years ago, we…",
      "source": "YouTube",
      "title": "The Espresso Guide For Beginners",
      "videoUrl": "https://encrypted-vtbn0.gstatic.com/video?q=tbn:ANd9GcS6eU…"
    },
    …
  ],
  "duration": "0.66",
  "statusCode": 200,
  "creditsUsed": 10
}

News

Google News results: headline, publisher, how long ago, link and image.

POST/api/v1/googleendpoint "/news"10 credits

Parameters in params

  • qstringRequired
    The search query.
  • gl, hlstring
    Country and language, as for web search.
  • num, pageinteger
    Page size and page number.
  • tbsstring
    Time filter, for example qdr:d for the past day.

Request

curl -X POST "https://scrapingbot.io/api/v1/google" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/news",
    "params": {"q": "openai"}
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/google",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/news",
        "params": {"q": "openai"},
    },
    timeout=60,
)
data = response.json()
print(data["news"][0]["title"])
const response = await fetch("https://scrapingbot.io/api/v1/google", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/news",
    params: { q: "openai" },
  }),
});
const data = await response.json();
console.log(data.news[0].title);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/google");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/news",
        "params" => ["q" => "openai"],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data["news"][0]["title"]);

Response

200 OK
{
  "success": true,
  "searchParameters": {
    "q": "openai",
    "type": "news",
    "engine": "google"
  },
  "news": [
    {
      "date": "1 day ago",
      "imageUrl": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQQpE…",
      "link": "https://www.reuters.com/legal/litigation/openai-alerts-mor…",
      "source": "Reuters",
      "title": "OpenAI alerts more than 100 groups about rogue AI agent ac…"
    },
    …
  ],
  "duration": "0.79",
  "statusCode": 200,
  "creditsUsed": 10
}

Shopping

Google Shopping products with price, store, rating and image. A page holds about 40 products.

POST/api/v1/googleendpoint "/shopping"10 credits

Parameters in params

  • qstringRequired
    The search query.
  • gl, hlstring
    Country and language, as for web search.
  • num, pageinteger
    Page size and page number.

Request

curl -X POST "https://scrapingbot.io/api/v1/google" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/shopping",
    "params": {"q": "espresso machine"}
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/google",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/shopping",
        "params": {"q": "espresso machine"},
    },
    timeout=60,
)
data = response.json()
print(data["shopping"][0]["price"])
const response = await fetch("https://scrapingbot.io/api/v1/google", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/shopping",
    params: { q: "espresso machine" },
  }),
});
const data = await response.json();
console.log(data.shopping[0].price);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/google");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/shopping",
        "params" => ["q" => "espresso machine"],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data["shopping"][0]["price"]);

Response

200 OK
{
  "success": true,
  "searchParameters": {
    "q": "espresso machine",
    "type": "shopping",
    "engine": "google"
  },
  "shopping": [
    {
      "imageUrl": "https://encrypted-tbn3.gstatic.com/shopping?q=tbn:ANd9GcQA…",
      "link": "https://www.google.com/search?ibp=oshop&q=espresso+machine…",
      "position": 1,
      "price": "$84.99",
      "productId": "811448378812220536",
      "rating": 4.1,
      "ratingCount": 671,
      "source": "Walmart",
      "title": "Chefman CraftBrew Espresso Machine Stainless Steel"
    },
    …
  ],
  "duration": "0.94",
  "statusCode": 200,
  "creditsUsed": 10
}

Places

Local businesses for a query, with address, category, rating, price level, website and coordinates. Use the cid with /maps or /reviews.

POST/api/v1/googleendpoint "/places"10 credits

Parameters in params

  • qstringRequired
    The search query.
  • gl, hlstring
    Country and language, as for web search.
  • num, pageinteger
    Page size and page number.
  • llstring
    Map viewport to search in, as @latitude,longitude,zoomz, for example @30.27,-97.74,12z.

Request

curl -X POST "https://scrapingbot.io/api/v1/google" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/places",
    "params": {"q": "coffee shops in austin"}
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/google",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/places",
        "params": {"q": "coffee shops in austin"},
    },
    timeout=60,
)
data = response.json()
print(data["places"][0]["title"])
const response = await fetch("https://scrapingbot.io/api/v1/google", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/places",
    params: { q: "coffee shops in austin" },
  }),
});
const data = await response.json();
console.log(data.places[0].title);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/google");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/places",
        "params" => ["q" => "coffee shops in austin"],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data["places"][0]["title"]);

Response

200 OK
{
  "success": true,
  "searchParameters": {
    "q": "coffee shops in austin",
    "type": "places",
    "engine": "google"
  },
  "places": [
    {
      "address": "221 W N Loop Blvd",
      "category": "Coffee shop",
      "cid": "140078896924485689",
      "latitude": 30.318579,
      "longitude": -97.72449,
      "position": 1,
      "priceLevel": "$1–10",
      "rating": 4.5,
      "ratingCount": 2500,
      "title": "Epoch Coffee",
      "website": "http://www.epochcoffee.com/"
    },
    …
  ],
  "duration": "1.50",
  "statusCode": 200,
  "creditsUsed": 10
}

Maps

Google Maps results, with phone, opening hours, types and the place IDs. Or pass a cid, placeId or fid instead of q to get one place.

POST/api/v1/googleendpoint "/maps"10 credits

Parameters in params

  • qstring
    What to find. Required unless you pass a place ID.
  • cid, placeId, fidstring
    Look up one place by an ID from /places or /maps.
  • llstring
    Map viewport as @latitude,longitude,zoomz. The response echoes the viewport used in ll.
  • gl, hl, pagestring
    Country, language and page.

Request

curl -X POST "https://scrapingbot.io/api/v1/google" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/maps",
    "params": {"q": "coffee austin tx"}
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/google",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/maps",
        "params": {"q": "coffee austin tx"},
    },
    timeout=60,
)
data = response.json()
print(data["places"][0]["placeId"])
const response = await fetch("https://scrapingbot.io/api/v1/google", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/maps",
    params: { q: "coffee austin tx" },
  }),
});
const data = await response.json();
console.log(data.places[0].placeId);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/google");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/maps",
        "params" => ["q" => "coffee austin tx"],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data["places"][0]["placeId"]);

Response

200 OK
{
  "success": true,
  "searchParameters": {
    "q": "coffee austin tx",
    "type": "maps",
    "engine": "google"
  },
  "places": [
    {
      "address": "221 W N Loop Blvd, Austin, TX 78751",
      "cid": "140078896924485689",
      "description": "Cool, vibrant small-chain cafe featuring nibbles, tea & ca…",
      "fid": "0x8644ca6bc309e81b:0x1f1a903bbb66839",
      "latitude": 30.318603699999997,
      "longitude": -97.72454019999999,
      "openingHours": {
        "Friday": "Open 24 hours",
        "Monday": "12 AM–11:30 PM",
        "…": "…"
      },
      "phoneNumber": "(512) 454-3762",
      "placeId": "ChIJG-gJw2vKRIYROWi2uwOp8QE",
      "position": 1,
      "priceLevel": "$1–10",
      "rating": 4.5,
      "ratingCount": 2530,
      "thumbnailUrl": "https://lh3.googleusercontent.com/gps-cs-s/ANWiy9Su5f44nEx…",
      "title": "Epoch Coffee",
      "type": "Coffee shop",
      "types": [
        "Coffee shop"
      ],
      "website": "http://www.epochcoffee.com/"
    },
    …
  ],
  "ll": "@30.2723021,-97.7530505,11z",
  "duration": "1.35",
  "statusCode": 200,
  "creditsUsed": 10
}

Reviews

Google Maps reviews for a place: rating, text, date, likes and the reviewer. About 20 a page.

POST/api/v1/googleendpoint "/reviews"10 credits

Parameters in params

  • cid, fid or placeIdstringRequired
    The place, from a /places or /maps result.
  • sortBystringDefault mostRelevant
    mostRelevant, newest, highestRating or lowestRating.
  • nextPageTokenstring
    From the previous response, to get the next page.
  • gl, hlstring
    Country and language.

Request

curl -X POST "https://scrapingbot.io/api/v1/google" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/reviews",
    "params": {"cid": "140078896924485689", "sortBy": "newest"}
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/google",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/reviews",
        "params": {"cid": "140078896924485689", "sortBy": "newest"},
    },
    timeout=60,
)
data = response.json()
print(data["reviews"][0]["rating"])
const response = await fetch("https://scrapingbot.io/api/v1/google", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/reviews",
    params: { cid: "140078896924485689", sortBy: "newest" },
  }),
});
const data = await response.json();
console.log(data.reviews[0].rating);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/google");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/reviews",
        "params" => ["cid" => "140078896924485689", "sortBy" => "newest"],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data["reviews"][0]["rating"]);

Response

200 OK
{
  "success": true,
  "searchParameters": {
    "cid": "140078896924485689",
    "sortBy": "newest",
    "type": "reviews",
    "engine": "google"
  },
  "reviews": [
    {
      "date": "3 days ago",
      "id": "Ci9DQUlRQUNvZENodHljRjlvT25wM2FtaHJTREYyYkRsNmQwbEZXVmhVVG…",
      "isoDate": "2026-09-29T19:38:42.887Z",
      "likes": 0,
      "rating": 4,
      "snippet": "Amazing coffee",
      "user": {
        "link": "https://www.google.com/maps/contrib/103728188663414702859/…",
        "name": "Megan Daisy",
        "photos": 0,
        "reviews": 2,
        "thumbnail": "https://lh3.googleusercontent.com/a/ACg8ocK0wGGT5b2dGtrwm6…"
      }
    },
    …
  ],
  "nextPageToken": "Ci8IARInCgoAP72F_OPuf-__EhCS2sYpTBBTn_vMWxQAAAAAGgf_Al_OPu…",
  "duration": "0.34",
  "statusCode": 200,
  "creditsUsed": 10
}

Missing all three IDs returns 400 with Missing required parameter: cid, fid or placeId. When there are more reviews, nextPageToken is set.

Stuck on something?

Try requests in the dashboard playgrounds, check every call in your usage log, or write to [email protected]. A real developer answers.