Ads Agent

Generate ad content and serve product data to ad networks.

Overview

The Ads Agent generates promotional content for ad platforms and responds to product queries from AI-powered shopping assistants like Perplexity. It ensures your products are discoverable in the emerging agent commerce ecosystem.

Capabilities

ADS AGENT CAPABILITIES
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ENDPOINTS:
  POST /ads/generate          Generate ad content
  POST /ads/product-card      Generate product cards
  GET /ads/campaigns          List active campaigns
  POST /ads/perplexity        Respond to Perplexity queries

FEATURES:
  ✓ Ad copy generation    LLM-powered ad text
  ✓ Product cards         Structured product data for ads
  ✓ Campaign management   Track ad campaigns
  ✓ Perplexity shopping   Answer product queries from Perplexity
  ✓ Dynamic pricing       Include real-time prices in ads
  ✓ A/B testing           Multiple ad variants

INTEGRATIONS:
  • Perplexity Shopping API
  • Google Ads
  • Meta Ads
  • Product catalog

Ad Generation

Generate platform-optimized ad content:

// Generate ad content for products
@OnEndpoint('/ads/generate', { method: 'POST' })
async generateAd(request: Request) {
  const { product_id, platform, style, max_length } = request.body;
  const product = await getProduct(product_id);
  const pricing = await calculateDynamicPrice(product, {});

  const adCopy = await this.llm.generate({
    prompt: `Generate a ${style} ad for ${platform}:
Product: ${product.name}
Description: ${product.description}
Price: $${pricing.suggested} (was $${product.pricing.list_price})
Key features: ${product.attributes}
Requirements:
- Max length: ${max_length} characters
- Platform: ${platform}
- Style: ${style}
- Include call to action
`,
  });

  return {
    product_id,
    platform,
    variants: [
      { id: 'v1', headline: adCopy.headline, body: adCopy.body, cta: adCopy.cta, character_count: adCopy.body.length },
      { id: 'v2', headline: adCopy.headline_alt, body: adCopy.body_alt, cta: adCopy.cta_alt, character_count: adCopy.body_alt.length },
    ],
    product_data: {
      name: product.name,
      price: pricing.suggested,
      original_price: product.pricing.list_price,
      discount_percent: pricing.discountPercent,
      image_url: product.media.images[0]?.url,
      landing_url: `https://store.example.com/p/${product_id}`,
    },
  };
}

// Generate structured product card
@OnEndpoint('/ads/product-card', { method: 'POST' })
async generateProductCard(request: Request) {
  const { product_id } = request.body;
  const product = await getProduct(product_id);
  const inventory = await checkInventory(product_id);
  const pricing = await calculateDynamicPrice(product, {});

  return {
    "@context": "https://schema.org",
    "@type": "Product",
    name: product.name,
    description: product.description,
    image: product.media.images.map(i => i.url),
    brand: { "@type": "Brand", name: product.attributes.brand },
    offers: {
      "@type": "Offer",
      price: pricing.suggested,
      priceCurrency: product.pricing.currency,
      availability: inventory.status === 'in_stock' ? "https://schema.org/InStock" : "https://schema.org/OutOfStock",
      seller: { "@type": "Organization", name: "Acme Sports" },
    },
    aggregateRating: {
      "@type": "AggregateRating",
      ratingValue: product.rating,
      reviewCount: product.review_count,
    },
  };
}

Perplexity Integration

Respond to queries from Perplexity Shopping and similar AI assistants:

// Handle Perplexity Shopping queries
@OnEndpoint('/ads/perplexity', { method: 'POST' })
async handlePerplexityQuery(request: Request) {
  const { query, user_context } = request.body;

  const products = await searchProducts(query, {
    limit: 5,
    minConfidence: 0.7,
  });

  return {
    results: products.results.map(product => ({
      title: product.name,
      description: this.generateShortDescription(product),
      price: { value: product.price, currency: 'USD', formatted: `$${product.price.toFixed(2)}` },
      availability: product.in_stock ? 'in_stock' : 'out_of_stock',
      url: `https://store.example.com/p/${product.product_id}`,
      image_url: product.image_url,
      rating: product.rating,
      brand: product.brand,
      merchant: {
        name: 'Acme Sports',
        logo_url: 'https://...',
        shipping_info: 'Free shipping on orders over $100',
      },
    })),
    summary: this.generateQuerySummary(query, products),
    follow_up_questions: [
      `What sizes are available for ${products.results[0]?.name}?`,
      `Do you have similar products under $100?`,
      `What's your return policy?`,
    ],
  };
}

generateShortDescription(product: Product): string {
  const highlights = [
    product.attributes.brand,
    ...product.semantics.usage_context.slice(0, 2),
    product.attributes.waterproof ? 'waterproof' : null,
  ].filter(Boolean);
  return `${product.name} - ${highlights.join(', ')}. ${product.description.slice(0, 150)}...`;
}

Configuration

# ads-agent-config.yaml
name: ads-agent
type: ads
version: "1.0"

platforms:
  google_ads:
    enabled: true
    headline_max: 30
    description_max: 90
  meta_ads:
    enabled: true
    primary_text_max: 125
    headline_max: 40
  perplexity:
    enabled: true
    api_key: $PERPLEXITY_API_KEY

generation:
  model: gpt-4o
  temperature: 0.8
  variants_per_product: 3
  styles:
    - professional
    - casual
    - urgent
    - value_focused
  blocklist:
    - "best in class"
    - "world's best"
    - "guaranteed"

pricing:
  include_original_price: true
  show_discount_percent: true
  min_discount_to_show: 5

ab_testing:
  enabled: true
  min_impressions: 1000
  significance_threshold: 0.95

tracking:
  utm_source: hyperfold
  utm_medium: agent_ads
  conversion_window_days: 30