GitHub description (short):
Rule-based programmatic SEO planner — GSC + crawl data → prioritized URL opportunities (CSV/YAML). Works standalone or with SEO-as-Code and AI-SEO-Toolkit.
Anyone can test in under 2 minutes with bundled sample data:
git clone https://github.com/seo-as-code/programmatic-SEO.git
cd programmatic-SEO
pip install -r requirements.txt
copy config\project.local.yaml.example config\project.local.yaml # Windows
# cp config/project.local.yaml.example config/project.local.yaml # macOS/Linux
python scripts/planner/pseo_planner.pyOr:
.\reports\code\run_planner.ps1Expected output in reports/pseo/:
pseo_queries_*.csv— one row per GSC querypseo_opportunities_*.csv— clustered URL opportunitiespseo_opportunities_*.yaml— machine-readable page specspseo_summary_*.md— human-readable summary
- Copy
config/project.local.yaml.example→config/project.local.yaml - Copy
config/patterns.local.yaml.example→config/patterns.local.yaml(optional but recommended) - Edit only
*.local.yamlfiles (gitignored, never pushed)
| File | Purpose |
|---|---|
project.local.yaml |
Site URL, locale, paths to GSC/SF CSV |
patterns.local.yaml |
Your services, cities, custom pattern rules |
config/project.yaml and config/patterns.yaml on GitHub stay generic.
Programmatic SEO Toolkit is the architecture layer of the SEO-as-Code stack:
- Reads GSC queries + crawl inventory (Screaming Frog)
- Applies YAML pattern rules (services, locations, intents)
- Outputs prioritized URL opportunities with actions:
create_new,optimize_existing,consolidate,ignore
No AI required. No Ahrefs. Deterministic and reproducible.
SEO-as-Code-Toolkit (Data)
├─ GSC, GA4, CrUX, Screaming Frog → data/raw/*.csv
└─ Index monitor (separate folder in monorepo)
Programmatic-SEO (Architecture) ← this repo
├─ GSC + SF + pattern rules
└─ reports/pseo/*.yaml → URL specs for devs/CMS
AI-SEO-Toolkit (Decision)
├─ Semantic map, gaps, blog strategy, executive report
└─ Optional copy briefs on top of pSEO specs
| Handoff | File | From → To |
|---|---|---|
| GSC export | ../data/raw/gsc_*.csv |
SEO-as-Code → pSEO Planner |
| Crawl export | ../data/raw/internos_html.csv |
SEO-as-Code → pSEO Planner |
| Opportunities | reports/pseo/pseo_opportunities_*.yaml |
pSEO → dev/CMS or AI module 12 |
programmatic-seo/
config/
project.yaml # generic site placeholders
patterns.yaml # generic pattern rules
project.local.yaml.example
patterns.local.yaml.example
data/samples/ # demo GSC + SF (committed)
scripts/
lib/ # config loader + rule engine
planner/pseo_planner.py # main CLI
orchestrator/pseo_master.py
reports/
pseo/ # generated (gitignored)
code/ # run_planner.ps1, run_with_seo_as_code.ps1
templates/ # page spec examples for CMS
docs/PLAYBOOK.md
cd programmatic-seo
.\reports\code\run_planner.ps1cd C:\path\to\proyecto_seo\programmatic-seo
.\reports\code\run_with_seo_as_code.ps1py .\scripts\planner\pseo_planner.py --gsc ..\data\raw\gsc_oauth_2026-01-01_2026-02-01.csv --sf ..\data\raw\internos_html.csvDefined in config/patterns.yaml + patterns.local.yaml:
| Pattern | Triggers | Suggested URL |
|---|---|---|
service_location |
service + city tokens | /services/{service}-{city}/ |
service_national |
service, no geo | /services/{service}/ |
blog_informational |
how/what/guide queries | /blog/{query-slug}/ |
brand_navigational |
brand intent | ignore |
Decision rules override patterns: hub weakness, cannibalization, low volume, etc.
Full guide: docs/PLAYBOOK.md
| Action | When |
|---|---|
create_new |
Demand exists, no dedicated URL |
optimize_existing |
URL exists but underperforms |
consolidate |
Same query split across multiple URLs |
ignore |
Low volume or out of scope |
See .gitignore:
config/project.local.yamlconfig/patterns.local.yamlreports/pseo/*.csv,*.yaml,*.md.venv/
- SEO-as-Code-Toolkit — data extraction
- AI-SEO-Toolkit — analysis & executive reports
- Org: github.com/seo-as-code
MIT — use freely in client and personal projects.