ChangelogNew

Introducing Place Lookup

Place Lookup
A map of Seattle with a pin on the restaurant Canlis, linked to four engine cards: ChatGPT found its Yelp record, Gemini and Copilot the same Google Maps record, and the Google card reads Not found

One call asks ChatGPT, Gemini, Google, Copilot and, in Korea, Naver about your store, and returns each engine's record of it, the map database behind it and every detail that differs from yours.

What you get

  • POST /v1/place-lookup takes one store, with its name and an address or map pin, plus its phone, website and Place IDs when you have them, and asks CHATGPT, GEMINI, GOOGLE, BING_COPILOT and, for KR stores, NAVER_AI_TAB about it.
  • GET /v1/place-lookup/{id} returns each engine's record of the store: its source, such as google_maps, naver_place or yelp, its placeId and page, and the name, address, phone, website and rating the engine shows.
  • issues names what is wrong with a record: phone_mismatch, website_mismatch, location_mismatch, other_business_record, or a listing marked closed.
  • summary lists the engines that showed the store and the differences between their records, and credits shows what the lookup has charged.

How it works

Each engine gets two questions, such as Show Canlis on a map and the same with the address, and each one runs as an ordinary task of that engine. For KR stores, the questions are in Korean and ChatGPT's second question is in English. Of the places in the answers, the one that matches the store by Place ID, phone, website, pin, address and name is the store's record, and match lists the details that agree. The lookup is judged again from the stored answers each time you read it, and most lookups finish within two minutes.

Where it helps

  • Find the one map listing behind a wrong phone number. An error in a Google Maps record shows up in every engine that reads that record, and the lookup names that record.
  • Learn which map database each engine reads in your market. In a test of 20 US stores, ChatGPT showed Yelp records for 15.
  • Check every branch of a chain before a local campaign, with one lookup per branch.

Send a request

Send the request with your API key in the Authorization header.

curl -X POST https://api.querying.ai/v1/place-lookup \
  -H "Authorization: Bearer $QUERYING_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "place": {
      "name": "Canlis",
      "address": "2576 Aurora Ave N, Seattle, WA 98109",
      "location": { "latitude": 47.6430534, "longitude": -122.3467361 },
      "phone": "(206) 283-3313",
      "website": "https://canlis.com/"
    },
    "country": "US",
    "idempotencyKey": "canlis-2026-10"
  }'

Request fields

place.namestringRequired
The store’s name, 1 to 200 characters. For a chain, include the branch.
place.addressstring
The street address, up to 500 characters. A lookup needs this, place.location or both.
place.locationobject
The store’s pin as latitude and longitude. Each record then carries its distance from the store, and a pin more than 300 m away is reported.
place.phonestring
The official phone number in any format. Each record’s phone is compared with it.
place.websitestring
The official website, an http or https URL. Each record’s website is compared with it by site.
place.googlePlaceIdstring
The store’s Google Place ID. A record with this ID is the store.
place.naverPlaceIdstring
The store’s Naver Place ID, or its map.naver.com or place.naver.com page. A record with this ID is the store.
place.yelpUrlstring
The store’s yelp.com/biz/… page. A record of this business is the store.
countrystringRequired
The store’s country as an ISO 3166-1 alpha-2 code, such as US or KR.
enginesarray
Engines to ask, without repeats: CHATGPT, GEMINI, GOOGLE, BING_COPILOT and, for KR, NAVER_AI_TAB. Default: all five for KR, the first four elsewhere.
idempotencyKeystring
The lookup’s id, 1 to 200 characters. Default: a UUID from the server. Sending the same request under it again adds the questions that are missing.

Response

The response, trimmed for length.

JSON
{
  "success": true,
  "lookup": { "id": "canlis-2026-10" },
  "tasks": [
    {
      "engine": "CHATGPT",
      "ask": 1,
      "success": true,
      "task": {
        "id": "…",
        "taskType": "CHATGPT",
        "status": "QUEUED",
        "priority": 1,
        "createdAt": "…",
        "idempotencyKey": "canlis-2026-10:CHATGPT:1"
      }
    },
    { "engine": "CHATGPT", "ask": 2, "…": "…" },
    { "engine": "GEMINI", "ask": 1, "…": "…" }
  ]
}
lookup.idstring
The lookup’s id. Read the result with GET /v1/place-lookup/{id}.
tasksarray
One entry per question: engine, ask, success and the queued task, status: "PENDING" while it waits for room, or error with its code. A task’s idempotencyKey joins the lookup’s id, the engine and the question number, as in canlis-2026-10:CHATGPT:1.

