Skip to main content

Local Grid API

How to use our API to run Local Grids and fetch their results.

Written by Holly Jimenez

This page explains how to use our API to run Local Grids and fetch grid results.

All requests to our API should be authenticated. Our API is RESTful and communicates using JSON.


How a Local Grid run works

Local Grid runs are asynchronous. Starting a run returns immediately with a grid id and a status of pending.

The grid then searches every point in the background:

  • A 5x5 grid runs 25 searches.

  • A 9x9 grid runs 81 searches.

  • An 11x11 grid runs 121 searches.

You can retrieve the finished result in two ways:

  • Polling – fetch the grid by its id every few seconds until its status is completed or failed.

  • Webhook – supply an on_completion URL and we will send the finished grid to it.

A run moves through these statuses: pendingprocessingcompleted. Its status will be failed if it could not be completed.

The grid id is the permanent reference used to fetch, refresh, view the history of or delete the grid.


Start a new Local Grid run

Method: POST

Endpoint: https://api.insites.com/api/v1/local-grids

Local Grid runs are asynchronous. Starting a run returns immediately with a grid ID and a pending status. You can then either:

  • Poll the grid using its ID until it completes

  • Supply an on_completion URL to receive the completed result by webhook

Request body should be JSON encoded, and can include the following fields:

Property

Definition

Required

business_name

String – The name of the business to analyse.

Yes

keyword

String – The keyword to search for.

Yes

latitude

Number – Latitude of the grid’s centre point, between -90 and 90.

Yes

longitude

Number – Longitude of the grid’s centre point, between -180 and 180.

Yes

grid_size

Integer – Number of points across the grid. Valid options are 5, 9 and 11 only. Defaults to 5.

No

distance

String or number - Number greater than 0 and no more than 100 representing approximately how wide the grid should be in the selected units. Defaults to automatic to calculate a suitable grid width from local competition.

No

on_completion

String – An HTTPS URL we will POST the completed grid to when finished.

No

report_id

String - An optional report to attribute the grid to. The report must belong to your account.

No

distance_units

String - km or miles. Defaults to your account’s unit.

No

country_code

String - Two-letter ISO country code, for example GB.

No

language_code

String - Two-letter language code, for example en.

No

address

String - The business’s street address.

No

street

String - The business’s street.

No

city

String - The business’s city.

No

state

String - The business’s state or region.

No

postcode

String - The business’s postcode.

No

cid

String - The business’s Google Maps CID, if known, to identify the exact listing.

No

website

String - The business’s website.

No

phone

String - The business’s phone number.

No

distance was previously called grid_width. The old property name is still supported, so existing integrations do not need to change. If both properties are supplied, the value of grid_width will be used.

You can also include an optional Idempotency-Key header to prevent retries from creating duplicate runs. See Idempotency below.

Example

curl "https://api.insites.com/api/v1/local-grids" \
--header "api-key:[YOUR API KEY]" \
--header "Content-Type: application/json" \
--data '{
"business_name": "Acme Plumbing",
"latitude": 53.8008,
"longitude": -1.5491,
"keyword": "emergency plumber",
"grid_size": 9,
"distance": "automatic",
"distance_units": "miles",
"country_code": "GB"
}'

Expected response

If successful, you would expect a 202 response, with a body like this:

{"id": "b7c3a912f4e54e6aa98f67b42d91a1b3",   
"status": "pending"}

The response also includes a Location header pointing to the new grid, which can be used when polling.

All possible responses

Code

Reason

202

Accepted. The grid run has started.

402

The account doesn’t have enough credits to start the run.

404

The supplied report_id does not belong to the account.

403

This action is not permitted with the API credentials you are using.

422

The request could not be processed.


Refresh an existing Local Grid

Method: POST

Endpoint: https://api.insites.com/api/v1/local-grids/[ID]/refresh

Runs an existing grid again using its saved location, keyword and grid settings. When the refresh finishes, the new result replaces the current result and the previous result is retained in the grid’s history.

The request body is optional. You only need to supply on_completion if you want to receive the finished grid by webhook.

Example

curl "https://api.insites.com/api/v1/local-grids/b7c3a912f4e54e6aa98f67b42d91a1b3/refresh" \   
--header "api-key:[YOUR API KEY]"

