> This page is for Data API, version v2 (default).
> For other versions, use one of these documentation indexes:
> - v2 (default): https://developers.webflow.com/data/v2.0.0/llms.txt
> - v2 Beta: https://developers.webflow.com/data/v2.0.0-beta/llms.txt
> - v1: https://developers.webflow.com/data/v1.0.0/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.webflow.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.webflow.com/_mcp/server.

# Working with AEO Analytics

> Use the Webflow AEO Analytics API to read AI bot traffic, tracked prompts, visibility scores, and citations.

The AEO Analytics API lets you read how AI bots visit your site, and how answer engines mention and cite you. AEO, or answer engine optimization, is the practice of improving how your content appears in AI-generated answers. Use the API to build reporting dashboards, sync metrics into other tools, or track how your brand shows up in answers over time.

Every endpoint is a read-only `GET` request.

> **AEO analytics entitlement required**
>
> AEO Analytics endpoints require an access token with the `sites:read` scope and a site or workspace with the AEO analytics entitlement. Every endpoint except the two bot traffic endpoints also requires Webflow AI to be enabled for the workspace.

## Choose an endpoint

Each endpoint answers a different question. Pick the one that matches what you want to measure.

### Bot traffic

#### [Get Bot Traffic](/data/reference/aeo-analytics/get-bot-traffic)

The total requests made to your site by the AI bots Webflow tracks.

#### [Get Bot Traffic by Page](/data/reference/aeo-analytics/get-bot-traffic-by-page)

The pages and files those bots requested most.

### Prompts

#### [List Prompts](/data/reference/aeo-analytics/list-prompts)

The prompts you track, with each one's topic and status.

#### [List Prompt Executions](/data/reference/aeo-analytics/list-prompt-executions)

The answer engine responses to your prompts, with their mentions and citations.

#### [Get Prompt Execution](/data/reference/aeo-analytics/get-prompt-execution)

One response, including its full text.

### Visibility

#### [Get Visibility Score](/data/reference/aeo-analytics/get-visibility-score)

The share of responses that mention your organization, for a time range or as a daily or weekly series.

#### [Get Visibility Score Breakdown](/data/reference/aeo-analytics/get-visibility-score-breakdown)

The visibility score for each topic or prompt.

### Citations

#### [Get Citation Rate](/data/reference/aeo-analytics/get-citation-rate)

The share of responses with citations that cited your domains, for each topic or prompt.

#### [Get Top Cited Domains](/data/reference/aeo-analytics/get-top-cited-domains)

The domains answer engines cited most, with each one's share of all citations.

#### [Get Cited Paths for a Domain](/data/reference/aeo-analytics/get-cited-paths-for-a-domain)

The cited paths on one domain.

#### [Get Page Citation Share](/data/reference/aeo-analytics/get-page-citation-share)

One page's share of citations to your domains.

#### [List Competitor Citations](/data/reference/aeo-analytics/list-competitor-citations)

The responses that cited a competitor and none of your domains.

#### [List Citations](/data/reference/aeo-analytics/list-citations)

Every response, with all its citations and mentions.

## Core concepts

### Bot traffic and prompt data

The endpoints read two separate sets of data:

* **Bot traffic** counts requests made to your site by the AI bots Webflow tracks, such as crawlers from OpenAI or Anthropic. Webflow records it from requests that reach your site.
* **Prompt data** covers everything else. You track prompts, which are questions that Webflow asks answer engines. The visibility and citation reports are all calculated from the responses to those prompts.

Filtering one set doesn't affect the other. A bot provider such as `openai` isn't the same as an answer engine such as `chat-gpt`, and each is filtered with its own parameter.

Bot traffic counts requests from bots, not visitors or page views. For visitor traffic, use the [Analyze API](/data/docs/working-with-analyze).

### Topics, prompts, and executions

Prompt data is organized in three levels:

* **Topic**: A group of related prompts, such as "Galactic travel."
* **Prompt**: A question you track, such as "What's the best guide for traveling the galaxy?" Webflow runs each prompt through ChatGPT, Claude, Gemini, and Perplexity once a day.
* **Prompt execution**: One answer from one answer engine to one prompt.

Call [List Prompts](/data/reference/aeo-analytics/list-prompts) first. Each topic and prompt has an `id`. Use these IDs as filters in the visibility and citation endpoints.

A prompt's `status` is `active`, `paused`, `pending`, or `archived`. List Prompts returns `active`, `paused`, and `pending` prompts by default. Set `status` to `archived` or `all` to include archived prompts.

