AEO Brand Visibility for Magento 2 — module reference
AEO Brand Visibility asks AI assistants the questions your shoppers ask — “where can I buy X?”, “what are the best stores for Y?” — and reads the answers. It then scores how visible your brand is.
It supports ChatGPT, Claude, Perplexity, Gemini and Groq. Every question is asked several times, because AI answers change from one call to the next. So the score comes with a margin of error, not a single lucky number.
The module plugs into AEO Audit as a live signal. It also runs on its own from the admin panel, from cron or from the command line.
What it measures
Each answer is scored on five signals:
| Signal | Question | Default weight |
|---|---|---|
| Mentioned | Does the answer name the brand? | 1.0 |
| Recommended | Is the brand suggested, not only listed? | 1.5 |
| URL cited | Is your domain quoted? | 1.5 |
| First position | Is the brand named before competitors? | 2.0 |
| Positive tone | Is the wording around the brand positive? | 0.5 |
Negative tone has no weight. It takes points away instead, because “avoid this shop” is worse than no mention.
On top of that, the report shows:
- Share of voice — your weight against every tracked competitor in the same answers.
- Win rate — how often you are named before every competitor.
- Accuracy issues — answers that link your brand to a website you do not own.
Reading the score honestly
Two settings decide if the number is useful.
Grounding. A model that answers from memory repeats training data that is months old. Nothing you change this quarter moves it. A grounded model searches the live web first, so it reacts to your work within days. Perplexity is always grounded. ChatGPT, Claude and Gemini can be grounded per provider. Groq cannot.
Sampling. Each provider and prompt pair is asked N times (3 by default). The result is a mean with a 95 % confidence margin, shown as ±. A change smaller than the margin is noise. Alerts ignore it.
Requirements
| Magento | 2.4.x (Open Source, Mage-OS or Adobe Commerce) — magento/framework ^103.0 |
|---|---|
| PHP | 8.1 – 8.5 — ~8.1.0||~8.2.0||~8.3.0||~8.4.0||~8.5.0 |
| Other angeo modules | angeo/module-aeo-audit ^3.0||^4.0 |
You also need at least one AI provider API key, and a running message queue consumer (or the Inline run mode).
Installation
composer require angeo/module-aeo-brand-visibility
bin/magento module:enable Angeo_AeoBrandVisibility
bin/magento setup:upgrade
bin/magento setup:di:compile # production mode only
bin/magento setup:static-content:deploy # production mode only
bin/magento cache:flush
Start the consumer that runs queued audits:
bin/magento queue:consumers:start angeoBrandVisAuditRun
On most stores consumers_runner in app/etc/env.php starts it from cron. If your hosting does not run consumers, set Run Mode to Inline. A full run then happens inside the admin request and can hit a PHP or gateway timeout.
Setting it up
- Open Stores → Configuration → Angeo AEO → Brand Visibility (AI Models).
- In General, enable the module and fill in Store Category — what you sell, in two or three words. This one field moves the score more than any other. Without it, prompts fall back to generic phrases that big marketplaces always win.
- Enable one or more providers and paste their API keys. Keys are stored encrypted.
- For a score that reacts to your work, turn on Answer from live web search for at least one provider, or enable Perplexity.
- Add competitors under Competitors → Tracked Competitors, one per line.
- Start a run from Marketing → AEO Brand Visibility → Dashboard.
Almost every setting works per website and per store view, so a multi-brand store can measure each brand on its own.
Providers
| Provider | Grounded answers | Note |
|---|---|---|
| ChatGPT | Optional | Needs a search-capable model, such as gpt-4o-search-preview |
| Claude | Optional | Uses the server-side web search tool, billed per search |
| Perplexity | Always | The fastest-reacting signal of the five |
| Gemini | Optional | Uses Google Search as a tool |
| Groq | No | Free tier, a memory-only baseline |
Model names change often. Pick the closest option and check the field again after a provider release.
Prompts
There are six built-in prompts, each with an on/off switch and optional override text: best stores in category, where to buy, tell me about this brand, product search, compare with competitors, and gift guide. Add your own under Custom Prompts, one per line, as key: prompt text.
You can use these placeholders: {{brand}}, {{domain}}, {{category}}, {{products}}.
Languages
Phrase matching supports English, Ukrainian, Dutch, German, French and Spanish. English is always matched as well, because AI answers often mix languages.
For the accuracy check, add your country domains under Extra Top-Level Domains (for example nl, de, co.uk). Otherwise a wrong country domain linked to your brand is not flagged.
Alerts
An alert fires when the score drops by more than the set number of points against the recent average and the drop is bigger than the margin of error. It also fires when a competitor outranks you, or when negative tone or a wrong URL shows up. Alerts go by email, by webhook, or both. The webhook must use HTTPS. Private and reserved addresses are refused unless you allow them.
Command line
# Full audit for the default scope
bin/magento angeo:aeo:brand-visibility
# One store view, skip the cache, print the action plan
bin/magento angeo:aeo:brand-visibility --store=2 --refresh --plan
# Machine-readable output
bin/magento angeo:aeo:brand-visibility --format=json
# One provider and one prompt, with the raw answer
bin/magento angeo:aeo:brand-visibility --provider=perplexity --prompt=brand_direct
# Fail a CI pipeline below a score
bin/magento angeo:aeo:brand-visibility --fail-on=50
| Option | Meaning |
|---|---|
--store | Store view id (default 0) |
--refresh, -r | Skip the result cache |
--provider | Ask one provider instead of the full audit |
--prompt | Prompt key to use with --provider |
--format | table, json or markdown |
--plan | Print the action plan |
--fail-on | Exit code 1 below this score |
Admin panel and permissions
Marketing → AEO Brand Visibility has a Dashboard (start a run, read each answer, build an action plan) and Audit History (a grid with filters, a detail page and CSV export per run).
Access is split into four permissions. You can give an agency read access without the right to spend money on API calls.
| ACL resource | Title in admin |
|---|---|
Angeo_AeoBrandVisibility::root | AEO Brand Visibility |
Angeo_AeoBrandVisibility::view | View Reports |
Angeo_AeoBrandVisibility::run | Run Audit |
Angeo_AeoBrandVisibility::export | Export Results |
Angeo_AeoBrandVisibility::config | Configuration |
Cost
One run costs providers × prompts × samples API calls. Three providers, three prompts and three samples make 27 calls. Weekly runs on small models cost cents. Grounded searches on large models cost more. Start with three samples and one grounded provider.
Configuration reference
All settings are under Stores → Configuration → Angeo AEO → Brand Visibility (AI Models). The table shows each field, its config path (for bin/magento config:set) and its default value.
General (9)
| Setting | Config path | Default |
|---|---|---|
| Enable Brand Visibility | angeo_brand_vis/general/enabled | No |
| Run Mode | angeo_brand_vis/general/run_mode | queue |
| Brand Name | angeo_brand_vis/general/brand_name | — |
| Brand Domain | angeo_brand_vis/general/brand_domain | — |
| Brand Aliases | angeo_brand_vis/general/brand_keywords | — |
| Store Category | angeo_brand_vis/general/store_category | — |
| Top Products | angeo_brand_vis/general/top_products | — |
| Cache Lifetime (hours) | angeo_brand_vis/general/cache_ttl_hours | 24 |
| Log Prompts and Answers | angeo_brand_vis/general/log_enabled | No |
ChatGPT (OpenAI) (7)
| Setting | Config path | Default |
|---|---|---|
| Enable | angeo_brand_vis/chatgpt/enabled | No |
| API Key | angeo_brand_vis/chatgpt/api_key | — (stored encrypted) |
| Model | angeo_brand_vis/chatgpt/model | gpt-4.1-mini |
| Answer from live web search | angeo_brand_vis/chatgpt/grounding | No |
| Max Answer Tokens | angeo_brand_vis/chatgpt/max_tokens | 800 |
| Temperature | angeo_brand_vis/chatgpt/temperature | 0.3 |
| Timeout (seconds) | angeo_brand_vis/chatgpt/timeout | 60 |
Claude (Anthropic) (7)
| Setting | Config path | Default |
|---|---|---|
| Enable | angeo_brand_vis/claude/enabled | No |
| API Key | angeo_brand_vis/claude/api_key | — (stored encrypted) |
| Model | angeo_brand_vis/claude/model | claude-sonnet-4-6 |
| Answer from live web search | angeo_brand_vis/claude/grounding | No |
| Max Answer Tokens | angeo_brand_vis/claude/max_tokens | 800 |
| Temperature | angeo_brand_vis/claude/temperature | 0.3 |
| Timeout (seconds) | angeo_brand_vis/claude/timeout | 90 |
Perplexity (6)
| Setting | Config path | Default |
|---|---|---|
| Enable | angeo_brand_vis/perplexity/enabled | No |
| API Key | angeo_brand_vis/perplexity/api_key | — (stored encrypted) |
| Model | angeo_brand_vis/perplexity/model | sonar |
| Max Answer Tokens | angeo_brand_vis/perplexity/max_tokens | 800 |
| Temperature | angeo_brand_vis/perplexity/temperature | 0.2 |
| Timeout (seconds) | angeo_brand_vis/perplexity/timeout | 60 |
Gemini (Google) (7)
| Setting | Config path | Default |
|---|---|---|
| Enable | angeo_brand_vis/gemini/enabled | No |
| API Key | angeo_brand_vis/gemini/api_key | — (stored encrypted) |
| Model | angeo_brand_vis/gemini/model | gemini-2.0-flash |
| Answer from live web search | angeo_brand_vis/gemini/grounding | No |
| Max Answer Tokens | angeo_brand_vis/gemini/max_tokens | 800 |
| Temperature | angeo_brand_vis/gemini/temperature | 0.3 |
| Timeout (seconds) | angeo_brand_vis/gemini/timeout | 60 |
Groq (6)
| Setting | Config path | Default |
|---|---|---|
| Enable | angeo_brand_vis/groq/enabled | No |
| API Key | angeo_brand_vis/groq/api_key | — (stored encrypted) |
| Model | angeo_brand_vis/groq/model | llama-3.3-70b-versatile |
| Max Answer Tokens | angeo_brand_vis/groq/max_tokens | 800 |
| Temperature | angeo_brand_vis/groq/temperature | 0.3 |
| Timeout (seconds) | angeo_brand_vis/groq/timeout | 30 |
Queries (18)
| Setting | Config path | Default |
|---|---|---|
| Samples per Query | angeo_brand_vis/queries/samples | 3 |
| Maximum Prompts per Provider | angeo_brand_vis/queries/max_prompts | 3 |
| Delay Between Calls (ms) | angeo_brand_vis/queries/delay_between_ms | 600 |
| Retries per Call | angeo_brand_vis/queries/max_retries | 2 |
| System Prompt | angeo_brand_vis/queries/system_prompt | — |
| Prompt: Best stores in category | angeo_brand_vis/queries/enable_recommendation | Yes |
| Override text | angeo_brand_vis/queries/prompt_recommendation | — |
| Prompt: Where to buy | angeo_brand_vis/queries/enable_category | Yes |
| Override text | angeo_brand_vis/queries/prompt_category | — |
| Prompt: Tell me about this brand | angeo_brand_vis/queries/enable_brand_direct | Yes |
| Override text | angeo_brand_vis/queries/prompt_brand_direct | — |
| Prompt: Product search | angeo_brand_vis/queries/enable_product_search | No |
| Override text | angeo_brand_vis/queries/prompt_product_search | — |
| Prompt: Compare with competitors | angeo_brand_vis/queries/enable_comparison | No |
| Override text | angeo_brand_vis/queries/prompt_comparison | — |
| Prompt: Gift guide | angeo_brand_vis/queries/enable_gift_guide | No |
| Override text | angeo_brand_vis/queries/prompt_gift_guide | — |
| Custom Prompts | angeo_brand_vis/queries/custom_prompts | — |
Competitors (1)
| Setting | Config path | Default |
|---|---|---|
| Tracked Competitors | angeo_brand_vis/competitors/list | — |
Analysis (2)
| Setting | Config path | Default |
|---|---|---|
| Analysis Language | angeo_brand_vis/analysis/language | auto |
| Extra Top-Level Domains | angeo_brand_vis/analysis/extra_tlds | — |
Scoring (8)
| Setting | Config path | Default |
|---|---|---|
| Weight: Mentioned | angeo_brand_vis/scoring/weight_mentioned | 1.0 |
| Weight: Recommended | angeo_brand_vis/scoring/weight_recommended | 1.5 |
| Weight: URL Cited | angeo_brand_vis/scoring/weight_url_cited | 1.5 |
| Weight: First Position | angeo_brand_vis/scoring/weight_first_result | 2.0 |
| Weight: Positive Tone | angeo_brand_vis/scoring/weight_positive_sentiment | 0.5 |
| Negative Tone Penalty | angeo_brand_vis/scoring/negative_penalty | 0.5 |
| Pass Threshold | angeo_brand_vis/scoring/pass_threshold | 60 |
| Warning Threshold | angeo_brand_vis/scoring/warn_threshold | 30 |
Alerts (5)
| Setting | Config path | Default |
|---|---|---|
| Enable Regression Alerts | angeo_brand_vis/alerts/enabled | No |
| Alert Recipient | angeo_brand_vis/alerts/recipient | — |
| Drop Threshold (points) | angeo_brand_vis/alerts/drop_threshold | 10 |
| Webhook URL | angeo_brand_vis/alerts/webhook_url | — |
| Allow Private Webhook Targets | angeo_brand_vis/alerts/webhook_allow_private | No |
Scheduled Runs (2)
| Setting | Config path | Default |
|---|---|---|
| Enable Schedule | angeo_brand_vis/cron/enabled | No |
| Cron Expression | angeo_brand_vis/cron/schedule | 0 5 * * 1 |
Data Retention (2)
| Setting | Config path | Default |
|---|---|---|
| Runs Kept per Store View | angeo_brand_vis/retention/max_records_per_store | 90 |
| Maximum Age (days) | angeo_brand_vis/retention/max_age_days | 365 |
Cron and stored data
Scheduled runs use their own cron group, angeo_brand_visibility, so slow provider calls never delay Magento’s default group. A second job removes old runs every night.
| Job | Cron group | Schedule |
|---|---|---|
angeo_brand_visibility_audit | angeo_brand_visibility | 0 5 * * 1 by default, set in angeo_brand_vis/cron/schedule |
angeo_brand_visibility_cleanup | angeo_brand_visibility | 30 3 * * * |
| Table | What it holds | Columns |
|---|---|---|
angeo_brand_visibility_audit | Angeo Brand Visibility Audit Results | id, run_uuid, status, error_message, brand_name, brand_domain, store_id, overall_score, score_margin, grade, samples, share_of_voice, win_rate, accuracy_issues, provider_scores, signal_rates, results_json, triggered_by, queries_count, errors_count, from_cache, created_at |
Adding a provider
Implement AiProviderInterface and add one line to the ProviderPool argument in etc/di.xml. No existing class needs a change.
FAQ
Why does my score not change after I improve the store?
The providers probably answer from memory. Turn on live web search for ChatGPT, Claude or Gemini, or enable Perplexity. Grounded answers react within days.
Why is every question asked three times?
AI answers are not stable. The same question gives different answers. Asking several times gives a mean and a margin of error, so you can tell a real change from noise.
How much does a run cost?
The number of calls is providers × prompts × samples. With the defaults that is a few dozen calls. Small models cost cents per run. Grounded searches on large models cost more.
Does it need AEO Audit?
Yes. It requires angeo/module-aeo-audit 3.x or 4.x and reports into it as a live signal. You can still run it on its own.
Can an agency see reports without running paid audits?
Yes. Give the agency role only the View Reports permission. Running audits needs the separate Run Audit permission.
Related
- AEO Audit — score 20 AI-visibility signals from the command line
- llms.txt — generate llms.txt, llms.jsonl, Markdown mirrors and agents.md
- Rich Data — one linked JSON-LD graph per page, with offers and policies
- Robots.txt AEO — manage AI crawler rules in robots.txt and verify real bots
- All module reference pages · Compatibility matrix
This page was written from the README.md, composer.json and etc/*.xml files of tag 4.0.1, read on 16 October 2026. Settings, commands and defaults come straight from that code. If a newer release is out, the README on GitHub wins.