All possible responses

Code

Reason

202

Accepted. The grid refresh has started.

402

Account does not have enough credits.

404

Grid not found.

422

Request could not be processed, for example because an invalid on_completion URL was supplied


Fetch a Local Grid run

Method: GET

Endpoint: https://api.insites.com/api/v1/local-grids/[ID]

While a run is in progress, the API returns a 202 response containing its status and basic run information. Once it has finished, it returns a 200 response containing the complete result.

A refresh in progress also returns 202 until the new result is ready. The previous result is not returned during the refresh, so an integration cannot read a partially updated grid.

Example

curl "https://api.insites.com/api/v1/local-grids/b7c3a912f4e54e6aa98f67b42d91a1b3" \   
--header "api-key:[YOUR API KEY]"

While still processing

{ 
"id": "e8064122dba67bdf2189a55289288095",
"status": "processing",
"business_name": "Acme Plumbing",
"keyword": "emergency plumber",
"grid_size": 9
}

Expected response

If the grid is still processing, you would expect a 202 response. If the grid has completed, you would expect a 200 response with the full Local Grid data.

All possible responses

Code

Reason

200

Grid details returned.

202

The grid is still processing.

404

Grid not found.


Fetch a list of Local Grid runs

Method: GET

Endpoint: https://api.insites.com/api/v1/local-grids

Returns a list of Local Grid runs for your account, newest first. The request can include the following filters:

Property

Definition

Required

keyword

String – Partial match on the keyword.

No

status

String – Filter by status.

No

created_after

String – Only return runs created at or after this date-time.

No

created_before

String – Only return runs created before this date-time.

No

limit

Integer – Number of grids per page from 1 to 100. Defaults to 25.

No

offset

Integer – Number of runs to skip. Defaults to 0.

No

report_id

Only return grids attributed to this report.

No

sort

-created_at for newest first, which is the default, or created_at for oldest first.

No

Example

curl "https://api.insites.com/api/v1/local-grids?limit=10" \
--header "api-key:[YOUR API KEY]"

All possible responses

Code

Reason

200

List of Local Grid runs.

400

An invalid filter was supplied.

Finding a report’s Local Grid ID

If your integration starts with a report ID, e.g. from a report-completion webhook, there are two ways to find its grids:

  • Filter this endpoint using GET /local-grids?report_id=[REPORT ID].

  • Use GET /report/[REPORT ID]?include_local_grids=true.

Adding include_local_grids=true adds a local_grids array to the report. It contains each grid’s id, status, business_name, keyword, grid_size and created_at.

This includes grids created automatically during an audit and grids started through the Local Grid API. An empty array means the report has no grids.

Use the returned id with the other endpoints on this page.


Fetch a Local Grid’s history

Method: GET

Endpoint: https://api.insites.com/api/v1/local-grids/[ID]/history

Returns the grid’s historical snapshots, newest first, with one snapshot for each run. Each snapshot contains the complete grid result as it appeared at that time.

Property

Definition

Required

limit

Number of snapshots per page, from 1 to 100. Defaults to 25.

No

offset

Number of snapshots to skip. Defaults to 0.

No

Example

curl "https://api.insites.com/api/v1/local-grids/e8064122dba67bdf2189a55289288095/history" \
--header "api-key:[YOUR API KEY]"

All possible responses

Code

Reason

200

A page of historical snapshots was returned.

404

No grid with that id was found for the account.


Delete a Local Grid

Method: DELETE

Endpoint: https://api.insites.com/api/v1/local-grids/[ID]

Example

curl --request DELETE 
"https://api.insites.com/api/v1/local-grids/b7c3a912f4e54e6aa98f67b42d91a1b3"\
--header "api-key:[YOUR API KEY]"

All possible responses

Code

Reason

204

Grid deleted successfully.

404

Grid not found.


Webhooks

If an on_completion URL is supplied when starting a grid, we will POST the completed grid to that URL once it reaches a final status.

Example payload

{"id": "evt_b7c3a912f4e54e6aa98f67b42d91a1b3", 
"type": "local-grid-run.completed",
"timestamp": "2026-06-30T14:17:48Z",
"data": {
"...": "the full Local Grid result"
}}

