Programmatic SEO

How we built thousands of SEO landing pages at scale

How we combined live inventory, AI classification, and automated indexation to build landing pages at scale.

1 · Problem

With a marketplace, inventory is constantly changing. A furniture type or location might have plenty of listings today and almost none tomorrow.

The problem becomes much larger when you consider all the possible combinations. Furniture can be organized across category, furniture type, room type, and location, from cities down to suburbs. Creating a page for every possible combination would produce thousands of URLs, many with little or no inventory. Those pages would end up looking almost identical apart from the title, URL, and a mostly empty listing grid.

We needed a system where real inventory determines which pages are worth creating and indexing. At the same time, the system needed to automatically recognize when a new page becomes viable as inventory grows, without requiring us to manually create or manage each page.

2 · Rule: A page has to earn its existence

A page becomes viable only when it reaches a minimum number of listings.

Once a page exists, whether it stays indexable is a separate question.

This prevents pages with little or no inventory from being created, and helps avoid thin, repetitive pages that provide little value to users or search engines. Everything that follows is an implementation of that one rule.

3 · System architecture

A listing moves through classification and location resolution before becoming part of the inventory that determines which landing pages are created and indexed.

processing
stored state
the threshold decision
discovery
listing → page pipelinelisting createdprimary image + locationai classificationfurniture type + room typeconstrained by db taxonomylocation resolutionsuburb → cityconsistent geographic hierarchydatabasetaxonomy · listings · page statepublished + indexablesource of truthinventory aggregationtype · room · locationlive inventorypage viabilityinventory meets the thresholdpage becomes eligiblebelow the threshold,no page is createdpage generationlive listingscounts · prices · metadataindexation & sitemapindexable → discoverabletechnical checks appliedfig 1 — the database is the join between classification, inventory and page state;pages emerge from live inventory rather than being maintained by hand.
fig 1Classification and location resolution run independently and meet in the database. Nothing downstream knows about a single listing — only about aggregated inventory, which is what makes page creation automatic.

4 · Following a listing through the system

Consider a seller listing a three-seater sofa. Once the listing is created, the system needs to understand two things: what the item is and where it belongs.

Furniture type
Classified from the primary image, constrained to the options allowed by the listing's category.
Room type
Classified in the same pass, from the same taxonomy stored in the database.
City
Resolved separately by mapping the listing's suburb up to its city.

Classification

The primary image is sent to Gemini Flash to determine the furniture type and room type. The model doesn't choose from every possible furniture type. The available options are constrained by the listing's existing category and come from the taxonomy stored in the database.

The model can also return no classification when the image is unclear. This is intentional. An unclassified listing is better than incorrectly placing a product on a landing page where it doesn't belong.

Location

The location is resolved separately. The listing's suburb is mapped to its corresponding city, giving us a consistent location hierarchy that can be used when aggregating inventory.

Becoming a page

The listing now becomes part of the inventory used to determine which pages are viable. As more listings are added, the inventory for each page grows. When that inventory reaches the required threshold, the page becomes eligible to be created and indexed.

Once a page becomes viable, it is generated from the inventory behind it. The page includes the actual listing grid along with information such as the current listing count, price range, and latest update. Structured data and other page metadata are also generated from the same underlying inventory.

5 · Page lifecycle & indexation

Creating a page is only one part of the problem. Marketplace inventory changes constantly, so the system also needs to decide whether an existing page should remain indexable.

We treat page existence and indexation as separate states. Once a page has been published, it remains available even when its inventory changes. Its indexation state follows a deliberately asymmetric set of rules:

InventoryWhat happens to the pageSitemap
ZeroDemoted — no longer eligible for indexationremoved
Below thresholdCurrent indexation state is preservedunchanged
At or above thresholdEligible to be indexed, or re-indexedincluded

The asymmetry is the point. Only a drop to zero forces a demotion; a page that dips into the middle band keeps whatever state it already had, so URLs don't churn in and out of the sitemap every time inventory moves by one listing.

Reconciliation. A background process reevaluates the full set of pages and handles demotions. It runs every six hours, ensuring that changes missed by the event-driven path are eventually reconciled.

6 · Sitemap validation

The sitemap is the final layer between the pages our system generates and what search engines are asked to discover. Instead of blindly adding every eligible URL, we validate each page before including it.

CheckWhat it prevents
Resolves successfullyA broken or erroring URL being advertised to search engines
Does not redirectThe URL in the sitemap differing from the URL that actually serves
Not marked noindexAsking for indexation of a page that refuses it
Self-referencing canonicalA page pointing search engines at a different URL than itself

If any of these checks fail, the page is excluded. Only pages that meet the indexation rules and pass all technical checks are included in the sitemap.

7 · Lessons learned

AI should be allowed to say “none.” If the model isn't confident, forcing a classification can place a listing on an unrelated landing page. To prevent this, the model can return none when the image isn't clear enough. An unclassified listing is better than an incorrect one.

Let the database own the taxonomy. The AI should never be the source of truth for furniture types or rooms. By generating its valid options from the database, classification stays aligned with the taxonomy used to build the pages.

Template the structure, derive the content. The page structure can be reused across thousands of URLs, but the actual content should come from live inventory. Counts, price ranges, listings, and update information make each page useful rather than just changing the URL and heading.

Working on something this touches?

Talk to us