Each execution lists the `mentions` and `citations` found in the answer. A mention is your organization name or one of its aliases. A citation is a URL the answer cited. To see competitor citations, use [List Competitor Citations](/data/reference/aeo-analytics/list-competitor-citations).

### Visibility score and citation rate

Both measures are fractions from 0 to 1. For example, `0.42` means 42%.

* **Visibility score**: The share of responses to your tracked prompts that mention your organization name or one of its aliases.
* **Citation rate**: Of the responses that cited at least one source, the share that cited one of your domains.

Your domains are your Allowed domains and your `webflow.io` subdomain, each with and without `www.`. Citation responses list them in `domains`.

### Organization info

Some endpoints depend on the organization details saved on the site:

* The visibility endpoints match responses against the organization name and aliases saved in the site's Organization info. They return `brandNames` so you can see which names were matched. Without an organization name, they return `400 brand_not_configured`.
* List Competitor Citations uses the competitors saved in Organization info. Without an organization name, it returns `400 brand_not_configured`. If no competitor has a domain, it returns `400 competitors_not_configured`.

The bot traffic, prompt, and execution endpoints don't return `brandNames`. A missing organization name doesn't block them. Sending `brandNames` as a query parameter returns `400 aeo_input_validation`.

### Time windows

Pass `startTime` and `endTime` as UTC timestamps ending in `Z`, for example `2026-09-01T00:00:00Z`. Don't send offsets or date-only values. `startTime` is inclusive, and `endTime` is exclusive.

The rules depend on the endpoint:

* **Reports** require `startTime` and `endTime`. The window can span at most **100 days**, and `endTime` must be later than `startTime`. This covers the bot traffic, visibility, and citation endpoints.
* **Bot traffic** also requires `endTime` to be no later than the start of the current UTC day, because today's data isn't available yet.
* **List Prompt Executions** takes an optional window of at most **90 days**. If you omit `endTime`, it's now. If you omit `startTime`, it's 90 days before `endTime`.
* **List Prompts** and **Get Prompt Execution** take no time window.

### Filtering

Narrow the visibility and citation reports to a subset of your prompt data with these parameters. Repeat a parameter to pass more than one value, for example `topicIds=ID1&topicIds=ID2`. Don't use comma-separated values.

* `topicIds`: Include only these topics, up to 50.
* `promptIds`: Include only these prompts, up to 50.
* `answerEngine`: Include only one answer engine. The visibility endpoints and List Prompt Executions use this singular form.
* `answerEngines`: Include only these answer engines, up to 4. The citation endpoints use this plural form.

Answer engines are `chat-gpt`, `gemini`, `claude`, and `perplexity`.

List Prompts and List Prompt Executions filter by a single `topicId`, and List Prompt Executions also takes a single `promptId`. You can't send `promptId` and `topicId` together.

Separate filters combine with AND. Values within one filter combine with OR. Each endpoint supports its own set of filters, so check the parameters on the endpoint's reference page.

Bot traffic endpoints filter by bot instead. Use `botProviders` for one or more providers, and `botCategory` for one of `agent`, `indexer`, `training`, or `multiple`.

### Daily and weekly series

[Get Visibility Score](/data/reference/aeo-analytics/get-visibility-score) returns one score for the whole time range. To get one score per day or week, send both `timeseries[granularityPeriod]` and `timeseries[bucketTimeZone]`:

```text
timeseries[granularityPeriod]=day&timeseries[bucketTimeZone]=America/New_York
```

`granularityPeriod` is `day` or `week`. Weeks start on Sunday. `bucketTimeZone` must be a valid IANA time zone, such as `UTC` or `America/New_York`. Bucket timestamps are returned as UTC instants.

### Pagination

Endpoints paginate in one of three ways:

* **List Prompts** and **List Prompt Executions** use cursors. When a response includes `nextCursor`, pass it as `cursor` to get the next page. `nextCursor` is present whenever a page is full, so the next page can be empty.
* **List Citations** uses `limit` and `offset`. To get the next page, set `offset` to the previous `offset` plus `limit`. The response includes `hasMore`.
* **All other endpoints** return a single response and aren't paginated.

## Rate and concurrency limits

AEO Analytics has two limits:

* **Rate limit**: The standard per-minute Data API [rate limit](/data/reference/rate-limits), based on the site plan.
* **Concurrency limit**: Each access token can have one AEO request in flight at a time, across all AEO Analytics endpoints.