Webhook event types

Type

Reason

local-grid-run.completed

The Local Grid run has completed.

local-grid-run.failed

The Local Grid run failed.

Use the event id to discard duplicate deliveries. Respond with a 2xx status to acknowledge the webhook. Other responses are logged but are not retried.

For the most robust integration, treat the webhook as a notification and fetch the grid using your API key after receiving it.

Verifying the signature

If you have configured a webhook signing secret in your API settings, every delivery includes a Webhook-Signature header:

Webhook-Signature: t=1718450042,v1=5257a869e7...

The signature is the lowercase hexadecimal HMAC-SHA256 of <timestamp>.<raw-request-body>, signed using your webhook signing secret.

To verify a delivery:

  1. Read t and v1 from the header.

  2. Calculate the HMAC of t + "." + body using the raw request-body bytes. Do not re-serialise the JSON.

  3. Compare the calculated value with v1 using a constant-time comparison.

You can reject deliveries whose timestamp is older than your chosen tolerance—for example, five minutes—to help prevent replay attacks.

Deliveries are unsigned if no signing secret has been configured. The same signing secret is used for all public API webhooks, including AI Visibility and Local Grid webhooks.


Idempotency

To make retries safe, send an Idempotency-Key header when starting a grid.

If we receive a repeated request carrying the same key within 24 hours, we return the original grid instead of starting a new one.

Use a new key for every distinct run, including a refresh. Reusing a key from an earlier run returns the original run instead of starting a new one.


Pagination

The Local Grid search and history endpoints support pagination using limit and offset.

Property

Definition

limit

The number of runs to return per page from 1-100. Defaults to 25.

offset

The number of runs to skip. Defaults to 0.

Each response includes a meta object containing the total result count and a links object containing ready-made first, prev, next and last URLs.

Follow links.next to move through the results. It will be null on the final page.


Errors

Errors use RFC 9457 problem details and have a content type of application/problem+json.

Every error includes a stable code that your integration can check.

Example error

{   "type": "about:blank",
"title": "Insufficient credits",
"status": 402,
"detail": "Not enough credits to start the run.",
"code": "insufficient_credits"
}

A 422 validation response also includes an errors list identifying the affected fields:

{   "type": "about:blank",   
"title": "Validation failed",
"status": 422,
"detail": "One or more fields are invalid.",
"code": "validation_failed",
"errors": [
{
"field": "grid_size",
"code": "invalid_value",
"detail": "The parameter 'grid_size' must be one of: 5, 9, 11."
} ] }

Code

Status

Meaning

insufficient_credits

402

The account does not have enough credits to start the run.

not_permitted

403

The account is not permitted to use the API.

report_not_found

404

The supplied report_id does not belong to the account.

local_grid_not_found

404

The requested grid could not be found.

validation_failed

422

One or more fields are invalid. See the errors list.


Completed grid data

A completed Local Grid includes the following sections:

Property

Definition

id

The Local Grid run ID.

status

The current run status.

grid

The complete Local Grid result, including its settings, ranking metrics, businesses and individual grid points.

The grid object

Property

Definition

guid

String – The Local Grid’s unique identifier.

created_at

String – The date and time at which the result was created.

keyword

String – The keyword measured by the grid.

grid_size

String – The grid dimensions.

radius

String or number – The configured grid width, or automatic.

distance_unit

String – The unit used for distance, such as miles or km.

business_name

String – The name of the business being measured.

address

String or null – The business’s address.

city

String or null – The business’s city.

state

String or null – The business’s state or region.

postcode

String or null – The business’s postcode.

country

String – The business’s country code.

latitude

String – Latitude of the grid’s centre point.

longitude

String – Longitude of the grid’s centre point.

main_place_id

String – The Google place ID of the subject business.

keyword_metrics

Object – Summary metrics for the subject business, including its average position, coverage, top positions, competitors and dominance.

business_data

Object – The subject business and competitors found across the grid, keyed by Google place ID.

location_data

Object – The coordinates and ranking results for every grid point.

Run statuses

Status

Definition

pending

The grid has been created and is waiting to start.

processing

The grid is in progress.

completed

The grid has completed successfully.

failed

The grid could not be completed.


Did this answer your question?