This page explains how to use our API to start AI Visibility runs and fetch their results.
All requests to our API should be authenticated. Our API is RESTful and communicates using JSON.
Start a new AI Visibility run
Method: POST
Endpoint: https://api.insites.com/api/v1/ai-visibility
Request body should be JSON encoded, and can include the following fields:
Property | Definition | Required |
business_name | String – The name of the business to check. | Yes |
city | String – The business’s city. | Yes |
country_code | String – Two-letter ISO country code, e.g. GB. | Yes |
category | String – The business category, e.g. Plumber. | Yes |
phone | String – The business’s phone number. | No |
website | String – The business’s website. | No |
language_code | String – Two-letter language code for the run, e.g. en. | No |
engines | String array – A list of engines to run. Supported values are chatgpt, gemini, grok and perplexity. If omitted, all engines will run. | No |
on_completion | String – An https:// URL we’ll send the finished run to when it completes. | No |
new_business | Boolean – If true, creates a new business record instead of reusing an existing business with the same website. | No |
Example
curl "https://api.insites.com/api/v1/ai-visibility" \
--header "api-key:[YOUR API KEY]" \
--header "Content-Type: application/json" \
--data
'{"business_name": "Acme Plumbing",
"city": "Leeds",
"country_code": "GB",
"category": "Plumber",
"website": "acme.test"}'
Expected response
If successful, you would expect a 202 response, with a body like this:
{"id": "9f2c1a7b8e4d4c10a3b25f6e7d8c9012",
"status": "pending",
"business":
{"id": "7d4e9b2a1c8f4063b5e2a9d7c1f60384",
"created": true}}The response also includes a Location header pointing to the new run, which can be used to fetch the run status.
All possible responses
Code | Reason |
202 | Accepted. The run has started. |
402 | The account doesn’t have enough credits to start the run. |
403 | This action is not permitted with the API credentials you are using. |
409 | A run is already in progress for this business. |
422 | The request could not be processed. |
Start an AI Visibility run for an existing business
Method: POST
Endpoint: https://api.insites.com/api/v1/businesses/[BusinessID or ReportID]/ai-visibility
The request body is optional. If no request body is sent, all engines will run.
If request body is supplied, it should be JSON encoded and can include the following fields.
Property | Definition | Required |
engines | String array – A list of engines to run. Supported values are chatgpt, gemini, grok and perplexity. If omitted, all engines will run. | No |
on_completion | String – An https:// URL we’ll send the finished run to when it completes. | No |
Example
curl "https://api.insites.com/api/v1/businesses/7d4e9b2a1c8f4063b5e2a9d7c1f60384/ai-visibility"\
--header "api-key:[YOUR API KEY]" \
--header "Content-Type: application/json" \
--data '{"engines": ["chatgpt", "perplexity"]}'
Expected response
If successful, you would expect a 202 response, with a body like this:
{"id": "1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
"status": "pending",
"business": {
"id": "7d4e9b2a1c8f4063b5e2a9d7c1f60384",
"created": false}}
All possible responses
Code | Reason |
202 | Accepted. The run has started. |
402 | The account doesn’t have enough credits to start the run. |
403 | This action is not permitted with the API credentials you are using. |
404 | Business not found. |
409 | A run is already in progress for this business. |
422 | The request could not be processed. |
Fetch a specific AI Visibility run
Method: GET
Endpoint: https://api.insites.com/api/v1/ai-visibility/[ID]
Example
curl "https://api.insites.com/api/v1/ai-visibility/9f2c1a7b8e4d4c10a3b25f6e7d8c9012"\
--header "api-key:[YOUR API KEY]"
Expected response
If the run is still processing, you would expect a 202 response, with a body like this:
{"id": "9f2c1a7b8e4d4c10a3b25f6e7d8c9012",
"status": "processing",
"started_at": "2026-06-24T09:15:02Z",
"completed_at": null,
"business":
{"id": "7d4e9b2a1c8f4063b5e2a9d7c1f60384",
"name": "Acme Plumbing",
"website": "acme.test"},
"links": {
"self": "https://api.insites.com/api/v1/ai-visibility/9f2c1a7b8e4d4c10a3b25f6e7d8c9012",
"rerun": "https://api.insites.com/api/v1/businesses/7d4e9b2a1c8f4063b5e2a9d7c1f60384/ai-visibility"}}If the run has completed, you would expect a 200 response with the completed run data.
All possible responses
Code | Reason |
200 | Run details returned. |
202 | The run is still processing. |
404 | Run not found. |
Fetch a list of AI Visibility runs
Method: GET
Endpoint: https://api.insites.com/api/v1/ai-visibility
Returns a list of AI Visibility runs for your account, newest first. The request can include the following filters:
Property | Definition | Required |
business_name | String – Partial, case-insensitive match on the business name. | No |
url | String – Partial, case-insensitive match on the business website. | No |
status | String – Only return runs with this status. Supported values are pending, processing, completed and failed. | 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 |
sort | String – Sort field. Prefix with - for descending. Defaults to -created_at. | No |
limit | Integer – Number of runs per page. Defaults to 25. | No |
offset | Integer – Number of runs to skip. Defaults to 0. | No |
Example
curl "https://api.insites.com/api/v1/ai-visibility?status=completed&limit=10"\
--header "api-key:[YOUR API KEY]"
Expected response
If successful, you would expect a 200 response, with a body like this:
{"data": [{
"id": "9f2c1a7b8e4d4c10a3b25f6e7d8c9012",
"status": "completed",
"started_at": "2026-06-24T09:15:02Z",
"completed_at": "2026-06-24T09:17:48Z",
"business": {
"id": "7d4e9b2a1c8f4063b5e2a9d7c1f60384",
"name": "Acme Plumbing",
"website": "acme.test"},
"links": {
"self": "https://api.insites.com/api/v1/ai-visibility/9f2c1a7b8e4d4c10a3b25f6e7d8c9012",
"rerun": "https://api.insites.com/api/v1/businesses/7d4e9b2a1c8f4063b5e2a9d7c1f60384/ai-visibility"
}}],
"meta": {
"total": 1,
"limit": 10,
"offset": 0
}}
All possible responses
Code | Reason |
200 | List of AI Visibility runs. |
400 | An invalid filter was supplied. |
Fetch a list of AI Visibility runs for a business
Method: GET
Endpoint: https://api.insites.com/api/v1/businesses/[BusinessID or ReportID]/ai-visibility
Returns a list of AI Visibility runs for a specific business, newest first. The request can include the following filters:
Property | Definition | Required |
limit | Integer – Number of runs per page. Defaults to 25. | No |
offset | Integer – Number of runs to skip. Defaults to 0. | No |
Example
curl "https://api.insites.com/api/v1/businesses/7d4e9b2a1c8f4063b5e2a9d7c1f60384/ai-visibility"\
--header "api-key:[YOUR API KEY]"
All possible responses
Code | Reason |
200 | List of AI Visibility runs returned. |
404 | Business not found. |
Webhooks
If an on_completion URL is supplied when starting a run, we will POST the finished run to that URL once it reaches a final status.
Example payload
{
"id": "evt_9f2c1a7b8e4d4c10a3b25f6e7d8c9012",
"type": "run.completed",
"timestamp": "2026-06-24T09:17:48Z",
"data": {
"...": "the full run, exactly as returned by GET /ai-visibility/[ID]"
}}Respond with a 2xx status to acknowledge the webhook. Other responses are logged but not retried.
Webhook event types
Type | Reason |
run.completed | The AI Visibility run has completed. |
run.failed | The AI Visibility run failed. |
Verifying the signature
If you’ve configured a webhook signing secret in your API settings, each webhook delivery will include a Webhook-Signature header.
Example
Webhook-Signature: t=1718450042,v1=5257a869e7...
The signature is a lowercase hex HMAC-SHA256 hash of:
<timestamp>.<raw-request-body>
To verify a webhook:
Read
t(timestamp) andv1(signature) from the header.Recompute the HMAC using
t + "." + body, using the raw request body and your signing secret.Compare your value to
v1using a constant-time comparison.
Optionally, reject requests whose timestamp is older than your chosen tolerance (for example, five minutes) to help prevent replay attacks. If no signing secret is configured, webhooks are sent unsigned.
Idempotency
To make retries safe, send an Idempotency-Key header when starting a run.
If we receive a repeated request carrying the same key within 24 hours, we return the original run instead of starting a new one.
Example
curl "https://api.insites.com/api/v1/ai-visibility"\
--header "api-key:[YOUR API KEY]"\
--header "Idempotency-Key: 7c3e1f08-2b9a-4d6e-9f1a-1c2d3e4f5a6b"\
--header "Content-Type: application/json"\
--data
'{"business_name": "Acme Plumbing",
"city": "Leeds",
"country_code": "GB",
"category": "Plumber"
}'
Pagination
The list endpoints support pagination using limit and offset.
Property | Definition |
limit | The number of runs to return per page. Defaults to 25. |
offset | The number of runs to skip. Defaults to 0. |
Each response includes a meta object with the total count, and a links object with pagination URLs for self, first, prev, next and last.
Errors
Errors are returned as JSON.
Example error
{"type": "about:blank",
"title": "A run is already in progress",
"status": 409,
"detail": "This business already has a run in progress.",
"code": "run_in_progress"}On a validation error, the response also includes an errors list with the specific fields at fault.
Example validation error
{
"type": "about:blank",
"title": "Validation failed",
"status": 422,
"detail": "One or more fields are invalid.",
"code": "validation_failed",
"errors": [
{
"field": "country_code",
"code": "required",
"detail": "country_code is required."
}
]
}
Error codes
Code | Status | Reason |
insufficient_credits | 402 | The account doesn’t have enough credits to start the run. |
not_permitted | 403 | This action is not permitted with the API credentials you are using. |
business_not_found | 404 | No business matches the supplied business ID or report ID for this account. |
run_not_found | 404 | The requested run could not be found. |
run_in_progress | 409 | A run is already in progress for this business. |
validation_failed | 422 | One or more request fields are invalid. |
insufficient_business_data | 422 | The business details supplied are not enough to run a check. |
invalid_engines | 422 | One or more of the requested engines is not recognised. |
invalid_filter | 400 | A search filter was invalid. |
Completed run data
A completed run from GET https://api.insites.com/api/v1/ai-visibility/[ID] includes the following sections:
Property | Definition |
id | The AI Visibility run ID. |
status | The current run status. |
started_at | The date and time the run started. |
completed_at | The date and time the run completed. |
business | The business linked to the run. |
links | API links for the run. |
readiness | AI readiness checks for the business. |
engines | Results from each AI engine. |
insights | Summary insights and recommended fixes. |
Run statuses
Status | Definition |
pending | The run has been created and is waiting to start. |
processing | The run is in progress. |
completed | The run has completed successfully. |
failed | The run could not be completed. |
OpenAPI specification
A full machine-readable OpenAPI specification is available for this API.
You can import it into tools like Postman or Insomnia to explore the endpoints and generate client code.
