> ## Documentation Index
> Fetch the complete documentation index at: https://docs.querying.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Place Lookup: see which record each AI engine shows for a store

> Ask ChatGPT, Gemini, Google, Copilot and Naver about one store and read each engine's record of it: the map database it comes from, what it says, and where it differs from the store's own details.

Use Place Lookup to check how AI engines show one store, branch or clinic. Each engine shows places from
a map database. Gemini, Copilot and Google's results page show Google Maps records, Naver AI Tab shows
Naver Place records, and ChatGPT shows records from feeds such as Yelp, Tripadvisor and Google Maps. A
lookup tells you which record each engine used and what is wrong with it, so you know which listing to
correct.

## Submit a lookup

```bash theme={"theme":"css-variables"}
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"
  }'
```

The lookup asks each engine two questions. Each question is an ordinary task of that engine, and the
response lists them:

```json theme={"theme":"css-variables"}
{
  "success": true,
  "lookup": { "id": "canlis-2026-10" },
  "tasks": [
    {
      "engine": "CHATGPT",
      "ask": 1,
      "success": true,
      "task": {
        "id": "9d02deef-...",
        "taskType": "CHATGPT",
        "status": "QUEUED",
        "priority": 1,
        "createdAt": "2026-10-20T09:00:00.000Z",
        "idempotencyKey": "canlis-2026-10:CHATGPT:1"
      }
    },
    { "engine": "CHATGPT", "ask": 2, "success": true, "task": { "...": "..." } },
    { "engine": "GEMINI", "ask": 1, "success": true, "task": { "...": "..." } }
  ]
}
```

Read the lookup with `GET /v1/place-lookup/{id}` until `lookup.status` is `COMPLETED`. Most lookups
finish within two minutes, so poll every 5 to 10 seconds. A lookup sends no webhook. The request schema is
in the [API reference](/api-reference/place-lookup.md).

```bash theme={"theme":"css-variables"}
curl https://api.querying.ai/v1/place-lookup/canlis-2026-10 \
  -H "Authorization: Bearer $QUERYING_API_KEY"
```

## Request fields

