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
idevery few seconds until its status iscompletedorfailed.Webhook – supply an
on_completionURL and we will send the finished grid to it.
A run moves through these statuses: pending → processing → completed. 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_completionURL 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 | 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 - | No |
country_code | String - Two-letter ISO country code, for example | No |
language_code | String - Two-letter language code, for example | 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 |
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 |
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 |
| 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 |
| Number of snapshots per page, from 1 to 100. Defaults to | No |
| Number of snapshots to skip. Defaults to | No |
Example
curl "https://api.insites.com/api/v1/local-grids/e8064122dba67bdf2189a55289288095/history" \
--header "api-key:[YOUR API KEY]"
All possible responses
Code | Reason |
| A page of historical snapshots was returned. |
| No grid with that |
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:
Read
tandv1from the header.Calculate the HMAC of
t + "." + bodyusing the raw request-body bytes. Do not re-serialise the JSON.Compare the calculated value with
v1using 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 |
|
| The account does not have enough credits to start the run. |
|
| The account is not permitted to use the API. |
|
| The supplied |
|
| The requested grid could not be found. |
|
| One or more fields are invalid. See the |
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 |
| String – The Local Grid’s unique identifier. |
| String – The date and time at which the result was created. |
| String – The keyword measured by the grid. |
| String – The grid dimensions. |
| String or number – The configured grid width, or |
| String – The unit used for distance, such as |
| String – The name of the business being measured. |
| String or null – The business’s address. |
| String or null – The business’s city. |
| String or null – The business’s state or region. |
| String or null – The business’s postcode. |
| String – The business’s country code. |
| String – Latitude of the grid’s centre point. |
| String – Longitude of the grid’s centre point. |
| String – The Google place ID of the subject business. |
| Object – Summary metrics for the subject business, including its average position, coverage, top positions, competitors and dominance. |
| Object – The subject business and competitors found across the grid, keyed by Google place ID. |
| 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. |
