Live ATS sync plus AI-generated SEO for every market you serve.
A national staffing company needed ATS jobs live on WordPress: filterable, mapped, and ranking in every city they place talent. Two plugins built as one system.
The ATS has the jobs. WordPress has the audience. Nothing connected them — cleanly, at scale, with SEO built in.
No live ATS integration
Their ATS has no official WordPress plugin. Jobs lived in the ATS and died there — manually exported, manually posted, always out of date. A national firm placing in dozens of markets can't run that way.
No search presence by market
Ranking for "jobs in Detroit, MI" or "staffing in Toledo, OH" requires a dedicated, unique page for each location. There were none — and no practical way to write hundreds of them by hand.
Legacy site to migrate
Years of content on an old website. No structured export, no WordPress-compatible format. The old content had to be preserved during the rebuild without manual copy-paste across hundreds of pages.
Plugin 01 owns the data. Plugin 02 owns the pages.
Clear separation of concerns — one plugin could be swapped or upgraded without touching the other.
The data layer.
Everything that touches the ATS lives here. The rest of the site — and Plugin 02 — only ever asks this plugin for data.
JWT auth exchange
Authenticates with the ATS API and auto-renews the JWT token on every 15-minute sync cycle — the site never goes offline due to an expired credential.
15-minute cron sync
Fetches all active job records from the ATS on a cron schedule and stores them locally. Jobs appear on the site within 15 minutes of being published in the ATS.
Geocoding cache
Each unique location is geocoded once and cached persistently. Never re-fetched unless the address changes — no API quota drain from the same city being re-geocoded on every sync.
Location normalizer
Collapses "Detroit, Michigan," "Detroit, MI," and "Detroit, MI 48226" into one consistent filter option. The client's ATS data was inconsistent — this engine handles every known variant.
4 frontend shortcodes
[ats_jobs_list] filterable grid · [ats_jobs_single] full job detail · [ats_jobs_map] interactive location map · [ats_jobs_search] standalone search bar — each independently embeddable anywhere.
Structured logger
Sync events, geocode hits and misses, API errors — all logged to a dedicated table queryable from the WP admin. A full audit trail without cluttering PHP's error_log.
The SEO layer.
Depends on Plugin 01. Location data flows from the live sync — no manual data entry, no duplicate sources of truth.
Auto-generated CPT
Creates one job_location_page CPT record per state and per city — entirely automatically, based on where live jobs exist. Pages appear and disappear as inventory moves.
AI content per page
OpenAI generates 500–600 words of unique, heading-structured content for every state and city — using the client's voice profile from the plugin settings. Every page is different. None are templated duplicates.
Auto-draft on no jobs
When a location has no active jobs, its page is automatically drafted — no dead pages ranking for places where the client has nothing to offer. When new jobs arrive, the page publishes again.
Daily content refresh
A daily cron checks every published page. Stale content or changed job counts trigger AI regeneration automatically — pages stay current without manual intervention.
Hooks into sync completion
When Plugin 01 finishes a sync and fires ats_jobs_sync_complete, Plugin 02 immediately checks for new or removed locations. A new city in the ATS gets a page within 15 minutes.
Admin regenerate-on-demand
Any location page can be manually regenerated from the WP admin — useful after changing the voice profile in settings or when a market needs freshened content.
From a new job in the ATS to a ranked, AI-described city page — in 15 minutes.
Hundreds of location pages. Every one unique.
Templated location pages get filtered by Google. Pages that repeat the same copy with only the city name changed don't rank — they compete with each other and dilute the domain. Every page generated by this system is written from scratch for that specific location, using the live job data as context.
AI content that uses live job data
The content generator receives the specific jobs active in that city — job titles, industries, job counts — and writes content that reflects the real opportunity landscape there. Not a generic "we staff in Detroit" paragraph.
Voice profile from settings
The system prompt for OpenAI is built from a voice profile the admin configures in the plugin settings — brand tone, keyword priorities, required disclaimers. Every page sounds like the same company.
Proper heading structure
H1, H2, and H3 are part of the generation spec — not left to the AI. Every page arrives with a correct heading hierarchy that search engines can parse cleanly.
Dynamic job counts in metadata
Title tags and meta descriptions include the live job count for that location — "Browse 12 open jobs in Detroit, MI" — updated whenever the page regenerates, so metadata reflects reality.
Schema markup per page
JobPosting schema written to the head of every location page. Compatible with Yoast SEO and RankMath — the SEO handler hooks into both and yields to whichever is active.
Sitemap-ready CPT
The job_location_page CPT is registered as public and show_in_rest — it's picked up by WordPress core sitemaps, Yoast, and RankMath automatically, with no additional configuration.
The location normalizer — because client data is never clean.
The client's ATS records used inconsistent location formats. Without normalization, the same city appeared as multiple filter options — and as multiple separate location pages, each too thin to rank. The normalizer collapses every variant to a single canonical "City, ST" form before any page is created or any filter is built.
Legacy website migration — without touching WordPress posts.
A purpose-built scraper that crawled the old site and stored it — cleanly, separately, non-destructively.
The client had years of content on a legacy website with no structured export and no WordPress-compatible format. We built a third plugin that crawled the old site, scraped every page and media asset, and stored them in a structured internal database — without creating WordPress posts or pages. The full content archive was preserved during the rebuild with zero manual copy-paste. When the new site was ready, the migrated content was available for selective import. A purpose-built tool for a specific one-time problem, built and deployed alongside the main system in the same engagement.
What the system delivers.
Need your ATS talking to your website — and your website ranking everywhere you work?
We've built this system. We can build the right version of it for your platform and your markets.