# AI Search Prompt Generator: GEO & AEO Prompt Sets (`emoubarak/ai-search-prompt-generator`) Actor

Generate the prompt set to track a brand on in ChatGPT, Perplexity, Gemini and Google AI Overviews — stratified across commercial, informational, transactional, brand-defensive and comparison intents. No API key required.

- **URL**: https://apify.com/emoubarak/ai-search-prompt-generator.md
- **Developed by:** [El Mahdi Moubarak](https://apify.com/emoubarak) (community)
- **Categories:** SEO tools, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 prompt generateds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## AI Search Prompt Generator: GEO & AEO Prompt Sets for Brand Tracking

**No API key required.** Generate the prompt set your brand should actually be tracked on in ChatGPT, Perplexity, Gemini and Google AI Overviews — the questions real buyers type, stratified across the five intents that decide whether a visibility measurement is representative or just a narrow slice of one surface.

This is the step before measurement. Every AI visibility tool asks you for prompts. Almost nobody tells you which prompts to use, and a bad prompt set produces a confident number about nothing.

For **generative engine optimization (GEO)**, **answer engine optimization (AEO)** and **LLM SEO** work: AI search prompt research, GEO prompt ideas, AEO query sets, brand tracking prompts and competitor comparison queries.

***

### Why the prompt set decides the measurement

A prompt set made only of "best X tools" queries measures one commercial surface, and it is the surface where every competitor is already looking. The questions that decide a purchase are spread across the funnel, and three of them will never appear in a "best X" list:

- Someone researching the category before they know any vendor names.
- Someone checking whether you are legitimate after a colleague named you.
- Someone comparing you head to head with one named rival.

Measure only the first kind and you get a number that is real but answers a question nobody asked.

#### The five intents

| Intent              | What it captures                                                  | Names your brand? |
| ------------------- | ----------------------------------------------------------------- | ----------------- |
| **Commercial**      | "best X for Y", "top X in <market>" — unprompted discovery        | No                |
| **Informational**   | how / what / why questions about the category                     | No                |
| **Transactional**   | pricing, plans, trials, "how much does X cost"                    | No                |
| **Brand-defensive** | reviews, legitimacy, pros and cons, "alternatives to X"           | Yes               |
| **Comparison**      | "X vs Y: which is better" against a named competitor              | Yes               |

The split matters for interpretation, not just coverage. Commercial, informational and transactional prompts deliberately **do not** name your brand: if they did, the measurement would be circular — you would be asking the engine about a brand you just handed it, then congratulating yourself when it comes up. Those three measure **unprompted discovery**. Brand-defensive and comparison prompts name your brand on purpose, and measure **reputation** instead. They are different questions, and a prompt set that blends them without saying so produces a mention rate that means neither.

***

### Quick start

The only required field is `brand`.

```json
{
    "brand": "Notion"
}
```

A fuller set, which is what you want before a first audit:

```json
{
    "brand": "Notion",
    "industry": "team workspace and note-taking software",
    "competitors": ["Coda", "Airtable", "ClickUp"],
    "market": "US",
    "language": "en",
    "maxPrompts": 20
}
```

Runs in well under a minute. The output is one dataset row per prompt, ready to paste straight into a tracker.

***

### What you get

One row per prompt:

| Field         | What it is                                                              |
| ------------- | ----------------------------------------------------------------------- |
| `index`       | Position in the set                                                      |
| `prompt`      | The question itself, in your chosen language                             |
| `intent`      | `commercial`, `informational`, `transactional`, `brand_defensive`, `comparison` |
| `brand`       | The brand the set was built for                                          |
| `competitors` | Competitors supplied, used by the comparison prompts                     |
| `industry`    | Category, as supplied or inferred                                        |
| `market`      | Two-letter country code                                                  |
| `language`    | Language the prompts are written in                                      |
| `origin`      | `generated` by the model, or `fallback` if generation was unavailable    |
| `generatedAt` | ISO timestamp                                                            |

A `SUMMARY` record in the key-value store carries the totals, the per-intent breakdown and any warnings.

#### Example output

```json
[
    {
        "index": 0,
        "prompt": "What are the best team workspace and note-taking tools for a remote US team?",
        "intent": "commercial",
        "brand": "Notion",
        "market": "US",
        "language": "en",
        "origin": "generated"
    },
    {
        "index": 3,
        "prompt": "What are the best alternatives to Notion?",
        "intent": "brand_defensive",
        "brand": "Notion",
        "market": "US",
        "language": "en",
        "origin": "generated"
    }
]
```

***

### Input reference

| Field              | Type            | Default               | Description                                                                    |
| ------------------ | --------------- | --------------------- | ------------------------------------------------------------------------------ |
| `brand`            | string          | —                     | **Required.** The brand the set is built around.                               |
| `industry`         | string          | `""`                  | Category buyers search in. Empty lets the model infer it.                      |
| `competitors`      | string\[]        | `[]`                  | Named competitors, used by the comparison prompts.                             |
| `language`         | string          | `"en"`                | Language the prompts are written in.                                           |
| `market`           | string          | `"US"`                | Two-letter country code, used where a question carries a location.             |
| `maxPrompts`       | integer         | `20`                  | How many prompts to generate (1–100), spread evenly across the chosen intents. |
| `intents`          | string\[]        | all five              | Which intents to cover.                                                        |
| `openRouterApiKey` | string (secret) | `""`                  | **Optional.** Generation runs on an included key by default.                   |
| `model`            | string          | `openai/gpt-5.6-luna` | Any OpenRouter model ID when you supply your own key.                          |

***

### Then measure them

A prompt set is an input, not an answer. To find out how AI answer engines actually respond to these prompts — mention rate, position, sentiment, share of voice against your competitors, and what moved since last week — feed them to the tracker:

**[AI Search Visibility Tracker: ChatGPT, Perplexity & Gemini](https://apify.com/emoubarak/ai-search-visibility-tracker)**

Paste this Actor's `prompt` column into its `queries` field and it skips its own generation step and uses yours verbatim. It asks each prompt **several times per engine**, because AI answers are non-deterministic — on a real 40-answer run, one prompt came back 4/5, 4/5, 1/5 and 0/5 across four engines, a true mention rate of 45% that no single-sample audit can even represent.

***

### Pricing

Pay per event, no subscription:

| Plan               | Per prompt | A 20-prompt set |
| ------------------ | ---------- | --------------- |
| Free               | $0.005     | **$0.10**       |
| Bronze (Starter)   | $0.004     | $0.08           |
| Silver (Scale)     | $0.0035    | $0.07           |
| Gold (Business)    | $0.003     | $0.06           |

Charged only for prompts actually written to the dataset — a run that returns nothing is not charged. Plus Apify's standard start event at $0.00005.

For comparison, the closest comparable Actors on Apify Store charge $0.03 and $0.05 per prompt, which is $0.60 and $1.00 for the same 20-prompt set.

***

### Run it unattended

Pay-per-event pricing and limited permissions make this callable from an agent with nothing to configure. Connect it to any MCP client:

```
https://mcp.apify.com?tools=emoubarak/ai-search-prompt-generator
```

Then ask your agent: *"Build me a GEO prompt set for \[brand] in \[market], then track it."*

***

### FAQ

#### What is a GEO prompt set?

The list of questions you measure a brand's AI search visibility against. Generative engine optimization is measured by asking answer engines real buyer questions and recording whether your brand appears; the prompt set is what you ask. Its coverage decides what your numbers can and cannot tell you.

#### How many prompts do I need?

Ten is enough to see whether a brand appears at all. Twenty across five intents is a solid first audit. Past forty you are usually adding near-duplicates that inflate cost without widening coverage — the generator de-duplicates, but it cannot invent distinct buyer intent that does not exist in a narrow category.

#### Why don't the commercial prompts mention my brand?

Because naming your brand in the question guarantees it appears in the answer. That measures nothing. Unprompted discovery — does the engine bring you up on its own — is the metric worth tracking, and it requires questions that do not hand the engine the answer.

#### Can I use these prompts with another tool?

Yes. The output is plain text with an intent label; nothing about it is specific to any tracker. Export as CSV or JSON from the dataset.

#### Does it work in languages other than English?

Yes. Set `language` and the prompts are written in that language. Write them in the language your customers actually search in, not your reporting language — an English prompt set measures English-language AI answers regardless of the `market` you set.

#### What happens if the model is unavailable?

The run still succeeds and returns a built-in stratified set derived from your brand, category and competitors, with a warning and `origin: "fallback"` on every row. A generic set is still usable; an aborted run is not.

#### Is this the same as keyword research?

No, and the difference matters. Keyword research finds strings people type into a search box, ranked by volume. This produces questions people ask an assistant in natural language — longer, more conversational, and frequently with no search volume at all attached to them, because they were never typed into Google in that form.

***

### License

MIT.

# Actor input Schema

## `brand` (type: `string`):

The brand the prompt set is built around. Write it exactly as it appears in the market, e.g. "Notion", not "notion.so".

## `industry` (type: `string`):

The category buyers would search in, e.g. "project management software". Leave empty to let the model infer it from the brand name.

## `competitors` (type: `array`):

Named competitors. Used for the head-to-head comparison prompts, which are the queries AI answers most often decide a purchase on.

## `language` (type: `string`):

Language the prompts are written in, e.g. "en", "fr", "de". Write them in the language your customers actually use.

## `market` (type: `string`):

Two-letter country code, e.g. "US", "FR". Used where a question would naturally carry a location.

## `maxPrompts` (type: `integer`):

How many prompts to generate, spread evenly across the selected intents. 20 is a solid starting set for a first audit.

## `intents` (type: `array`):

Which buyer intents the set should span. Keeping all five is what stops a prompt set from measuring one narrow surface. Note that brand-defensive and comparison prompts name your brand on purpose, so they measure reputation rather than unprompted discovery.

## `openRouterApiKey` (type: `string`):

Optional. Generation runs on an included key by default, so you do not need an OpenRouter account. Supply your own to pick any model.

## `model` (type: `string`):

Any OpenRouter model ID when you supply your own key. Ignored on the included key, which uses the default.

## Actor input object example

```json
{
  "brand": "Notion",
  "industry": "team workspace and note-taking software",
  "competitors": [
    "Coda",
    "Airtable",
    "ClickUp"
  ],
  "language": "en",
  "market": "US",
  "maxPrompts": 10,
  "intents": [
    "commercial",
    "informational",
    "transactional",
    "brand_defensive",
    "comparison"
  ],
  "model": "openai/gpt-5.6-luna"
}
```

# Actor output Schema

## `prompts` (type: `string`):

Every generated prompt with its buyer intent, ready to paste into the queries field of a visibility tracker.

## `summary` (type: `string`):

Total prompts returned, the per-intent breakdown, whether the set was model-generated or came from the built-in fallback, and any warnings.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "brand": "Notion",
    "industry": "team workspace and note-taking software",
    "competitors": [
        "Coda",
        "Airtable",
        "ClickUp"
    ],
    "language": "en",
    "market": "US",
    "maxPrompts": 10,
    "intents": [
        "commercial",
        "informational",
        "transactional",
        "brand_defensive",
        "comparison"
    ],
    "model": "openai/gpt-5.6-luna"
};

// Run the Actor and wait for it to finish
const run = await client.actor("emoubarak/ai-search-prompt-generator").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "brand": "Notion",
    "industry": "team workspace and note-taking software",
    "competitors": [
        "Coda",
        "Airtable",
        "ClickUp",
    ],
    "language": "en",
    "market": "US",
    "maxPrompts": 10,
    "intents": [
        "commercial",
        "informational",
        "transactional",
        "brand_defensive",
        "comparison",
    ],
    "model": "openai/gpt-5.6-luna",
}

# Run the Actor and wait for it to finish
run = client.actor("emoubarak/ai-search-prompt-generator").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "brand": "Notion",
  "industry": "team workspace and note-taking software",
  "competitors": [
    "Coda",
    "Airtable",
    "ClickUp"
  ],
  "language": "en",
  "market": "US",
  "maxPrompts": 10,
  "intents": [
    "commercial",
    "informational",
    "transactional",
    "brand_defensive",
    "comparison"
  ],
  "model": "openai/gpt-5.6-luna"
}' |
apify call emoubarak/ai-search-prompt-generator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,emoubarak/ai-search-prompt-generator"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/bvRLKoWVJmeYLocSA/builds/EMxEJxkNQPpONhdoa/openapi.json
