> For the complete documentation index, see [llms.txt](https://docs.airops.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.airops.com/developers/tools.md).

# Tools

The AirOps MCP server tools reference: give Claude, Cursor, and other AI assistants programmatic access to AEO analytics, Brand Kits, Grids, Knowledge Bases, Playbooks, and Workflows in your AirOps wo

The AirOps MCP server gives AI assistants like Claude and Cursor programmatic, AI-native access to your AirOps workspace. This page lists the tools it exposes for accessing and managing your data, organized into several areas: **AEO** (Answer Engine Optimization) for AI visibility analytics, prompt setup, and reports, **Brand Management** for managing brand identity, writing style, and visual assets, **Grids** for reading, writing, and creating Grid data programmatically, **Knowledge Bases** for semantic search and document ingestion, and **Playbooks and Workflows** for inspecting definitions, reviewing feedback, and running work.

List and get tools support filtering, field selection, sorting, and pagination where applicable. Write tools document their required fields in each section.

## Plan access

Resource tools require a paid workspace. Paid-tier trials remain eligible. Free workspaces can connect, discover tools, and use `list_workspaces`, but requests for their data return a plan restriction. If you belong to both Free and paid workspaces, choose a paid workspace for resource queries and changes.

## Workspace & Brand Kit

### `list_workspaces`

List all workspaces you have access to.

**Returns:** Workspace ID, name, slug, and subscription tier.

| Parameter   | Values            |
| ----------- | ----------------- |
| **Filters** | name, tier        |
| **Sort**    | name, created\_at |

***

### `list_brand_kits`

List all Brand Kits you have access to. Returns `brand_management_enabled` and `aeo_enabled` flags for each Brand Kit, so you know which capabilities are available.

* Use `get_brand_kit` for Brand Kits with `brand_management_enabled: true`
* Use `get_insights_settings` for Brand Kits with `aeo_enabled: true`

**Returns:** Brand Kit ID, name, about, URL, workspace name, `brand_management_enabled`, and `aeo_enabled`.

| Parameter   | Values                                                                             |
| ----------- | ---------------------------------------------------------------------------------- |
| **Filters** | workspace\_name, brand\_name, brand\_url, brand\_management\_enabled, aeo\_enabled |
| **Sort**    | brand\_name, created\_at                                                           |

***

### `get_brand_kit`

Get a specific Brand Kit by ID for brand management and content creation. Returns brand identity, writing style, and related entities.

**Requires:** `id`

**Returns:** Brand name, URL, about, writing persona, writing tone, status, and timestamps. Optionally includes related entities with nested data.

| Parameter    | Values                                                                                                                                                                                                                              |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Includes** | product\_lines, product\_lines.competitors, audiences, audiences.writing\_rules, content\_types, content\_types.content\_samples, content\_types.writing\_rules, regions, regions.writing\_rules, writing\_rules, custom\_variables |

***

### `get_insights_settings`

Get AEO insights configuration for a Brand Kit. Returns the information needed to use any AEO and analytics tools.

**Requires:** `id`

**Returns:** Brand Kit ID, name, URL, countries, AEO status, prompt count, customer description, competitors with domain URLs, and personas.

***

### `update_brand_kit`

Update a Brand Kit's base fields. Only provided fields are changed.

**Requires:** `brand_kit_id`

**Updatable fields:** `brand_name`, `brand_url`, `brand_about`, `writing_persona`, `writing_tone`

***

### `list_topics`

List topics configured for a Brand Kit.

**Requires:** `brand_kit_id`

**Returns:** Topic ID, name, and color.

| Parameter   | Values            |
| ----------- | ----------------- |
| **Filters** | name              |
| **Sort**    | name, created\_at |

***

### `create_topic`

Create a new topic for a Brand Kit. Topics group tracked prompts and analytics views by theme.

**Requires:** `brand_kit_id`, `name`

**Optional fields:** `color`

***

### `update_topic`

Update a topic's name or color. Existing prompt assignments stay attached to the topic.

**Requires:** `brand_kit_id`, `topic_id`

**Fields:** `name`, `color`

***

### `delete_topic`

Delete a topic from a Brand Kit.

**Requires:** `brand_kit_id`, `topic_id`

{% hint style="warning" %}
Deleting a topic can affect prompt organization and reporting views. Confirm the topic and downstream impact before calling this tool.
{% endhint %}

***

### `list_personas`

List personas configured for a Brand Kit.

**Requires:** `brand_kit_id`

**Returns:** Persona ID, title, and description.

| Parameter   | Values             |
| ----------- | ------------------ |
| **Filters** | title              |
| **Sort**    | title, created\_at |

***

### `publish_brand_kit`

Publish a Brand Kit's current draft so changes become active. All changes made via `update_brand_kit` and `manage_brand_kit_*` are applied to a draft. Publishing promotes the draft to active and creates a fresh draft from it.

**Requires:** `brand_kit_id`

{% hint style="warning" %}
Always confirm with the user before publishing. This makes all pending changes live.
{% endhint %}

***

### `create_brand_kit_recap_entry`

Record a recap entry summarizing Brand Kit changes made during an MCP session. Use this once near the end of a session that changed the Brand Kit, with evidence such as source URLs, page names, or short quotes in `body_markdown`.

**Requires:** `brand_kit_id`, `title`

**Optional fields:** `body_markdown`

**Returns:** Recap entry ID, title, source, and success message.

***

## Brand Kit Management

Tools for creating and updating Brand Kit entities. Each tool supports both create (omit `id`) and update (provide `id`) operations. On update, only provided fields are changed.

{% hint style="info" %}
Changes are saved to a **draft**. Use `publish_brand_kit` to make them active.
{% endhint %}

### `manage_brand_kit_product_line`

Create or update a product line for a Brand Kit.

**Requires:** `brand_kit_id`

**Fields:** `name` (required on create), `url`, `details`, `positioning`, `ideal_customer_profile`

***

### `manage_brand_kit_competitor`

Create or update a competitor for a Brand Kit. Competitors must be associated with at least one product line.

**Requires:** `brand_kit_id`

**Fields:** `name` (required on create), `domain`, `product_line_ids` (at least one required)

***

### `manage_brand_kit_audience`

Create or update an audience for a Brand Kit.

**Requires:** `brand_kit_id`

**Fields:** `name` (required on create), `description`

***

### `manage_brand_kit_region`

Create or update a region for a Brand Kit.

**Requires:** `brand_kit_id`

**Fields:** `name` (required on create), `description`, `icon_name` (flag icon, e.g., `flag-us`)

***

### `manage_brand_kit_content_type`

Create or update a content type for a Brand Kit. On create, you can provide a `sample_url` to seed the content type. The system will scrape the URL and use AI to generate fields automatically.

**Requires:** `brand_kit_id`

**Fields:** `name` (required on create), `template_outline`, `cta_text`, `cta_url`, `header_case` (title\_case, sentence\_case, custom), `header_case_custom_value`, `sample_url` (create only)

***

### `manage_brand_kit_content_sample`

Create or update a content sample for a Brand Kit. On create, the sample URL is processed asynchronously to extract content.

**Requires:** `brand_kit_id`

**Fields:** `url` (required on create), `content_type_id` (required on create), `content` (update only), `audience_ids`, `region_ids`

***

### `manage_brand_kit_writing_rule`

Create or update a writing rule for a Brand Kit. Rules can be global or scoped to a single content type, audience, or region (mutually exclusive). Scoping is set on create only.

**Requires:** `brand_kit_id`

**Fields:** `text` (required on create), `content_type_id` (create only), `audience_id` (create only), `region_id` (create only)

***

### `manage_brand_kit_custom_variable`

Create or update a custom variable for a Brand Kit. Custom variables are discouraged for most use cases. Prefer using regions, audiences, content types, or writing rules instead.

**Requires:** `brand_kit_id`

**Fields:** `name` (required on create), `value` (required on create)

***

### `create_brand_kit_direct_upload`

Initiate a direct upload for Brand Kit visual assets such as logos, visual examples, and font files. The tool returns a presigned upload URL, upload headers, and a `signed_id` to pass to the relevant visual asset manage tool.

**Requires:** `brand_kit_id`, `filename`, `content_type`, `byte_size`, `checksum`

**Returns:** `signed_id`, `upload_url`, and `upload_headers`.

***

### `manage_brand_kit_palette`

Create or update a color palette for a Brand Kit draft.

**Requires:** `brand_kit_id`

**Fields:** `name` (required on create)

***

### `manage_brand_kit_palette_color`

Create or update a color inside a Brand Kit palette.

**Requires:** `brand_kit_id`

**Fields:** `palette_id` (required on create), `name` (required on create), `value` (required on create), `usage_instructions`

***

### `manage_brand_kit_logo_variant`

Create or update a logo variant for a Brand Kit draft. Attach a file with `signed_id` from `create_brand_kit_direct_upload` or with a public `file_url`.

**Requires:** `brand_kit_id`

**Fields:** `name` (required on create), `background_color`, `usage_instructions`, `signed_id`, `file_url`

***

### `manage_brand_kit_logo_size`

Create or update recommended logo dimensions and usage instructions.

**Requires:** `brand_kit_id`

**Fields:** `name` (required on create), `width`, `height`, `usage_instructions`

***

### `manage_brand_kit_font`

Create or update a Brand Kit font. Attach a font file with `signed_id` from `create_brand_kit_direct_upload` or with a public `file_url`.

**Requires:** `brand_kit_id`

**Fields:** `name` (required on create), `usage_instructions`, `google_font_link`, `signed_id`, `file_url`

***

### `manage_brand_kit_type_size`

Create or update a typography size associated with a Brand Kit font.

**Requires:** `brand_kit_id`

**Fields:** `font_id`, `name` (required on create), `weight`, `size`, `line_height`, `usage_instructions`

***

### `manage_brand_kit_usage_rule`

Create or update a Brand Kit usage rule. `applies_to` is set on create and cannot be changed later.

**Requires:** `brand_kit_id`

**Fields:** `name` (required on create), `applies_to` (required on create)

***

### `manage_brand_kit_visual_use_case`

Create or update a visual use case, a named group of visual examples with shared instructions.

**Requires:** `brand_kit_id`

**Fields:** `name` (required on create), `instructions`

***

### `manage_brand_kit_visual_example`

Create or update a visual example for a Brand Kit. Visual examples must be grouped under a visual use case. Attach an image with `signed_id` from `create_brand_kit_direct_upload` or with a public `file_url`.

**Requires:** `brand_kit_id`

**Fields:** `visual_use_case_id` (required on create), `title` (required on create), `sample_url`, `usage_instructions`, `signed_id`, `file_url`

***

### Edit a Brand Kit draft <a href="#suggest_brand_kit_edits" id="suggest_brand_kit_edits"></a>

Use `update_brand_kit` for base fields and the appropriate `manage_brand_kit_*` tool for related entities. Summarize the intended changes and get the user's confirmation before applying them.

These tools write directly to the draft. Read the draft back to verify the result and tell the user the changes are not yet active. Ask for explicit confirmation before calling `publish_brand_kit`; publishing is a separate action that makes all pending changes active.

The former `suggest_brand_kit_edits` interactive review tool is no longer available.

***

## AEO Prompts & Answers

### `list_aeo_prompts`

List tracked AI prompts for a Brand Kit.

**Requires:** `brand_kit_id`

**Returns:** Prompt ID, text, keyword, whether brand is mentioned, volume, topic ID, timestamps, mention\_rate, citation\_rate, and trends.

| Parameter        | Values                                                                                     |
| ---------------- | ------------------------------------------------------------------------------------------ |
| **Filters**      | text, strategy, brand\_mentioned, topic\_id, prompt\_volume, mention\_rate, citation\_rate |
| **Sort**         | text, created\_at, prompt\_volume, mention\_rate, citation\_rate                           |
| **Includes**     | topic, tags                                                                                |
| **Date filters** | start\_date, end\_date, providers, countries, personas                                     |

***

### `create_aeo_prompt`

Create a new tracked AEO prompt for a Brand Kit. Background jobs analyze the prompt, extract keywords, and compute volume metrics after creation.

**Requires:** `brand_kit_id`, `text`, `topic_id`

**Optional fields:** `countries`, `persona_ids`, `platforms`

{% hint style="warning" %}
Creating prompts can affect answer volume. Confirm the prompt text, topic, and assignments with the user before calling this tool.
{% endhint %}

***

### `get_prompt_answers`

Get AI answers for a specific prompt.

**Requires:** `prompt_id`

**Returns:** Answer ID, text (truncated), provider, country, brand\_mentioned, brand\_cited, timestamps, and the prompt's read-only `intent_stage` (`awareness`, `consideration`, `evaluation`, `purchase`, or `null`).

| Parameter    | Values              |
| ------------ | ------------------- |
| **Filters**  | countries, personas |
| **Sort**     | created\_at         |
| **Includes** | persona             |

***

### `get_answer`

Get a specific AI answer by ID with full text content.

**Requires:** `id`

**Returns:** Full answer text (not truncated), provider, country, brand\_mentioned, brand\_cited, read-only `intent_stage`, and optionally citations, mentions, and persona details.

| Parameter    | Values                       |
| ------------ | ---------------------------- |
| **Includes** | citations, mentions, persona |

Use this after `get_prompt_answers` to retrieve complete answer text with citation URLs and positions.

***

### `list_answers`

List AI answers across a Brand Kit with filters for date range, providers, countries, personas, and other AEO dimensions. Use this when you need answers across many prompts instead of answers for one prompt.

**Requires:** `brand_kit_id`

Each answer includes the prompt's read-only `intent_stage`, or `null` when classification is unavailable.

***

## AEO Setup and Prompt Management

### `create_aeo_persona`

Create a new AEO persona for a Brand Kit. Personas represent the user perspectives used to simulate AI search queries.

**Requires:** `brand_kit_id`, `title`, `description`

**Optional fields:** `add_to_all_prompts`

***

### `add_aeo_region`

Add an ISO alpha-2 country code to a Brand Kit's configured AEO regions.

**Requires:** `brand_kit_id`, `country_code`

**Optional fields:** `add_to_all_prompts`

***

### `list_tags`

List AEO tags configured for a Brand Kit.

**Requires:** `brand_kit_id`

| Parameter   | Values            |
| ----------- | ----------------- |
| **Filters** | name              |
| **Sort**    | name, created\_at |

***

### `create_aeo_tag`

Create a new AEO tag on a Brand Kit. Tags are user-defined labels that can be applied to prompts.

**Requires:** `brand_kit_id`, `name`

**Optional fields:** `color`

***

### `update_aeo_tag`

Update an AEO tag's name or color. Existing prompt taggings are preserved.

**Requires:** `brand_kit_id`, `tag_id`

**Fields:** `name`, `color`

***

### `delete_aeo_tag`

Delete an AEO tag from a Brand Kit and remove it from every prompt that uses it.

**Requires:** `brand_kit_id`, `tag_id`

{% hint style="warning" %}
This action permanently deletes the tag and removes its prompt taggings. Confirm the tag and impact before calling it.
{% endhint %}

***

### `bulk_update_aeo_prompt_tags`

Add or remove one or more tags across a batch of AEO prompts in one transaction.

**Requires:** `brand_kit_id`, `prompt_ids`, `operation`, `tag_ids`

**Operations:** `add`, `remove`

***

### `update_aeo_prompt_assignments`

Stage draft assignment changes for one or more AEO prompts. Assignments include countries, personas, and platforms. Changes do not become live until `commit_aeo_prompt_assignments` runs.

**Requires:** `brand_kit_id`, `prompts`

**Prompt fields:** `prompt_id`, `countries`, `persona_ids`, `platforms`

***

### `get_aeo_prompt_assignments_status`

Inspect the current prompt-assignment draft state for a Brand Kit. Use this to check whether a draft exists, whether it has changes, and whether committing it would exceed the workspace answer limit.

**Requires:** `brand_kit_id`

***

### `commit_aeo_prompt_assignments`

Commit the current prompt-assignment draft to live. This replaces live country, persona, and platform assignments with the draft state.

**Requires:** `brand_kit_id`

{% hint style="warning" %}
This affects live AEO tracking assignments. Confirm with the user before committing.
{% endhint %}

***

### `discard_aeo_prompt_assignments`

Discard the current prompt-assignment draft and create a fresh draft from live assignments.

**Requires:** `brand_kit_id`

{% hint style="warning" %}
This discards all pending assignment edits in the shared draft, including unsaved UI edits. Confirm with the user before calling it.
{% endhint %}

***

## Citations & Domains

Use `prompt_type` with operator `EQUALS` and value `brand` or `category` to filter by whether the prompt names your brand. Use `brand_mentioned` with operator `EQ` and value `true` or `false` to filter by whether the citing page mentions your brand.

The older `brand_mentioned EQUALS brand/category` and `brand_referenced EQ true/false` filters remain accepted as compatibility aliases. Prefer the explicit names above; they take precedence when both old and new filters are supplied. The `brand_mentioned` filter on `list_aeo_prompts` still refers to the prompt text.

### `list_aeo_citations`

List citations (URLs) with metrics for a Brand Kit. Shows individual URLs being cited in AI answers.

**Requires:** `brand_kit_id`

**Returns:** URL, domain name, domain category, citation count, citation share, citation rate, influence score, page type, brand sentiment, trends, and social metadata when available.

The `social` object identifies the platform and contains `content` and `account` envelopes with metadata, metrics, and sync status. It is `null` when no supported social record exists. The account can be `null` when content exists without an associated account. Pending or failed collection can leave metadata incomplete.

YouTube content metadata includes `duration_seconds`, `format`, and `sponsorship_status`. Duration can be `null`; format and sponsorship status use `unknown` when unavailable.

| Parameter        | Values                                                                                                                                |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| **Filters**      | domain\_category, domain\_id, topic\_id, prompt\_type, brand\_mentioned, page\_type, brand\_sentiment, mentioned\_competitor\_domains |
| **Sort**         | citation\_count, citation\_share, citation\_rate, influence\_score                                                                    |
| **Date filters** | start\_date, end\_date, providers, countries, personas                                                                                |

**Domain categories:** Owned, Competitors, Social, Communities, Reviews, Media, Educational, Marketplaces, Products, Affiliates, Other

***

### `get_aeo_citation`

Get details and prompts citing a specific URL.

**Requires:** `brand_kit_id`, `id` (the citation/URL ID)

**Returns:** URL details, citation metrics, influence score breakdown, page type, brand sentiment, mentioned competitors, and the same `social` envelope returned by `list_aeo_citations`.

***

### `list_aeo_domains`

List domains cited in AI answers for a Brand Kit. Aggregated by domain with citation metrics.

**Requires:** `brand_kit_id`

**Returns:** Domain ID, name, category, logo URL, citation count, URL count, citation share, citation rate, and trends.

| Parameter        | Values                                                                                    |
| ---------------- | ----------------------------------------------------------------------------------------- |
| **Filters**      | domain\_category, topic\_id, prompt\_type, brand\_mentioned, page\_type, brand\_sentiment |
| **Sort**         | citation\_count, citation\_share, citation\_rate                                          |
| **Date filters** | start\_date, end\_date, providers, countries, personas                                    |

***

## AEO Observed Ads & Advertisers

Ads AirOps observes in ChatGPT and Google AI Mode answers for your tracked prompts. These tools query observed ad data used by [Ads](/insights/ads.md), including **Ad Library**, so they need no ChatGPT Ads account connection.

{% hint style="info" %}
Coverage is limited to ads AirOps has seen in its own answer collection. These numbers do not describe full market coverage, targeting intent, impression delivery, or advertiser spend.
{% endhint %}

### `list_aeo_ads`

List ads observed in ChatGPT and Google AI Mode answers for a Brand Kit. Each row represents a platform and observed creative pair. The same creative on two platforms produces two rows, each with its own activity counts.

**Requires:** `brand_kit_id`

**Returns:** Provider, observed creative ID, observed family ID, advertiser name, domain, type and logo, ad title and body, appearances, answers, prompts, frequency, first\_seen, last\_seen, and days\_active.

| Parameter        | Values                                                       |
| ---------------- | ------------------------------------------------------------ |
| **Filters**      | topic\_id, prompt\_id, prompt\_type                          |
| **Date filters** | start\_date, end\_date, providers, countries, personas, tags |

**Advertiser types:** owned, competitor, other

`list_aeo_ads` includes both supported providers by default. Pass `providers: ["chat_gpt"]` or `providers: ["google_ai_mode"]` to narrow the scope. Use `prompt_type EQUALS brand/category` for prompt classification; the former `brand_mentioned` prompt-type filter remains a compatibility alias.

***

### `get_aeo_ad`

Get one observed ad, including its creative image and destination URL.

**Requires:** `brand_kit_id`, `id` (the `observed_creative_id` returned by `list_aeo_ads`)

**Returns:** Provider, observed creative ID, observed family ID, advertiser name, domain, type and logo, ad title, body, image\_url, target\_url, first\_seen, last\_seen, and days\_active.

Pass the row's provider as a single-element `providers` array along with its creative ID, for example `providers: ["google_ai_mode"]`. Detail requests default to ChatGPT when no provider is specified and require a single provider when one is supplied.

The windowed metrics reported by `list_aeo_ads` (appearances, answers, prompts, frequency) are not returned here.

***

### `list_aeo_advertisers`

List advertisers observed in ChatGPT and Google AI Mode answers for a Brand Kit. Every observed ad rolls up to the advertiser that ran it, identified by canonical domain.

**Requires:** `brand_kit_id`

**Returns:** Advertiser ID, name, domain, type, logo URL, unique ad count, appearances, answers, prompts, first\_seen, and last\_seen.

| Parameter        | Values                                                                                            |
| ---------------- | ------------------------------------------------------------------------------------------------- |
| **Filters**      | topic\_id, prompt\_id, prompt\_type                                                               |
| **Sort**         | advertiser\_name, advertiser\_domain, ads, appearances, answers, prompts, first\_seen, last\_seen |
| **Date filters** | start\_date, end\_date, providers, countries, personas, tags                                      |

Results are sorted by unique ad count, most prolific first, unless you pass **Sort**. Use `list_aeo_ads` for the individual ads behind each advertiser's counts.

***

## Playbooks & Feedback

Read Playbook definitions, inspect Session outputs and reviewer comments, and run or publish Playbooks with your existing workspace permissions. Publishing and running require user OAuth authentication. Runs can consume workspace credits and perform the actions configured in the Playbook.

### `list_playbooks`

List editable Playbooks, including draft and active-version metadata.

**Requires:** `workspace_id`

**Optional:** `search` (title), `page` (default 1), `per_page` (default 20, maximum 50).

### `get_playbook`

Read a Playbook's configuration and definition as Markdown. Integration references do not expose credentials.

**Requires:** `playbook_id`

**Optional:** `version_number`. Omit it to read the current draft (**Latest**); provide a number to read an immutable published version.

### `list_playbook_sessions`

List Sessions in reverse chronological order.

**Requires:** `workspace_id`

**Optional:** `playbook_id`, `status`, `search` (Session or creator name), `page` (default 1), `per_page` (default 20, maximum 50). Archived Sessions use the public status `archived`.

### `get_playbook_session`

Inspect Session metadata and a page of events, including text, tool results, artifacts, and completion state.

**Requires:** `session_id`

**Optional:** `after_id` (event cursor), `limit` (default 20, maximum 50).

Pass the returned `next_after_id` as `after_id` to continue until it is `null`. Text previews are capped at 2,000 characters; `content_truncated: true` indicates that more text exists. Use `read_playbook_output` for the full output.

### `read_playbook_output`

Read one text output in character-based pages. Collaborative text artifacts reflect current editor content, including edits made after the run. Binary artifacts are unsupported.

**Requires:** `session_id` and exactly one of `event_id` or `artifact_path`. Artifact paths must identify a file under `artifacts/external/`.

**Optional:** `offset` (default 0), `max_chars` (default 20,000, maximum 200,000).

**Returns:** `content`, `offset`, `total_chars`, and `next_offset`. Pass `next_offset` back as `offset` until it is `null`.

### `list_artifact_comments`

Read reviewer comments with author, timestamps, resolution state, and available anchor or surrounding-text context.

**Requires:** `session_id`

**Optional:** `artifact_path` to limit results to one artifact.

Use the comments alongside `read_playbook_output` to review feedback in context. Tracked-change suggestions are counted separately in `suggestions_count`; they are not comment threads. This tool reads feedback without modifying it.

### `publish_playbook`

Publish the current draft as a new active version.

**Requires:** `playbook_id` and user OAuth authentication.

**Optional:** `notes` for the published version.

**Returns:** The active version ID and version metadata. Confirm the draft and publication intent before calling this tool; publishing makes the pending draft active.

### `run_playbook`

Start an asynchronous Session. Each call starts a new run.

**Requires:** `playbook_id` and user OAuth authentication.

**Optional:** `inputs` keyed by input name, `message`, and `version_number`.

By default, this runs the current draft (**Latest**). Pass `version_number` to run a specific published version. Running a draft does not publish it. Confirm the intended version, inputs, and execution before starting.

**Returns:** `session_id`, `session_uuid`, status, and version information. Poll `get_playbook_session`, then read outputs and comments as needed.

## Workflows

List executable Workflows and start or inspect runs with your workspace permissions. Runs can consume credits and perform the Workflow's configured actions.

### `list_workflows`

List published Workflows you can execute. Draft-only, deleted, agent, and legacy resources are excluded.

**Requires:** `workspace_id`

**Optional:** `search`, `page` (default 1), `per_page` (default 20, maximum 50).

### `run_workflow`

Start an asynchronous execution. Each call starts a new run.

**Requires:** `workflow_id`

**Optional:** `inputs` keyed by input name and `version_number`.

The default is the active published version. Pass `version_number` to select another published version. Confirm the intended Workflow, inputs, and execution before starting.

**Returns:** `execution_id`, status, and Workflow/version information.

### `get_workflow_execution`

Inspect a run's status, output, or error.

**Requires:** `execution_id` returned by `run_workflow`.

Poll this tool to follow the run through states such as `pending`, `running`, `review_needed`, `success`, `error`, or `cancelled`. A returned execution ID means the run started; check its status before treating its output as complete.

## Example: review a Playbook run

1. Find the Playbook with `list_playbooks` and inspect its definition with `get_playbook`.
2. Find a Session with `list_playbook_sessions`, then read its events with `get_playbook_session`.
3. Read the full text with `read_playbook_output` and reviewer feedback with `list_artifact_comments`.
4. Summarize the output and unresolved feedback for the reviewer.

## Page Analytics

### `list_pages`

List pages with AEO, Google Search Console, and GA4 metrics.

**Requires:** `brand_kit_id`

**Returns:** For each page: URL, folder path, primary keyword, and metrics:

* **AEO:** citations\_count, citation\_rate, prompts\_count, and trends
* **GSC:** clicks, impressions, ctr, position, and trends
* **GA4:** traffic, sessions, engagement, average\_session\_engagement, and trends
* **Agent Analytics:** `user_browse` (AI Agent Visits), `ai_training` (Training Crawls), and `ai_search` (Web Search Crawls)

Agent Analytics must be connected first. Its three counts support filtering and sorting for the selected dates, without change variants. Use `list_aeo_agent_analytics` for Total Crawls and daily breakdowns.

| Parameter         | Values                                                                                                 |
| ----------------- | ------------------------------------------------------------------------------------------------------ |
| **Filters**       | Any metric field, url, folder\_name, primary\_keyword, session\_source, session\_medium                |
| **Sort**          | All metric fields, url, folder\_name                                                                   |
| **Smart filters** | almost\_page\_one, losing\_clicks, rankings\_slipping, losing\_ai\_visibility, citation\_rate\_decline |

**Smart filters** (use instead of manual filtering):

| Filter                  | Description                                  |
| ----------------------- | -------------------------------------------- |
| `almost_page_one`       | Pages ranking #11-20 (quick wins for page 1) |
| `losing_clicks`         | Declining clicks with stable position        |
| `rankings_slipping`     | Position declining over time                 |
| `losing_ai_visibility`  | Losing AEO citations                         |
| `citation_rate_decline` | Losing AI authority with stable SEO          |

***

### `create_page`

Add a page to a Brand Kit's AEO pages. AirOps normalizes the URL, verifies that it belongs to the Brand Kit's configured AEO domain, and requires it to be unique within that Brand Kit.

**Requires:** `brand_kit_id`, `url`

**Returns:** Page ID, Brand Kit ID, AEO domain ID, normalized URL, tracked status, creation timestamp, and a confirmation message.

Confirm the URL and Brand Kit with the user before creating the page. Verify the result with `list_pages` filtered by URL. This adds the page to AirOps; it does not publish content to a CMS.

***

### `get_page_details`

Get detailed metrics for a specific page.

**Requires:** `id`

**Returns:** URL, folder, primary keyword, citation share, citation rate, unique cited questions count, GSC metrics (clicks, impressions, position, CTR), and all trends.

| Parameter      | Values                 |
| -------------- | ---------------------- |
| **Date range** | start\_date, end\_date |

***

### `get_page_prompts`

Get AI prompts that cite a specific page.

**Requires:** `brand_kit_id`, `web_page_id`

**Returns:** Prompt ID, text, keyword, topic\_id, volume, total\_answers, answers\_with\_citations, citation\_rate, mention\_rate, and trends.

| Parameter      | Values                                     |
| -------------- | ------------------------------------------ |
| **Filters**    | providers, countries, personas, topic\_ids |
| **Includes**   | topic                                      |
| **Date range** | start\_date, end\_date                     |

***

## Agent Analytics

### `list_aeo_agent_analytics`

List daily bot requests to the Brand Kit's tracked pages. [Connect Agent Analytics](/insights/onsite/traffic.md) before querying this data.

**Requires:** `brand_kit_id`

**Returns:** Rows containing `date`, `platform`, `crawl_type`, and `count`. The crawl types are `ai_search`, `ai_training`, `user_browse`, and `other`. Rows with no requests are omitted.

| Parameter      | Values                                                                |
| -------------- | --------------------------------------------------------------------- |
| **Date range** | `start_date`, `end_date`                                              |
| **Filters**    | `platform`, `crawl_type`, or a single `web_page_id` from `list_pages` |
| **Sort**       | `date` (default), `count`, or `-count`                                |
| **Pagination** | `page`, `per_page` (25 by default, 100 maximum)                       |

Read every page before summing counts. The Agent Analytics **Total Crawls** summary counts search and training crawls for tracked AI engines. The **Pages** table's Total Crawls counts every platform and crawl type for that page. Use the [API calculation guide](/developers/api.md#agent-analytics) for the exact engine set, chart recipes, and date-boundary behavior.

## Analytics

### `query_analytics`

Query analytics with flexible metrics, dimensions, and filters. BI-style interface for custom analysis.

**Requires:** `brand_kit_id`, `metrics`

**Returns:** Query results with requested metrics grouped by dimensions, plus metadata.

**Metrics:**

| Metric               | Description                              |
| -------------------- | ---------------------------------------- |
| `mention_rate`       | % of answers mentioning brand (0-100)    |
| `share_of_voice`     | Brand mentions vs competitors (0-100)    |
| `citation_rate`      | % of answers citing brand domain (0-100) |
| `citation_share`     | Brand citations vs all citations (0-100) |
| `citation_count`     | Absolute citation count                  |
| `sentiment_score`    | Average sentiment (0-100)                |
| `average_position`   | Mean rank in answer lists                |
| `answer_count`       | Total answers analyzed                   |
| `first_mention_rate` | % where brand is mentioned first (0-100) |

**Dimensions** (max 3):

| Dimension         | Description                   |
| ----------------- | ----------------------------- |
| `date`            | Group by time period          |
| `provider`        | Group by AI provider          |
| `topic`           | Group by tracked topic        |
| `competitor`      | Group by competitor           |
| `country`         | Group by region/country       |
| `persona`         | Group by customer persona     |
| `domain`          | Group by cited domain         |
| `domain_category` | Group by citation source type |

| Parameter      | Values                                                   |
| -------------- | -------------------------------------------------------- |
| **grain**      | daily, weekly, monthly, total (default: total)           |
| **Date range** | start\_date, end\_date (default: last 7 days)            |
| **Filters**    | providers, topics, countries, personas, brand\_mentioned |
| **Limit**      | max rows (default 100, max 1000)                         |
| **order\_by**  | custom sort (e.g., "citation\_count DESC")               |

***

### `get_sentiment_theme_answers`

Get the answers behind a sentiment theme so you can inspect source answer text and examples for that theme.

**Requires:** `brand_kit_id`, `sentiment_theme_id`

**Optional fields:** `start_date`, `end_date`, `providers`, `countries`, `topic_ids`, `persona_ids`, `page`, `per_page`

***

### `analytics_chart`

{% hint style="info" %}
**Interactive App:** This tool renders a chart in the conversation. Available in **Codex through the AirOps plugin, Claude Web, and Claude Desktop**.
{% endhint %}

Query analytics and display as an interactive chart. Returns data with a UI reference for visualization.

**Requires:** `brand_kit_id`, `metrics`

**Returns:** Chart data with interactive visualization rendered in the conversation.

| Parameter       | Values                                                         |
| --------------- | -------------------------------------------------------------- |
| **chart\_type** | line, bar, pie, area (default: line)                           |
| **metrics**     | Same as query\_analytics                                       |
| **dimensions**  | Same as query\_analytics (max 2 for line charts with grouping) |
| **grain**       | daily, weekly, monthly, total                                  |
| **Date range**  | start\_date, end\_date                                         |
| **Filters**     | providers, topics, countries, personas, brand\_mentioned       |
| **title**       | Optional chart title                                           |

**Constraints:**

* Only metrics from the same scale can be plotted together (percentage, count, or position)
* Area and bar charts support single metrics with single dimensions
* Line charts support up to 2 dimensions but only single metric when using 2

***

## Reports

### `list_reports`

List saved analytics reports.

**Requires:** `brand_kit_id`

**Returns:** Report ID, name, created\_at, updated\_at.

| Parameter    | Values                         |
| ------------ | ------------------------------ |
| **Filters**  | name                           |
| **Sort**     | name, created\_at, updated\_at |
| **Includes** | modules                        |

***

### `get_report`

Get a specific report by ID.

**Requires:** `brand_kit_id`, `id`

**Returns:** Report ID, name, timestamps. With `includes: ['modules']`, returns full module configurations.

***

## Grids

Tools for reading, writing, creating, and executing AirOps Grids programmatically. Use these to populate data, manage columns, trigger workflow runs, and retrieve results.

### `create_grid`

Create a new empty, general-purpose Grid with one empty sheet. Use `add_grid_column` to add columns and `write_grid` to add rows.

**Requires:** `name`

**Optional fields:** `workspace_id`

***

### `create_grid_sheet`

Create a new sheet within an existing Grid.

**Requires:** `grid_id`, `name`

***

### `list_grids`

List grids the authenticated user has access to. Use `includes: ["grid_tables.grid_columns"]` to get the table and column structure needed for other grid tools.

**Returns:** Grid ID, name, workspace ID, and optionally table and column details (ID, title, data type, position).

| Parameter    | Values                         |
| ------------ | ------------------------------ |
| **Filters**  | name, workspace\_id            |
| **Sort**     | name, updated\_at, created\_at |
| **Includes** | grid\_tables.grid\_columns     |

***

### `read_grid`

Read rows from a grid table. Returns rows as objects with column titles as keys.

**Requires:** `grid_id`, `grid_table_id`

**Returns:** Grid metadata, columns (with writable flag), and row data with pagination info.

Playbook columns also include `playbook_id` and `artifacts`, with each Artifact's `name` and `artifact_type`. Use these names when mapping a Playbook column's output into another execution column.

| Parameter             | Type    | Default | Description                                                     |
| --------------------- | ------- | ------- | --------------------------------------------------------------- |
| `filters`             | array   | none    | Filter by column values                                         |
| `filters[].column_id` | integer | none    | Column ID to filter on                                          |
| `filters[].operator`  | string  | none    | CONTAINS, NOT\_CONTAINS, EMPTY, NOT\_EMPTY, =, !=, >=, <=, >, < |
| `filters[].value`     | string  | none    | Filter value (not required for EMPTY/NOT\_EMPTY)                |
| `column_ids`          | array   | all     | Column IDs to include in results                                |
| `limit`               | integer | 50      | Rows per page (1–100)                                           |
| `offset`              | integer | 0       | Row offset for pagination                                       |
| `truncate`            | integer | 0       | Max characters per cell (0 = no truncation)                     |

***

### `read_grid_cell`

Read the full value of a single Grid cell. Use this when `read_grid` truncates a long cell, such as a full article, brief, JSON payload, or HTML field.

**Requires:** `grid_id`, `grid_table_id`, `row_id`, `column_id`

**Returns:** Column title, full value, and value type.

***

### `write_grid`

Create or update rows in a grid table. Maximum 1000 rows per call.

**Requires:** `grid_id`, `grid_table_id`, `mode`, `rows`

| Parameter | Type   | Description                                                                               |
| --------- | ------ | ----------------------------------------------------------------------------------------- |
| `mode`    | string | `create` to add new rows, `update` to modify existing rows                                |
| `rows`    | array  | Row objects with column titles as keys. For `update` mode, include `__id` with the row ID |

**Returns:** `rows_created` (create mode) or `rows_updated` and `cells_updated` (update mode).

{% hint style="info" %}
Values can be strings, numbers, booleans, arrays, or objects. Arrays and objects are stored as JSON. Column titles must exactly match existing grid columns. Use `add_grid_column` to create new columns first.
{% endhint %}

***

### `run_grid_rows`

Trigger execution of one or more grid rows. This runs all workflow (app execution) columns for each specified row, in dependency order. Execution is asynchronous — this tool returns immediately with execution metadata.

**Requires:** `grid_id`, `grid_table_id`, `grid_row_ids`

| Parameter      | Type  | Description                              |
| -------------- | ----- | ---------------------------------------- |
| `grid_row_ids` | array | IDs of the grid rows to execute (max 50) |

**Returns:** Execution metadata, including the row execution IDs to poll with `get_grid_row_execution_status`.

{% hint style="info" %}
Maximum 50 rows per call. Use `get_grid_row_execution_status` to check progress and completion.
{% endhint %}

***

### `get_grid_row_execution_status`

Check the status of grid row executions. Use this after `run_grid_rows` to poll for completion.

**Requires:** `grid_id`, `row_execution_ids`

| Parameter           | Type  | Description                                 |
| ------------------- | ----- | ------------------------------------------- |
| `row_execution_ids` | array | IDs of the row executions to check (max 50) |

**Returns:** Overall status and per-column detail for each execution.

***

### `add_grid_column`

Add a new column to a grid table. Use this before `write_grid` when you need to write to a column that doesn't exist yet.

**Requires:** `grid_id`, `grid_table_id`, `title`, `data_type`

| Parameter   | Type    | Description                                                                                                   |
| ----------- | ------- | ------------------------------------------------------------------------------------------------------------- |
| `title`     | string  | Column title                                                                                                  |
| `data_type` | string  | text, number, datetime, markdown, url, html, image\_from\_url, json, single\_select, playbook, app\_execution |
| `position`  | integer | Optional column position (appended at end if omitted)                                                         |

**Returns:** Created column's ID, title, data type, and position.

For a Playbook column, use `data_type: "playbook"` and provide `playbook_id`. For a Workflow column, use `data_type: "app_execution"` and provide `workflow_id`. Configure `inputs` by Input name. Each mapping requires `type` and `value`.

When mapping from a Playbook column, `value` is the source column ID in the same sheet, and `artifact_name` is the exact Artifact name:

```json
{
  "article": {
    "type": "column",
    "value": 123,
    "artifact_name": "Final Article"
  }
}
```

This example is an `inputs` object. Copy the Artifact name from `read_grid`, or from the `artifacts` metadata returned when `add_grid_column` creates the source Playbook column.

***

### `update_grid_column`

Update a Grid column's title, data type, or Playbook/Workflow Input mappings.

**Requires:** `grid_id`, `grid_table_id`, `grid_column_id`, and at least one of `title`, `data_type`, or `inputs`

**Returns:** Grid and sheet IDs plus the updated column's ID, title, data type, and position. Playbook and Workflow columns also include their configuration details.

Passing `inputs` replaces the entire Input mapping. Include every Input you want to keep. The tool cannot reposition a column or change which Playbook or Workflow it runs.

***

### `delete_grid_column`

Delete a Grid column and its dependent Workflow output or Playbook Artifact columns.

**Requires:** `grid_id`, `grid_table_id`, `grid_column_id`

**Returns:** `grid_id`, `grid_table_id`, and `deleted_column_ids` for all affected columns.

{% hint style="warning" %}
Review dependent columns before deleting. Deletion is blocked while row executions are running for the sheet.
{% endhint %}

***

### Example: Grid Data Workflow

A typical programmatic workflow using Grid tools:

1. **Discover:** Call `list_grids` with includes to find the grid and its column structure
2. **Prepare:** Call `add_grid_column` to create any missing columns
3. **Populate:** Call `write_grid` with mode `create` to add rows
4. **Execute:** Call `run_grid_rows` to trigger the row's workflow columns, then poll `get_grid_row_execution_status` until complete
5. **Retrieve:** Call `read_grid` to pull the results
6. **Update:** Optionally call `write_grid` with mode `update` to write data back

***

## Knowledge Bases

### `list_knowledge_bases`

List all Knowledge Bases you have access to. Knowledge Bases store documents for semantic search.

**Returns:** Knowledge Base ID, name, workspace ID, status, and document count. Only Knowledge Bases with status `ready` can be searched.

| Parameter   | Values                               |
| ----------- | ------------------------------------ |
| **Filters** | workspace\_name, name, workspace\_id |
| **Sort**    | name, created\_at                    |

***

### `knowledge_base_manage`

Create or update a Knowledge Base. Omit `knowledge_base_id` to create a new Knowledge Base; provide it to update an existing one.

**Fields:** `knowledge_base_id`, `name`, `workspace_id`

**Required on create:** `name`, plus `workspace_id` when the user has access to multiple workspaces.

**Returns:** Knowledge Base ID, name, workspace ID, status, document count, and whether it was created.

***

### `search_knowledge_base`

Search a Knowledge Base for relevant content using semantic similarity.

**Requires:** `knowledge_base_id`, `query`

**Parameters:** `top_k` (number of results, 1-20, default 5)

**Returns:** Matching content ranked by relevance.

***

### `knowledge_base_create_direct_upload`

Start the two-step file upload flow for Knowledge Base ingestion. The tool returns a presigned upload URL, required headers, and a `signed_id`.

**Requires:** `knowledge_base_id`, `filename`, `content_type`, `byte_size`, `checksum`

**Returns:** `signed_id`, `upload_url`, and `upload_headers`.

***

### `knowledge_base_add_file`

Register an uploaded file with a Knowledge Base after `knowledge_base_create_direct_upload`. The document is queued for indexing.

**Requires:** `knowledge_base_id`, `signed_id`, `name`, `document_type`

**Optional fields:** `metadata`

**Returns:** Created document IDs and pending status.

***

### `knowledge_base_add_urls`

Bulk-ingest one or more web pages into a Knowledge Base. Each URL becomes a separate document and indexes asynchronously.

**Requires:** `knowledge_base_id`, `urls`

**Optional fields:** `metadata`

**Returns:** Created document IDs and pending status.

***

### `knowledge_base_get_status`

Get Knowledge Base indexing status and per-document statuses. Use this after adding files or URLs.

**Requires:** `knowledge_base_id`

**Optional fields:** `document_ids`, `cursor`, `items`

***

### `knowledge_base_get_document`

Get a Knowledge Base document by ID, including document metadata and extracted content when available.

**Requires:** `knowledge_base_id`, `document_id`

***

### `knowledge_base_update_document_metadata`

Replace a document's user-facing metadata. Metadata is a single-level key/value object and can be used in Knowledge Base search filters.

**Requires:** `knowledge_base_id`, `document_id`, `metadata`

***

### `knowledge_base_delete_document`

Permanently delete a single document from a Knowledge Base.

**Requires:** `knowledge_base_id`, `document_id`

{% hint style="warning" %}
This action cannot be undone. Confirm with the user before deleting a document.
{% endhint %}

***

### `knowledge_base_delete`

Permanently delete a Knowledge Base and all of its documents.

**Requires:** `knowledge_base_id`

{% hint style="warning" %}
This deletes the Knowledge Base, all documents, and underlying vectors. Confirm with the user before calling it.
{% endhint %}

***

## Query Options

All list tools support:

| Option         | Description                                                              |
| -------------- | ------------------------------------------------------------------------ |
| **Filters**    | Narrow by field values (EQUALS, CONTAINS, EQ, NEQ, GT, LT, GEQ, LEQ, IN) |
| **Includes**   | Request related data in one call                                         |
| **Fields**     | Select specific fields to return                                         |
| **Sort**       | Order by supported fields (prefix `-` for descending)                    |
| **Pagination** | Control results with `page` and `per_page` (max 100)                     |

***

## AI Providers

Available provider values for filtering:

* `chat_gpt`
* `gemini`
* `perplexity`
* `google_ai_mode`
* `google_ai_overview`


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.airops.com/developers/tools.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
