Most of what is written about AI prompts for SEO is one-line tricks, and one-line tricks produce exactly the output that gets a cannabis site into trouble. Not because the model is bad at writing. It writes well.
The problem is that a one-line prompt asks it to invent, and inventing is the one thing you cannot afford here.
The framing that makes this work is simple and it takes a while to accept: a prompt is not a request, it is a brief.
The same brief you would hand a freelance writer, with the same parts, including the parts you would find tedious to write. The difference in output between a one-line prompt and a proper brief is not incremental.
It is the difference between forty pages that look like every other chain’s forty pages and forty pages nobody else could have written.
This module is four working prompts, the chain they run in, the failures specific to this industry, and an honest account of what the time saving actually is.
It is the fifth of six modules, and it assumes you have module three’s intake in place, because without it none of this works.
It is the operational layer under everything else in dispensary search visibility: the same output, produced at a rate a small team can hold.
What a model is genuinely good at, and what it cannot do
Worth being precise about this before anything else, because most disappointment with AI output traces back to asking for something from the wrong column.
Everything in the left column is a transformation. You supply material, the model reshapes it, and the reshaping is genuinely excellent, better and faster than most people, and tireless in a way no writer is at page thirty.
Everything in the right column needs a fact that is not in the conversation. What your store is actually like. What your state’s rules say this quarter. Whether a particular sentence crosses a line.
And here is the part that catches people: asked for something from the right-hand column, a model does not decline. It produces something plausible, in the same confident register as the true material, with nothing marking it as different.
So the operating principle for everything below is one sentence: never ask it for a fact, only ever ask it to arrange facts you supplied. Every prompt in this module is built to make that structurally difficult to violate.
Why the one-line prompt produces the module three problem
Here is the thing that ought to worry a chain more than it does. The most common way AI is used for location pages recreates, exactly, the failure that module three was written to prevent, and does it in an afternoon instead of a fortnight.
“Write a 600 word location page for our dispensary in {CITY}”, run forty times, is a template. The variable simply moved from the content management system into the prompt.
And the outputs converge harder than a human writer’s would, because every run draws on the same training distribution and lands on the same defaults: the same opening move, the same three-adjective phrase, the same closing invitation to visit.
Two things make this worse than the hand-built template it replaced. The output is fluent, so it reads like it is fine, and nobody scrolls to page eleven to check.
And it is fast, so a chain can produce eighty pages before anyone has read three of them next to each other, which is precisely what sameness across location pages actually looks like from the outside.
The scaled content policy tests three things: volume, sameness, and whether the pages add value of their own. None of those three is “was a human involved”. That question was settled in the March 2024 update and it has not come back.
A prompt is a brief, and a brief has six parts
A usable prompt has six parts: role, inputs, constraints, structure, a forbidden list, and output format. Three of the six never change once written.
Every prompt in this module has the same six sections in the same order. Once you have written them once, three of the six are constant and you only ever edit the other three.
- Role. Who is writing, for whom, at what level. Not decoration. It sets the register, and “a senior local SEO writer for a licensed retailer” produces measurably plainer prose than no role at all.
- Inputs. The actual material, pasted in. Not summarised, not described. This is the section that decides whether the output is yours.
- Constraints. Length, reading level, sentence style, what may be assumed. Be specific: “240 to 320 words” beats “concise” every time.
- Structure. The exact blocks, in order, with what belongs in each one. This is where module three’s page skeleton gets reused verbatim.
- Forbidden. The claim categories, written once and pasted into every prompt. Its own section below.
- Output. The format you intend to paste. Gutenberg blocks, plain markdown, CSV, JSON. Specify it or you will spend your saved time reformatting.
The two people skip are inputs and forbidden. Inputs get skipped because pasting nine hundred words of transcript into a prompt feels like doing the work yourself, which is exactly backwards.
It is the only part that makes the output specific to your business. Forbidden gets skipped because it is boring, and it is the only thing standing between a draft and a liability.
Inputs decide everything
If you take one practical thing from this module, take this. Prompt engineering, for this kind of work, is mostly input engineering. The clever phrasing matters far less than what you paste underneath it.
Give a model twelve words of generic description and it fills the gap the only way it can, from the average of everything it has read, which is why the output sounds like every dispensary page ever written.
Give it nine hundred words of transcript from the intake call and it has something to work with, so it writes about the old hardware shop and the lot behind the building.
Which means the bottleneck has not moved. It is still the intake. A model cannot make the call to the store manager, cannot notice the detail the manager threw away mid-sentence, and cannot tell you that store nine never sent their answers back.
If you skipped module three’s intake, no prompt in this module will save you. It will just produce the template faster and with better grammar.
Practical notes on the input block, all learned by getting them wrong. Paste the transcript raw rather than tidying it first; the disfluencies carry information about what mattered to the person.
Include more than you think the page needs, because it is cheaper to have the model ignore material than to have it invent. And label the input clearly as input, so it is not read as instruction.
A transcript containing “we should really say we’re the best in town” is a fact about what the manager said, not a direction to write it.
The forbidden block
Module four’s six claim categories become a block of text you write once and paste into every prompt you ever run. This is the highest-value fifteen minutes in the whole workflow.
DO NOT, under any circumstances:
- Make health, medical, therapeutic or effects claims of any kind.
- Use potency figures as a reason to buy, or as a headline.
- Mention prices, discounts, promotions or first-time-customer offers.
- Use superlatives: best, strongest, cheapest, finest, number one,
award-winning, premium, top-rated.
- Use language, imagery or product framing that could appeal to
anyone under 21.
- Include customer quotes, testimonials or review excerpts.
- Make claims about legality, delivery range, licensing or compliance.
- State any fact that is not present in the INPUT block above.
If information is missing, omit that sentence entirely.
Do not estimate, infer, or write a placeholder.
Two things about that block are worth explaining rather than just asserting.
First, none of this happens because a model is careless. It reproduces the register of the copy it was trained on, and the corpus of dispensary marketing copy on the open web is saturated with every single one of these.
“Premium” is not a word a model chooses. It is a word that appears in that position in the training data ten million times.
Second, the final instruction is the most useful sentence you will write. Left to itself a model treats a gap as something to fill smoothly, and a smoothly filled gap is indistinguishable from a fact.
Telling it explicitly to omit rather than estimate, and adding “do not write a placeholder” so it does not leave a bracketed stub you then miss, converts the failure from silent to visible.
The location page prompt
The long one, and the one that earns its keep. Everything in module three’s page skeleton is encoded here as structure.
ROLE
You are a senior local SEO writer producing a store page for a
licensed cannabis retailer. You write plainly. You do not stack
adjectives. You never write a sentence that could be true of a
different store.
INPUT
Store: {STORE NAME}
Address, phone, hours: {NAP BLOCK}
Neighbourhoods this store serves: {LIST}
Intake transcript, verbatim:
{PASTE THE FULL TRANSCRIPT HERE}
STRUCTURE
Write these seven blocks, in this order, with an H2 for each of
blocks 3 to 7:
1. H1: the store name and the place, phrased as a person would say it.
2. Opening, 2-3 sentences: where this store is, in walking or driving
words, using the landmark from the transcript.
3. Getting here: parking, transit, the entrance. Concrete detail only.
4. What this store is known for: the products or services the
transcript says move here, and why here specifically.
5. The people: who works here and what they know, from the transcript.
6. Neighbourhoods served: name them. One sentence each, saying
something true about the relationship, not a list.
7. Questions: the six questions from the transcript, each as an H3,
each answered in 40-70 words, answer in the first sentence.
CONSTRAINTS
- 240 to 320 words across blocks 2 to 6, excluding block 7.
- Short sentences. No sentence longer than 28 words.
- No introductory throat-clearing. Start with the fact.
- Do not use the words: nestled, boasts, offering, whether you are,
look no further, your destination, we pride ourselves.
- British or American spelling: {PICK ONE}, consistently.
FORBIDDEN
{PASTE THE FORBIDDEN BLOCK HERE}
OUTPUT
WordPress Gutenberg block markup. Heading levels exactly as above.
No commentary before or after. No explanation of your choices.
Keep your own banned-words list
The banned-words line in constraints is worth keeping and extending as you go. Every model has a set of tics it returns to, they are recognisable across a site, and listing them explicitly is more effective than any amount of instruction about tone. Add to that list every time you catch one in review.
What comes back is roughly eighty percent of a publishable page, in about ninety seconds. The remaining twenty percent is a person reading it beside the transcript and cutting the two sentences that drifted, and there are almost always exactly two.
The keyword map prompt
This one has the best return of the four, because the underlying task is tedious, mechanical and completely unsuited to a person. Sorting six hundred queries against forty URLs is not thinking; it is clerical work with occasional judgement, and the judgement can be flagged rather than automated.
ROLE
You are mapping search queries to pages for a multi-location cannabis
retailer. You are cautious. You flag rather than guess.
INPUT
Stores and the neighbourhoods each one serves:
{PASTE}
Every live URL on the site, with its page title:
{PASTE}
Query export from Search Console (query, impressions, clicks, position):
{PASTE}
RULES
- Every query gets exactly one owner URL. No ties, no "both".
- Brand-plus-place queries belong to that store's page.
- Neighbourhood queries belong to the store that serves them.
- Generic city-wide and "near me" queries belong to a metro hub page,
never to an individual store page.
- Product and service queries belong to one page each, chosen by
which page already ranks best for them.
OUTPUT
Three CSV tables, in this order, nothing else:
1. MAPPED: query, owner_url, query_type, confidence (high/med/low)
2. CONTESTED: query, candidate_url_1, candidate_url_2, why_unclear
3. UNCOVERED: query, impressions, what_page_would_have_to_exist
Do not resolve anything in CONTESTED. List it and stop.
If a query does not fit any rule, put it in CONTESTED, not MAPPED.
The instruction not to resolve contested terms is the important one. A model asked to decide between two store pages will decide, confidently, on no basis.
It does not know which store is busier, which is newer, which is about to relocate or which one the owner cares about.
Asking it to flag rather than resolve turns a hundred silent wrong decisions into a list of twelve real ones.
The third table is the one clients react to. “Queries with impressions and no page that targets them” is a content plan that wrote itself out of data you already had.
The questions prompt
Separate call, separate prompt, and worth doing separately even though the location prompt already produces a question block. Asked on its own, with the right shape constraints, the output is markedly better, and this is the block that determines whether an answer engine can use your page at all.
ROLE
You are writing the questions-and-answers block for one store page.
Your output will be read by people in a hurry and by systems that
quote short passages. Both need the answer in the first sentence.
INPUT
Intake transcript: {PASTE}
The six questions customers actually ask here: {PASTE FROM INTAKE}
Store facts (hours, address, parking, payment, delivery area): {PASTE}
STRUCTURE
For each question:
- H3 phrased exactly as a customer would ask it, in their words,
including the store or place name where it makes the question
specific.
- Answer of 40 to 70 words.
- The direct answer in the FIRST sentence. Context after, never before.
- Every answer must contain at least two checkable facts from INPUT.
CONSTRAINTS
- No preamble: never "Great question", "At our store", "We believe".
- No sentence that would be equally true of a different location.
- If the transcript does not answer a question, drop that question.
Do not answer it generically.
FORBIDDEN
{PASTE THE FORBIDDEN BLOCK HERE}
OUTPUT
Gutenberg blocks: H3 followed by a paragraph, repeated. Nothing else.
“Drop the question rather than answer it generically” is the constraint that makes this work. Five real answers beat nine where four are padding, and padding is exactly what a model produces when it has a question and no material.
Once the block exists, it is worth running it through something that scores the block for liftability rather than trusting that it reads well, because those are different properties and only one of them is what gets you cited.
Titles and descriptions
The shortest output in the chain and the highest risk, for the reasons module four sets out: this is advertising, it is public, and it is where a model’s trained instincts are most dangerous.
ROLE
You are writing title tags and meta descriptions for the location
pages of a licensed cannabis retailer.
INPUT
For each store: name, city, and THREE differentiating facts taken
from the intake (e.g. closing time, parking, street, transit landmark,
delivery area, something the store is known for).
{PASTE, ONE STORE PER LINE}
RULES
- Title: 50-58 characters including spaces. Count them.
- Description: 140-155 characters including spaces. Count them.
- The differentiator must be a fact from INPUT. Never an adjective.
- Never repeat a differentiator across two stores.
- The word "dispensary" appears at most once per title.
FORBIDDEN
{PASTE THE FORBIDDEN BLOCK HERE}
Also: no THC or potency figures, no price, no "%" symbol,
no exclamation marks, no year.
OUTPUT
For EACH store, TEN title options and THREE description options,
as a table: store, option_number, text, character_count.
Do not recommend one. Do not explain.
Ask for ten and pick, rather than asking for one. The first option a model produces is the average of its training data, which is the one you do not want; the value is in the spread. Expect to reject six of the ten, usually because they would be equally true of another store.
Character counts come back wrong often enough that they need checking independently. Models do not count reliably, they estimate. Running the chosen ones through something that shows how the ten options actually render takes a minute and catches truncation that a raw character count misses anyway, since rendering is by pixel width rather than character count.
Five steps, not one prompt
The instinct is to combine all of this into one large prompt that produces a finished page. It is worth understanding why that fails, because the failure is not obvious and the fix is cheap.
In a single long prompt, instructions compete. The forbidden list gets obeyed carefully in the body and forgotten by the time the title is written. The word limit is honoured in block two and abandoned by block six. And when the output is wrong you cannot tell which instruction lost, so you rewrite the whole prompt and hope.
The chain fixes that by giving each step one job and a checkable output. The step people leave out is the second one, and it is the one that pays for the rest: before drafting anything, have the model extract a plain fact list from the transcript: every checkable claim, one per line, nothing else.
A person reads that list in thirty seconds, corrects the two that are wrong, and everything downstream is then built from facts that have already been approved.
Errors get caught at the cheapest possible point rather than in a finished page where they are camouflaged by good prose.
Run the chain per store, not per step across all stores. It is tempting to do all forty drafts and then all forty title sets, but a mistake in the prompt then reaches forty outputs before anybody notices. Do store one end to end, look hard at it, fix the prompt, and only then batch.
Where models fail on cannabis specifically
Six failure modes, all of which I have watched reach a draft, none of which announce themselves.
- Confidently wrong regulation. Ask about a state’s advertising rules and you will get an answer with the shape and tone of a correct one. Cannabis rules change often, vary by state, and are exactly the kind of material training data represents unevenly. Never take a compliance answer from a model. That is what module four’s rule of looking it up per state, with a date, is for.
- Effects language leaking in. “Relaxing”, “uplifting”, “great for evenings”. The model is not making a medical claim on purpose; it is reproducing how strains are described in nearly all the text it has seen. The forbidden block catches most of it and not all, and the survivors are usually in the most fluent sentence on the page.
- Invented local detail. The most dangerous one, because it is indistinguishable from good writing. A park that is not there, a road that does not intersect, a neighbourhood name that belongs to a different city. It happens when the brief left a gap, and it is the direct reason for the “omit rather than estimate” instruction.
- Convergence, fabricated formats and drift round out the list. Forty drafts developing one voice; a plausible-looking licence number in a plausible-looking format; and a brief followed carefully for six paragraphs and then quietly abandoned in the seventh, which is why the questions block belongs in its own call rather than at the end of a long one.
The review layer that has to be human
Three layers, in a fixed order, each doing what the others cannot. Skipping any of them does not save time; it moves the cost somewhere less convenient.
The model can draft and it can restructure, and it cannot check its own work. Asking it to review what it just wrote produces agreement, because the same process that generated the sentence evaluates it. Asking a fresh session, with the transcript and no memory of writing the draft, works considerably better and is still not a review.
The second layer is deterministic and it is where the free tools belong. Same input, same answer, every time, which is the property a model does not have and the one you want for anything you are going to enforce.
Two checks in particular carry this layer: a deterministic pass for banned phrasing, which catches what leaked through the forbidden block, and something to score every draft against every page already live, which is the only way to catch convergence across a batch. Neither can tell you the page is dull or that a fact is wrong.
Which leaves the third layer, and it is irreducible. One person, with the transcript open beside the draft, reading every factual claim and confirming it came from the call. Noticing the sentence that was quietly invented.
And then deciding it is good enough to carry the brand, which is a judgement, and an accountability, that does not belong to a tool. Run in this order it takes about four minutes a page. Skip either of the first two layers and it takes twenty, or it stops happening.
What this actually saves
Worth being straight about, because the numbers people quote for this are not real and quoting them to a client sets up a disappointment you then have to manage.
Where the hours actually move
Three stages fall sharply: research, first draft, and title generation. Two are unchanged, because a person still has to make the intake call and the deterministic checks still take what they take. And two get longer.
Rewriting the draft is work that did not exist when a human wrote it in the first place, and fact-checking takes more time precisely because you trust the source less.
Roughly a hundred and forty minutes a page becomes roughly sixty five. A bit over half. On a forty store rollout that is around fifty hours, which is a genuinely large saving and is worth having, and it is a different claim from the ninety percent that gets advertised, which is only achievable by not doing the checks.
The return the table does not show
The saving also shows up somewhere the table does not capture. The tenth page is as good as the first, which is not true of a human writer working through forty location pages in a fortnight. Consistency at volume is probably the real return here, and it is the one nobody puts in the pitch.
The summary: a model is a fast, tireless, slightly overconfident junior writer who has never been to your store and never will.
Brief it properly, give it real material, tell it what it may not say, check everything it produces, and it is worth having.
Skip any of those four and it produces the exact problem the previous two modules were written to prevent, faster than you can read it.
If you would rather have this running as a system than assemble it yourself, how the phases actually run on an engagement sets out the sequence, that is what the strategy and production work we do covers, and the free audit is a reasonable way to see what state the existing pages are in first.
The last module is the technical one: why the menu that is the whole point of the site is frequently invisible to Google.
Check your own site
Run the free check to see how your menu, age gate, and location pages appear to a search engine.
