AACSearch / guide
Programmatic SEO pages
Turn a facet into indexable landing pages with templated metatags, generate them from the live index, audit what was generated and export a sitemap.
A rule turns one facet of a collection into search-engine landing pages — one per facet value — so a page that only exists as a combination of filters (a brand and a price bracket) stops being empty for a crawler. Rules are templates with #PLACEHOLDER# substitutions; generateSeoPages materializes the pages from the live index, auditSeoPages re-checks what's already generated, and exportSeoSitemap emits the urlset. Every operation on this page needs a full key.
Create a rule
createSeoRule — POST /seo/rules:
await client.seo.createSeoRule({
collection: "products",
name: "Brand pages",
facet_field: "brand",
url_template: "#SECTION#/brand/#VALUE#",
templates: {
title: "#VALUE# — #SECTION# | #SITE_NAME#",
description: "#COUNT# #VALUE# products in #SECTION#.",
h1: "#VALUE#",
},
});| Placeholder | Renders as |
|---|---|
#SECTION# | the collection |
#PROPERTY# | the facet field (brand) |
#VALUE# | the facet value (Acme) |
#COUNT# | documents carrying that value, at generation time |
#SITE_NAME# | the rule's site_name, or the organization's name |
At least one non-empty template (title, description, h1, text) is required; an unknown placeholder is rejected rather than rendered onto a live page. active: false (the default is true) makes generateSeoPages skip the rule without deleting it.
| Operation | Endpoint |
|---|---|
listSeoRules | GET /seo/rules |
getSeoRule | GET /seo/rules/{ruleId} |
updateSeoRule | PUT /seo/rules/{ruleId} |
deleteSeoRule | DELETE /seo/rules/{ruleId} |
Generate pages
generateSeoPages — POST /seo/pages/generate — renders every active rule of a collection (or just rule_id) against the live index: the engine's facet counts for facet_field supply one page per value, with #COUNT# set to how many documents carry it. A value that already has a page gets it re-rendered in place; the rest are created:
const report = await client.seo.generateSeoPages({ collection: "products" });
// { collection, rules, created, updated, total }listSeoPages (GET /seo/pages, paginated, filterable by collection) lists what's been materialized — url, title, robots and when it was last rendered:
const page1 = await client.seo.listSeoPages({ collection: "products", limit: 50 });Audit and export
auditSeoPages — POST /seo/pages/audit — re-checks the organization's generated pages (or one collection) against their rules and reports, per page: an empty title or description, a rule that was deleted or deactivated since the page was rendered, templates changed after the page was rendered (the page is stale), and the robots directive the page deserves now. Findings are advisory — nothing is rewritten; run generateSeoPages to fix what the audit found:
const audit = await client.seo.auditSeoPages({ collection: "products" });
// audit.checked, audit.findings -> [{ page_id, url, robots, issues }]exportSeoSitemap — GET /seo/pages/sitemap — returns the active, indexable pages as an XML urlset, wrapped as a JSON string (the contract is JSON-only). Store it at the sitemap URL your storefront serves:
curl -G https://api.aacsearch.com/v1/seo/pages/sitemap \
-H "X-NOVA-API-KEY: $NOVA_API_KEY" --data-urlencode "collection=products"A page's active flag decides whether it belongs in the sitemap at all; robots: "noindex" keeps a page reachable but out of search-engine indexes without removing it.
Storefront UI (aacsearch-ui)
Search page, autocomplete, ⌘K palette, support chat, voice, photo search and recommendations — in React or on any HTML page.
Assistants (RAG)
Create an assistant that answers from your collections, ask it from a server or a browser, stream the answer, continue conversations and keep the cost in check.