If either limit is exceeded, the request fails with `429 Too Many Requests` and a `Retry-After` header. Send AEO calls one at a time, and retry after the `Retry-After` interval.

## Errors

AEO Analytics validates each request and returns `400 Bad Request` with a `code` that identifies the rule that failed:

| Code                         | Meaning                                                                                                                         |
| :--------------------------- | :------------------------------------------------------------------------------------------------------------------------------ |
| `aeo_input_validation`       | A parameter is missing, invalid, or not recognized, or a `cursor` isn't valid. The `details` array lists each failing field.    |
| `validation_error`           | `site_id` or `execution_id` isn't a valid ID.                                                                                   |
| `invalid_time_range`         | `endTime` isn't later than `startTime`.                                                                                         |
| `time_range_too_wide`        | The time range is longer than 100 days, or longer than 90 days for List Prompt Executions.                                      |
| `end_time_too_recent`        | On the bot traffic endpoints, `endTime` is later than the start of the current UTC day.                                         |
| `unsupported_bot_provider`   | A `botProviders` value isn't a supported provider.                                                                              |
| `conflicting_scope_filters`  | A List Prompt Executions request sent both `promptId` and `topicId`.                                                            |
| `brand_not_configured`       | The site has no organization name in Organization info. This applies to the visibility endpoints and List Competitor Citations. |
| `competitors_not_configured` | No competitor in Organization info has a domain. This applies to List Competitor Citations.                                     |

Requests can also fail with these errors:

| Status | Code                       | Meaning                                                                                                                                |
| :----- | :------------------------- | :------------------------------------------------------------------------------------------------------------------------------------- |
| `403`  | `missing_scopes`           | The token is missing the `sites:read` scope.                                                                                           |
| `403`  | `forbidden`                | The site doesn't have the AEO analytics entitlement, or Webflow AI isn't enabled for the workspace.                                    |
| `403`  | `insufficient_permissions` | The user who authorized the token doesn't have permission.                                                                             |
| `404`  | `resource_not_found`       | The site wasn't found, or the access token can't access it. For Get Prompt Execution, no execution on the site matches `execution_id`. |

## Walkthrough: measure AI bot traffic

Imagine you're reporting on how AI bots visit your site. You want to know how many requests the `agent` bots from OpenAI made last week, and then which pages they requested most.

#### Request the bot traffic total

Call Get Bot Traffic with a window that ends at the start of a UTC day, a `botProviders` value, and a `botCategory`.

```bash
curl --request GET \
  --url 'https://api.webflow.com/v2/sites/{site_id}/aeo/reports/bot_traffic?startTime=2026-09-01T00:00:00Z&endTime=2026-09-08T00:00:00Z&botProviders=openai&botCategory=agent' \
  --header 'authorization: Bearer YOUR_API_TOKEN' \
  --header 'accept: application/json'
```

#### Read the total

`totalRequestCount` is the number of successful requests the bots made to your site. It isn't a count of visitors. The `filter` field echoes the filters you sent.

```json
{
  "report": "bot_traffic",
  "window": {
    "startTime": "2026-09-01T00:00:00Z",
    "endTime": "2026-09-08T00:00:00Z"
  },
  "totalRequestCount": 4242,
  "filter": {
    "botProviders": ["openai"],
    "botCategory": "agent"
  }
}
```

#### List the pages bots requested most

Call Get Bot Traffic by Page with the same window and filters. Results are sorted by `requestCount`, highest first.

```bash
curl --request GET \
  --url 'https://api.webflow.com/v2/sites/{site_id}/aeo/reports/bot_traffic_pages?startTime=2026-09-01T00:00:00Z&endTime=2026-09-08T00:00:00Z&botProviders=openai&botCategory=agent&limit=10' \
  --header 'authorization: Bearer YOUR_API_TOKEN' \
  --header 'accept: application/json'
```

Each row is a page, a CMS item, or a file. A file with no page, such as `/sitemap.xml`, has only a `title`, set to its path.

```json
{
  "report": "bot_traffic_pages",
  "window": {
    "startTime": "2026-09-01T00:00:00Z",
    "endTime": "2026-09-08T00:00:00Z"
  },
  "data": [
    { "requestCount": 420, "page": { "pageId": "68cdb4b5a699862fcd8c1a31", "title": "Home" } },
    {
      "requestCount": 42,
      "page": {
        "pageId": "68cdb4b5a699862fcd8c1a30",
        "collectionId": "68cdb4b5a699862fcd8c1a40",
        "itemSlug": "dont-panic",
        "title": "Don't Panic"
      }
    },
    { "requestCount": 7, "page": { "title": "/sitemap.xml" } }
  ]
}
```