| Field | Required | Description |
| - | - | - |
| `place.name` | Yes | The store's name, 1–200 characters. For a chain, include the branch, such as `Anchorhead Coffee Downtown Seattle`. |
| `place.address` | `address` or `location` | The street address, up to 500 characters. |
| `place.location` | `address` or `location` | The store's pin as `{ "latitude", "longitude" }` in decimal degrees. With it, each record carries its distance from the store, and a misplaced pin is reported. |
| `place.phone` | No | The official phone number in any format, up to 50 characters. Each record's phone is compared with it. |
| `place.website` | No | The official website, an `http` or `https` URL. Each record's website is compared with it by site. |
| `place.googlePlaceId` | No | The store's Google Place ID, such as `ChIJRXCfNwUVkFQRxraD8U-dANE`. A record with this ID is the store. |
| `place.naverPlaceId` | No | 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.yelpUrl` | No | The store's `yelp.com/biz/...` page. A record of this business is the store. |
| `country` | Yes | The store's country as an ISO 3166-1 alpha-2 code, such as `US` or `KR`. |
| `engines` | No | Engines to ask, without repeats: `CHATGPT`, `GEMINI`, `GOOGLE`, `BING_COPILOT` and `NAVER_AI_TAB`. Default: all five for `KR`, the first four elsewhere. `NAVER_AI_TAB` is for `KR` only. |
| `idempotencyKey` | No | The lookup's id, 1–200 characters without leading or trailing spaces. Without it the server mints a UUID. See [Send a lookup again](#send-a-lookup-again). |
| `priority` | No | Integer `1`–`10`, default `1`, set on every task. It does not guarantee execution order. |

Other fields, `webhook` included, return `400 VALIDATION_ERROR`.

## How a lookup asks

Each engine gets two questions. ChatGPT, Gemini and Copilot are asked to show the store on a map, the
second time with its address. Google's results page is searched for the store's location, then for its
name from the store's own pin. Naver AI Tab is asked for the store's location, then for its name.

| Engine | First question | Second question |
| - | - | - |
| `CHATGPT`, `GEMINI`, `BING_COPILOT` | `Show {name} on a map` | `Show {name}, {address} on a map` |
| `GOOGLE` | `{name} location` | `{name}`, searched from `place.location` |

For `KR` stores the questions are in Korean, and ChatGPT's second question is `Show {name} on a map` in
English, because ChatGPT shows a Korean store's place card more often when asked in English. Without
`place.address`, an engine whose second question adds the address asks the first one twice. Without
`place.location`, Google's second search adds the address outside `KR`. `via[]` in the result shows each
question as it was sent.

## Read the result

The Canlis lookup reads like this, trimmed to the main fields:

```json theme={"theme":"css-variables"}
{
  "success": true,
  "lookup": {
    "id": "canlis-2026-10",
    "status": "COMPLETED",
    "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",
    "engines": [
      {
        "engine": "CHATGPT",
        "status": "COMPLETED",
        "found": true,
        "via": [
          {
            "taskType": "CHATGPT",
            "prompt": "Show Canlis on a map",
            "taskId": "9d02deef-...",
            "status": "COMPLETED",
            "collectedAt": "2026-10-19T16:38:48.957Z",
            "places": 1
          },
          {
            "taskType": "CHATGPT",
            "prompt": "Show Canlis, 2576 Aurora Ave N, Seattle, WA 98109 on a map",
            "taskId": "91505c8f-...",
            "status": "COMPLETED",
            "collectedAt": "2026-10-19T16:39:04.194Z",
            "places": 1
          }
        ],
        "record": {
          "position": 1,
          "name": "Canlis",
          "source": "yelp",
          "provider": "yelp-feed",
          "url": "https://www.yelp.com/biz/canlis-seattle?adjust_creative=openai",
          "address": "2576 Aurora Ave N, Seattle, WA 98109, United States",
          "latitude": 47.6430933,
          "longitude": -122.3467535,
          "phone": "+1 206-283-3313",
          "rating": 4,
          "reviewCount": 1935,
          "website": "https://canlis.com/",
          "match": {
            "same": true,
            "by": ["phone", "website", "location", "address", "name"],
            "nameScore": 1,
            "distanceMeters": 5
          }
        }
      },
      {
        "engine": "GEMINI",
        "status": "COMPLETED",
        "found": true,
        "via": [{ "...": "..." }],
        "record": {
          "position": 1,
          "name": "Canlis",
          "source": "google_maps",
          "placeId": "ChIJRXCfNwUVkFQRxraD8U-dANE",
          "url": "https://maps.google.com/?cid=15060210120606856902",
          "phone": "+1 206-283-3313",
          "rating": 4.6,
          "reviewCount": 2892,
          "website": "https://canlis.com/",
          "match": {
            "same": true,
            "by": ["phone", "website", "location", "address", "name"],
            "nameScore": 1,
            "distanceMeters": 5
          }
        }
      },
      {
        "engine": "GOOGLE",
        "status": "COMPLETED",
        "found": false,
        "via": [
          {
            "taskType": "GOOGLE",
            "query": "Canlis location",
            "taskId": "6d3c3a73-...",
            "status": "COMPLETED",
            "collectedAt": "2026-10-19T16:38:43.932Z",
            "places": 0
          },
          {
            "taskType": "GOOGLE",
            "query": "Canlis",
            "location": { "latitude": 47.6430534, "longitude": -122.3467361 },
            "taskId": "980a858a-...",
            "status": "COMPLETED",
            "collectedAt": "2026-10-19T16:38:48.902Z",
            "places": 0
          }
        ]
      },
      {
        "engine": "BING_COPILOT",
        "status": "COMPLETED",
        "found": true,
        "via": [{ "...": "..." }],
        "record": {
          "name": "Canlis",
          "source": "google_maps",
          "placeId": "ChIJRXCfNwUVkFQRxraD8U-dANE",
          "openState": "Closed · Opens 5 PM Tue",
          "...": "..."
        }
      }
    ],
    "summary": {
      "foundIn": ["CHATGPT", "GEMINI", "BING_COPILOT"],
      "notFoundIn": ["GOOGLE"],
      "failed": [],
      "pending": [],
      "differences": []
    },
    "credits": 10
  }
}
```

ChatGPT showed the restaurant's Yelp record. Gemini and Copilot showed the same Google Maps record, with
the same Place ID. Google's results page showed no place for either question, so its `found` is `false`.

### `engines[]`

| Field | Description |
| - | - |
| `engine` | The engine asked. |
| `status` | `PROCESSING` until both questions end, then `COMPLETED`. `FAILED` when both questions failed. |
| `found` | `true` once an answer shows the store. `false` when both questions ended and no answer showed it. `null` while a question is still running, and when both failed. |
| `via[]` | Each question as sent: `prompt` or `query`, `location` when one was sent, `taskId` once the question starts, `status`, `collectedAt`, `places` (how many places the answer showed) and `error` for a failed question. `status` is `PENDING` while the question waits for room in your plan. |
| `record` | The store's record: of the places in the two answers, the one that matches the store most strongly. Present when `found` is `true`. |
| `issues` | What is wrong with `record`. Present only when something is. |

### `record`

| Field | Description |
| - | - |
| `source` | The record's map database: `google_maps`, `naver_place`, `yelp`, `tripadvisor`, or `unknown` when the answer does not show it. |
| `placeId`, `url` | The record's ID and page at its source, such as a Google Place ID and its Google Maps link. |
| `name`, `address`, `latitude`, `longitude`, `phone`, `website` | The details the engine shows. Only fields the answer carries are present. |
| `category`, `rating`, `reviewCount`, `openState`, `image`, `description` | More details as the engine shows them, when present. |
| `position` | The record's order among the places in the answer, from 1. |
| `provider` | ChatGPT only: the feed ChatGPT names for the record, such as `yelp-feed` or `bright-feed`. |
| `localName` | ChatGPT only: the record's other name, such as a Korean store's Korean name. |
| `resolvedBy` | ChatGPT only: `address` when ChatGPT found the record by an address the model wrote. Such a record can belong to another business at that address. |
| `closed` | ChatGPT only: `permanently` or `temporarily` when the record is marked closed. |
| `match` | Why the record is the store. `by` lists the details that agree: `place_id`, `phone`, `website`, `location`, `address` and `name`. `nameScore` is the name similarity from 0 to 1, and `distanceMeters` the distance from `place.location` to the record's pin. |

### `issues`

| Issue | Meaning |
| - | - |
| `phone_mismatch` | The record's phone differs from `place.phone`, or, without it, from the number most other engines show. |
| `website_mismatch` | The record's website is another site than `place.website`, or, without it, than the site most other engines show. |
| `location_mismatch` | The record's pin is more than 300 m from `place.location`. |
| `other_business_record` | The record is likely another business's at the store's spot: its phone and website both differ, or ChatGPT found it by address and one of them differs. |
| `closed_permanently`, `closed_temporarily` | ChatGPT shows the place as closed. |

A number that every branch of a chain lists, such as a toll-free number, is not compared.

### `summary` and `credits`

| Field | Description |
| - | - |
| `summary.foundIn` | Engines that showed the store. |
| `summary.notFoundIn` | Engines whose answers completed without it. |
| `summary.failed` | Engines whose questions both failed. |
| `summary.pending` | Engines still answering that have not shown the store yet. |
| `summary.differences[]` | Where the engines' records disagree. `field` is `name`, `phone`, `website` or `location`, and `values[]` lists each `value` with the `engines` that show it. A `location` entry appears when two pins are more than 300 m apart and carries `spreadMeters`, the largest distance between them. |
| `credits` | Credits charged so far for the lookup's questions. |

`lookup.status` is `PROCESSING` until every engine ends, then `COMPLETED`. The result is judged from the
stored answers on every read, and a lookup can be read for 24 hours after its tasks complete.

## Send a lookup again

Each question is a task whose key is `{lookup id}:{engine}:{ask}`, such as `canlis-2026-10:GEMINI:2`.
Send the same request under the same `idempotencyKey`, and the lookup returns the tasks it has and sends
the questions that have no task yet, such as ones refused for want of credits. The same id with another
store, country or engine list returns `409 RESOURCE_ALREADY_EXISTS` and creates nothing. To look the store
up again later, use a new `idempotencyKey`.

## Plan concurrency

Each question counts as one task toward your plan's concurrency limit. A lookup starts the questions your
plan has room for, and the rest wait in `tasks[]` with `status: "PENDING"`:

```json theme={"theme":"css-variables"}
{ "engine": "GEMINI", "ask": 1, "success": true, "status": "PENDING" }
```

A waiting question starts on its own as your running tasks finish, within a minute or the next time you
read the lookup, so one request runs the whole lookup. On the Free plan, which allows 2 concurrent tasks,
a lookup runs two questions at a time and takes a few minutes. Paid plans start at 50 concurrent tasks, so
a whole lookup starts at once while your account has room. Questions also wait while an engine's queue is
full or the key has spent its daily credit limit. A question's price is held when it starts. If the key
that sent the lookup is revoked or expires first, the waiting questions end as `FAILED` with
`API_KEY_INACTIVE` and cost 0. See [Credits and limits](/concepts/credits-and-limits.md#plan-concurrency).

## Errors and billing

A lookup of the country's default engines costs 10 credits. Each question is priced as its share: 1
credit for each of the 10 questions in `KR`, and 1.25 for each of the 8 elsewhere. A lookup that names
fewer engines pays for the questions it sends. Each question's price is held at submit and charged when
it completes, and a failed question costs 0. See [Credits and limits](/concepts/credits-and-limits.md).

### Rejected at submit

| Status | Code | Cause |
| - | - | - |
| `400` | `VALIDATION_ERROR` | The body is not valid JSON, a field is missing or invalid, an unknown field or `webhook` was sent, or `NAVER_AI_TAB` was asked outside `KR`. `details` names the field. |
| `409` | `RESOURCE_ALREADY_EXISTS` | The `idempotencyKey` names a lookup of another store, country or engine list. |

When every question is refused, the first refusal is the response with its own status, such as
`402 INSUFFICIENT_CREDITS` or `403 KEY_SCOPE_DENIED`, and nothing is
created. When some questions are admitted, the response is `200`, and each refused question carries its
`error` in `tasks[]`:

```json theme={"theme":"css-variables"}
{
  "engine": "GOOGLE",
  "ask": 2,
  "success": false,
  "error": {
    "code": "INSUFFICIENT_CREDITS",
    "message": "insufficient credits (need 1.25)",
    "timestamp": "2026-10-20T09:00:00.000Z"
  }
}
```

### Reading a lookup

`GET /v1/place-lookup/{id}` returns `404 RESOURCE_NOT_FOUND` for an id your account has not used, and
for a lookup whose tasks are past the 24-hour window. A failed question shows `status: "FAILED"` in
`via[]` and an `error` that starts with its code, such as `ENGINE_NO_RESULT`. The codes are those of the
engine's tasks, and a waiting question that ends before it starts carries `API_KEY_INACTIVE` or
`INSUFFICIENT_CREDITS`. See [Errors](/concepts/errors.md).

## Next steps

> **[ChatGPT](/engines/chatgpt.md)**
>
> The place cards ChatGPT shows, in `map`.

> **[Batches and grids](/concepts/bulk-submission.md)**
>
> Ask one prompt from every point of a grid around a store.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.