Automating SEO Meta Descriptions at Scale: A Script + GPT-4o Pipeline
The math: 500 pages × 3 minutes per meta description = 25 hours of mind-numbing work. Or: one Python script + GPT-4o = 500 descriptions in 20 minutes, with human review on the worst 10%.
I built this for a site migration where every URL changed and every meta description needed rewriting. Here's the exact pipeline.
What You'll Need
- 15 minutes to review edge cases
Step 1: Extract Page Context
Meta descriptions fail when they're generic. The fix is feeding GPT-4o real page context, not just a title.
Scrape or export for each URL:
- Top 3 keywords the page targets
Store this in pages.csv.
Step 2: The Meta Description Prompt
This is the entire quality control mechanism. A bad prompt = 500 bad descriptions.
``
You are an SEO copywriter. Write a meta description for this page.
URL: {url}
Page Title: {title}
H1: {h1}
Content excerpt: {excerpt}
Target keywords: {keywords}
Requirements:
- One sentence only, no periods at the end unless grammatically necessary
Return ONLY the meta description. No quotes, no explanation.
`
The {intent_type} variable is crucial. Informational queries get "Learn how..." Commercial get "See how..." Navigational get "Find..."
Step 3: The Python Script
`python
import pandas as pd
import openai
from concurrent.futures import ThreadPoolExecutor
openai.api_key = "YOUR_KEY"
def generate_meta(row):
prompt = f"""
You are an SEO copywriter...
URL: {row['url']}
Page Title: {row['title']}
H1: {row['h1']}
Content excerpt: {row['excerpt']}
Target keywords: {row['keywords']}
Intent: {row['intent']}
"""
response = openai.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
temperature=0.3,
max_tokens=80
)
desc = response.choices[0].message.content.strip()
# Enforce character limit
return desc[:160] if len(desc) > 160 else desc
Process in batches of 50
pages = pd.read_csv("pages.csv")
with ThreadPoolExecutor(max_workers=10) as executor:
pages['new_meta'] = list(executor.map(generate_meta, pages.to_dict('records')))
pages.to_csv("meta_descriptions_output.csv", index=False)
``
Temperature 0.3 keeps output consistent. Max 80 tokens prevents runaway generation.
Step 4: The Approval Gate
Not every description needs human eyes. Use these filters:
- Human task: review the flagged 10–15%, fix brand voice issues, approve in bulk
I use a Google Sheet with three columns: auto-generated, human-edited, status (approved / needs work / rejected).
Step 5: Bulk Update
Export approved descriptions and upload via:
- Next.js/Vercel: Update frontmatter and redeploy
The Catch (What's Still Hard)
AI still misses nuance. It wrote "Learn how to handle a data breach" for a page about breach prevention. The intent was wrong. Every flagged description gets a second look for intent match.
Character counting is imprecise. GPT-4o counts tokens, not characters. The script truncates at 160, which sometimes cuts a word mid-thought. I add a 5-character buffer and let the human round out the final 2%.
Brand voice doesn't transfer automatically. For a medical client, AI generated "Discover how to manage your diabetes" — too casual. The approved version was "Learn evidence-based strategies for diabetes management." Brand guardrails must be explicit in the prompt.
What's Still Hard
- API costs at scale: 500 descriptions × ~1,500 input tokens = ~750K tokens = ~$3.75 on GPT-4o. Cheap, but 50,000 pages = $375. Budget accordingly.
Related reading
The Bottom Line
This isn't a future possibility—it's happening now for organizations that moved early. The question isn't whether this technology will reshape your workflows. It's whether your team will be leading that change or reacting to competitors who did.
Daily AI Intelligence, Free
Get AI news and analysis delivered to your inbox. No spam. Unsubscribe anytime.
One-click unsubscribe · We never share your data