## Walkthrough: find where competitors are cited instead of you

Imagine you want to know which topics answer engines rarely connect with your brand, and which competitor sites they cite instead. This walkthrough finds your topics, compares their visibility, and then lists the responses that cited a competitor.

#### List your topics

Call List Prompts to see your tracked prompts and the topic each belongs to. Note the topic IDs.

```bash
curl --request GET \
  --url 'https://api.webflow.com/v2/sites/{site_id}/aeo/prompts?limit=50' \
  --header 'authorization: Bearer YOUR_API_TOKEN' \
  --header 'accept: application/json'
```

Each item includes the prompt's `topic`. In this example, the prompt belongs to the "Galactic travel" topic.

```json
{
  "items": [
    {
      "id": "68cdb4b5a699862fcd8c1a01",
      "text": "What's the best guide for traveling the galaxy?",
      "topic": { "id": "68cdb4b5a699862fcd8c1a02", "name": "Galactic travel" },
      "tags": [],
      "status": "active",
      "createdAt": "2026-08-01T16:20:42.000Z"
    }
  ]
}
```

#### Compare visibility by topic

Call Get Visibility Score Breakdown with `breakdown=topic`. Results are sorted by `visibilityScore`, highest first.

```bash
curl --request GET \
  --url 'https://api.webflow.com/v2/sites/{site_id}/aeo/reports/visibility_breakdown?startTime=2026-09-01T00:00:00Z&endTime=2026-09-08T00:00:00Z&breakdown=topic' \
  --header 'authorization: Bearer YOUR_API_TOKEN' \
  --header 'accept: application/json'
```

`brandNames` shows the organization name and aliases the report matched. Here, the "Galactic travel" topic has a visibility score of 0.42, so 42% of its responses mention your organization. That's much lower than the "Towels" topic at 0.9.

```json
{
  "report": "visibility_breakdown",
  "window": {
    "startTime": "2026-09-01T00:00:00Z",
    "endTime": "2026-09-08T00:00:00Z"
  },
  "breakdown": "topic",
  "brandNames": ["Hitchhiker's Guide", "The Guide"],
  "data": [
    { "visibilityScore": 0.9, "topic": { "id": "68cdb4b5a699862fcd8c1a03", "name": "Towels" } },
    { "visibilityScore": 0.42, "topic": { "id": "68cdb4b5a699862fcd8c1a02", "name": "Galactic travel" } }
  ]
}
```

#### List the responses that cited a competitor

Call List Competitor Citations with the weaker topic's ID. It returns the newest responses that cited a competitor's domain and none of your domains.

```bash
curl --request GET \
  --url 'https://api.webflow.com/v2/sites/{site_id}/aeo/reports/competitor_citations?startTime=2026-09-01T00:00:00Z&endTime=2026-09-08T00:00:00Z&topicIds=68cdb4b5a699862fcd8c1a02&limit=10' \
  --header 'authorization: Bearer YOUR_API_TOKEN' \
  --header 'accept: application/json'
```

`competitorDomains` lists the competitor domains the report checked, which come from the competitors in Organization info. Each row shows the prompt, the answer engine, and the URLs the response cited.

```json
{
  "report": "competitor_citations",
  "window": {
    "startTime": "2026-09-01T00:00:00Z",
    "endTime": "2026-09-08T00:00:00Z"
  },
  "competitorDomains": ["example.net", "www.example.net"],
  "data": [
    {
      "timestamp": "2026-09-07T06:00:12.000Z",
      "topic": { "id": "68cdb4b5a699862fcd8c1a02", "name": "Galactic travel" },
      "prompt": {
        "id": "68cdb4b5a699862fcd8c1a01",
        "text": "What's the best guide for traveling the galaxy?"
      },
      "answerEngine": { "key": "perplexity", "name": "Perplexity" },
      "citations": [
        "https://example.net/travel",
        "https://example.org/travel/guides"
      ]
    }
  ]
}
```

From here, try another endpoint to answer a different question:

* [Get Top Cited Domains](/data/reference/aeo-analytics/get-top-cited-domains): which sites answer engines cite most
* [Get Page Citation Share](/data/reference/aeo-analytics/get-page-citation-share): how often answer engines cite one of your pages
* [Get Prompt Execution](/data/reference/aeo-analytics/get-prompt-execution): the full text of a single answer

To browse every endpoint, see [Choose an endpoint](#choose-an-endpoint).