Receive the result

Read the lookup by its id every 5 to 10 seconds until lookup.status is COMPLETED. It stays readable for 24 hours after its questions finish.

curl "https://api.querying.ai/v1/place-lookup/$LOOKUP_ID" \
  -H "Authorization: Bearer $QUERYING_API_KEY"

The Canlis lookup reads like this, trimmed. ChatGPT showed the restaurant's Yelp record, Gemini and Copilot the same Google Maps record, and Google's results page answered without a place, so its found is false.

JSON
{
  "success": true,
  "lookup": {
    "id": "canlis-2026-10",
    "status": "COMPLETED",
    "country": "US",
    "engines": [
      {
        "engine": "CHATGPT",
        "status": "COMPLETED",
        "found": true,
        "via": [{ "…": "…" }],
        "record": {
          "name": "Canlis",
          "source": "yelp",
          "provider": "yelp-feed",
          "phone": "+1 206-283-3313",
          "website": "https://canlis.com/",
          "rating": 4,
          "reviewCount": 1935,
          "match": {
            "same": true,
            "by": ["phone", "website", "location", "address", "name"],
            "nameScore": 1,
            "distanceMeters": 5
          },
          "…": "…"
        }
      },
      {
        "engine": "GEMINI",
        "status": "COMPLETED",
        "found": true,
        "via": [{ "…": "…" }],
        "record": {
          "name": "Canlis",
          "source": "google_maps",
          "placeId": "ChIJRXCfNwUVkFQRxraD8U-dANE",
          "phone": "+1 206-283-3313",
          "rating": 4.6,
          "reviewCount": 2892,
          "…": "…"
        }
      },
      {
        "engine": "GOOGLE",
        "status": "COMPLETED",
        "found": false,
        "…": "…"
      },
      {
        "engine": "BING_COPILOT",
        "status": "COMPLETED",
        "found": true,
        "…": "…"
      }
    ],
    "summary": {
      "foundIn": ["CHATGPT", "GEMINI", "BING_COPILOT"],
      "notFoundIn": ["GOOGLE"],
      "failed": [],
      "pending": [],
      "differences": []
    },
    "credits": 10
  }
}
lookup.statusstring
PROCESSING until every engine ends, then COMPLETED.
lookup.engines[].foundboolean
true once an answer shows the store, false when both questions ended without it, and null while a question runs or when both failed.
lookup.engines[].recordobject
The store’s record in that engine: of the places in the two answers, the one that matches the store best, with the name, address, phone, website and rating the engine shows.
lookup.engines[].record.sourcestring
The map database behind the record: google_maps, naver_place, yelp, tripadvisor or unknown. placeId and url are its ID and page there.
lookup.engines[].record.matchobject
Why the record is the store. by lists the details that agree, nameScore is the name similarity from 0 to 1, and distanceMeters the distance from place.location.
lookup.engines[].issuesarray
What is wrong with the record, when something is: phone_mismatch, website_mismatch, location_mismatch, other_business_record, closed_permanently or closed_temporarily.
lookup.summaryobject
The engines by outcome in foundIn, notFoundIn, failed and pending, and differences: each name, phone, website or pin that differs between engines, with the engines behind each value.
lookup.creditsnumber
Credits charged so far for the lookup’s questions.

Errors

When every question is refused, the response is the first refusal, such as 402 or 403. When some are admitted, the call answers 200 and each refused question carries its error. While your plan’s concurrent tasks are all in use, the remaining questions answer PENDING and start on their own as running tasks finish, so on the free plan, which runs 2 tasks at a time, one request runs the whole lookup.

VALIDATION_ERRORHTTP 400
A field is missing or out of range. details names the field.
INSUFFICIENT_CREDITSHTTP 402
The balance is below the price of the task. Add credits or upgrade the plan, then send again.
KEY_SCOPE_DENIEDHTTP 403
The engine is outside the key’s Allowed engines. Use another key, or add the engine in Manage key.
RESOURCE_ALREADY_EXISTSHTTP 409
The idempotencyKey already names a lookup of another store, country or engine list. A new idempotencyKey starts a new lookup.

Pricing

A lookup of the country's default engines costs 10 credits: 1 per question for the 10 questions in KR, and 1.25 for each of the 8 elsewhere. A lookup of fewer engines pays for the questions it sends, and a failed question costs 0. Plan prices are listed at https://querying.ai/pricing .

More updates

Stay in the loop

Get new product updates in your inbox.

RSS feed