Requirements
| Item | Needed |
|---|---|
| ExpressionEngine | 5, 6 or 7 |
| PHP | 7.0 or newer, with cURL |
| API key | At least one of OpenAI, Google Gemini, Perplexity |
| Scheduled runs | CLI access on EE 6 and 7, or any cron that can call a URL |
Your keys, your account
Measurements run through your own provider accounts. Keys are stored in your own database and are sent to nothing but the provider they belong to. This add-on has no server of its own and phones home to nobody.
The cost is therefore yours, and it is small. One run asks each active question to each selected engine once: ten questions across three engines is thirty calls. Within the reuse window a repeated run costs nothing at all.
Install
- Copy the
aishortlistfolder intosystem/user/addons/. - In the control panel go to Developer Tools → Add-Ons and press Install next to AIShortlist.
- Open Settings, enter your brand name and at least one API key.
- Open Questions and write the questions your buyers would ask.
- Press Run measurement now.
The first run takes a while: search-grade models are slow, and the add-on deliberately pauses between calls so the providers’ per-minute token limits are not tripped. Three questions across three engines takes roughly three minutes.
Settings reference
Your brand
Brand name is the name you want to be recommended by. Other spellings takes one variant per line. Engines write names inconsistently, and adding the variants you have seen keeps the score honest. Leave it empty to match on the brand name alone.
Products to track takes one per line as
Name | keyword, keyword. Without the pipe, the name is used as
the keyword. A product counts as mentioned when any of its keywords appears
in the answer.
API keys
A saved key is never displayed back to you. Leave a field empty to keep the key you already have; type a new one to replace it. Leave a key empty entirely and that engine is skipped.
Engines and limits
| Setting | Default | What it does |
|---|---|---|
| Engines to measure | all three | Which engines a run asks. Each is measured separately and never substituted for another. |
| Reuse answers for | 24 hours | Inside this window a question is not asked again, so a repeated run costs nothing. Set 0 to always ask. |
| Delay between calls | 2 seconds | Search models have low per-minute token limits. Too short a delay causes rate limit errors and lost measurements. |
| Model fields | empty | Leave empty to use the default model for each provider. Set one only if you need a specific model. |
Scheduled measurement
ExpressionEngine 6 and 7
These ship a CLI, so a normal cron entry is enough:
0 6 * * 1 cd /path/to/site && php system/ee/eecli.php aishortlist:olc
ExpressionEngine 5, or any host without shell access
Use the URL shown at the bottom of the Settings screen. It carries a token that is generated for your site:
0 6 * * 1 curl -s "https://example.com/?ACT=12&jeton=..."
The token is required. Without it the endpoint returns
403, so nobody who guesses the address can spend your API credit. If the
URL ever leaks, clear the cron_jeton row from the settings
table and reload the Settings screen to get a new one.
Weekly is usually the right frequency. Answer engines do not change their recommendations hour to hour, and a weekly line is easier to read than a daily one.
Template tags
Every figure in the control panel is also available in templates, so the numbers can go onto a client report or a dashboard page.
Score
{exp:aishortlist:score}
We are named in {mentioned} of {measured} AI answers ({visibility}%).
{if best_position}Best position: {best_position}{/if}
{if no_results}No measurement has run yet.{/if}
Last measured {run_date format="%Y-%m-%d"}.
{/exp:aishortlist:score}
Competitors
{exp:aishortlist:competitors limit="10"}
{count}. {name}: named in {mentions} answers
{/exp:aishortlist:competitors}
Results
{exp:aishortlist:results engine="openai"}
{question} → {engine_name}
{if mentioned}named us at position {position}{if:else}not named{/if}
{evidence}
{/exp:aishortlist:results}
engine is optional and accepts openai,
gemini or perplexity. Omit it for every result.
All three tags read the most recent run.
What it stores
Four tables, all prefixed exp_aishortlist_: settings,
questions, the raw answers, and the scores derived from them. Uninstalling
the add-on drops all four.
Raw answers are kept on purpose. Scoring an answer costs nothing, so when you change your brand spellings the whole history can be re-scored without asking a single question again.
Multi-site installs
Every row carries a site ID. On an MSM install each site keeps its own brand, its own questions and its own measurements, and they never mix.
Troubleshooting
A run reports errors for one engine
The message carries the provider’s own response. insufficient_quota
or a billing message means that account is out of credit; the add-on stops
retrying that engine for the rest of the run rather than wasting time.
Repeated 429s mean the delay between calls is too short, so raise it.
The measurement says 0% and you expected better
Check the evidence column before assuming a bug. If the engines genuinely do not name you, that is the finding the tool exists to deliver. If they do name you but spell it differently, add that spelling under Other spellings and run again. Stored answers are re-scored, so it costs nothing.
Nothing happens on the cron URL
A 403 means the token is missing or wrong. A 500 means the run could not start, usually because no brand name is set or no questions exist. The endpoint returns JSON describing the run, so log the response body while you are setting it up.