Generated Page

Programmatic SEO pages grounded in fresh source material

Live preview

Checking API key

How it works

Each page is one request to Exa's /search endpoint with type: "deep". The query asks Exa to research the keyword, then the systemPrompt and outputSchema shape the result into a page.

The variants differ by schema. A listicle returns items and faqs. A comparison returns exactly two contenders and a verdict. Alternatives returns ranked replacements. FAQ returns only question and answer pairs.

Sources come from output.grounding. The preview keeps inline markdown links in prose and renders a compact favicon source row deduped by domain.

Source code

npm install exa-js
import Exa from "exa-js";
const exa = new Exa("YOUR_API_KEY");

const keyword = "Top 10 AI sales tools for B2B SaaS";

const result = await exa.search(
  `Research the best options for: ${keyword}. Find recent rankings, reviews, and comparisons.`,
  {
    type: "deep",
    numResults: 12,
    systemPrompt: `Generate a programmatic SEO listicle targeting "${keyword}". Rank real products by fit for the named audience. Plain prose, grounded claims, natural inline links, no hype.`,
    outputSchema: {
      type: "object",
      required: ["metaTitle", "metaDescription", "intro", "items", "faqs"],
      properties: {
        metaTitle: { type: "string" },
        metaDescription: { type: "string" },
        intro: { type: "string" },
        items: {
          type: "array",
          items: {
            type: "object",
            required: ["name", "url", "summary"],
            properties: {
              name: { type: "string" },
              url: { type: "string" },
              summary: { type: "string" },
            },
          },
        },
        faqs: {
          type: "array",
          items: {
            type: "object",
            properties: {
              question: { type: "string" },
              answer: { type: "string" },
            },
          },
        },
      },
    },
    contents: { highlights: true },
  }
);

const page = result.output.content;
const citations = result.output.grounding.flatMap((g) => g.citations);
Ask ExaBot