Skip to main content

Overview

The agentic product feed at GET /agentic/products/feed is the primary interface for AI agents discovering products on Podium. Every product in the feed includes:
  • An intent score reflecting both user-declared preferences and market-derived intelligence
  • Provenance metadata showing exactly what signals contribute to the score
  • Attribute baselines — the top enriched attributes for the product (texture, sentiment, key ingredients, etc.)
The feed is public — no API key required. This enables AI agents to discover products without pre-provisioned credentials, lowering the integration barrier for the agentic commerce ecosystem.

Request

GET /api/v1/agentic/products/feed

Query Parameters

ParameterTypeDefaultDescription
limitinteger20Max products to return (1–100)
offsetinteger0Pagination offset
categorystringFilter by product category
minPriceintegerMinimum price in cents
maxPriceintegerMaximum price in cents
inStockbooleantrueOnly return in-stock products

Response Shape

{
  "products": [
    {
      "id": "prod_abc123",
      "title": "Organic Face Serum",
      "description": "Lightweight hydrating serum with hyaluronic acid",
      "price": {
        "amount": 2500,
        "currency": "USD"
      },
      "available": true,
      "imageUrl": "https://cdn.example.com/serum.jpg",
      "productUrl": "https://shop.example.com/organic-serum",
      "creator": {
        "id": "creator_xyz",
        "name": "Clean Beauty Co",
        "slug": "clean-beauty-co"
      },
      "intentScore": 0.42,
      "intentProvenance": {
        "USER_DECLARED": {
          "voteCount": 12,
          "weight": 0.7
        },
        "MARKET_DERIVED": {
          "signalCount": 87,
          "weight": 0.3
        }
      },
      "attributeBaselines": [
        {
          "type": "texture",
          "topValue": "lightweight",
          "score": 0.91
        },
        {
          "type": "sentiment",
          "topValue": "positive",
          "score": 0.84
        },
        {
          "type": "key_ingredient",
          "topValue": "hyaluronic acid",
          "score": 0.78
        },
        {
          "type": "scent",
          "topValue": "fragrance-free",
          "score": 0.72
        }
      ]
    }
  ],
  "pagination": {
    "total": 234,
    "limit": 20,
    "offset": 0,
    "hasMore": true
  }
}

Intent Score Computation

The intent score combines two signal lanes with fixed weighting:
intentScore = (declaredScore × 0.7) + (marketScore × 0.3)

USER_DECLARED (70% weight)

First-party signals: campaign votes, user interactions, explicit preferences.
declaredScore = min(voteCount / 100, 1.0)
Scales linearly from 0 to 1 as votes accumulate, capped at 100 votes. This lane carries the most weight because user-declared intent is the highest-fidelity signal.

MARKET_DERIVED (30% weight)

Enrichment pipeline signals: extracted attributes from reviews, structured APIs, and community sources.
marketScore = min(signalCount / 500, 1.0)
Scales linearly from 0 to 1 as enrichment signals accumulate, capped at 500 signals.

Memory-Aware Scoring

When a user has an AgentMemory, the scoring system incorporates their structured profile into signal weights. Goals, concerns, avoidances, and category-specific price ranges all influence which products score highest. Domain-specific weights are applied based on the product’s vertical — beauty products are weighted differently than wellness supplements. See Memory & Intelligence — Signal Scoring for details.

Cold-Start Behavior

When a product is new and has zero votes, the intent score is driven entirely by market-derived signals. As users interact with the product (via campaigns, companion interactions, or direct purchases), the user-declared lane naturally takes over:
PhaseUSER_DECLAREDMARKET_DERIVEDEffective Score Driver
Cold start (0 votes, 50 signals)00.03Market data only
Early (5 votes, 100 signals)0.0350.06Balanced
Growing (50 votes, 200 signals)0.350.12User data dominates
Mature (100+ votes, 500 signals)0.70.3User data drives

Provenance Transparency

Every product in the feed includes intentProvenance — a breakdown of exactly what signals contribute to the score. This enables agents to:
  • Explain recommendations to users (“This product has strong positive reviews from 87 market sources”)
  • Apply their own weighting if the default 70/30 split doesn’t match their use case
  • Filter by confidence — only recommend products with sufficient user-declared signals

Attribute Baselines

The attributeBaselines array provides the top enrichment attribute for each type, computed by the enrichment pipeline. Each entry includes:
FieldTypeDescription
typestringAttribute type from the taxonomy
topValuestringMost prominent value for this attribute
scorefloatComputed score: avg(confidence) × log1p(count)
Agents can use baselines to match products against user preferences. For example, a user with skinType: "oily" and concerns: ["acne"] can be matched against products with skin_type_suitability: "oily" and key_ingredient: "salicylic acid" baselines.

Reason Tags

Products in the companion recommendations include a reasonTag field — a concise, human-readable explanation of why this product was recommended for a specific user.
{
  "id": "prod_abc123",
  "title": "Organic Face Serum",
  "intentScore": 0.42,
  "reasonTag": "For oily skin · Hydration"
}
Reason tags are generated during recommendation re-ranking by combining signals from the user’s memory profile — skin type, concerns, budget, brand preferences, and avoidances. Tags can be simple ("Hydration") or compound ("For oily skin · Under your $50 budget"). See Memory & Intelligence — Reason Tags for the full list of tag types and how they’re computed.

ML Scoring Layer

Beyond the two-lane intent score, Podium applies machine learning signals to improve product ranking over time.

Popularity Scoring

Product popularity is computed from weighted user interactions — purchases carry the most weight, followed by purchase intent, affiliate clicks, and rank-ups. Negative interactions (skips, rank-downs) reduce the score. The raw sum is normalized by the square root of total interactions to prevent high-volume but low-quality signals from dominating.

Temporal Decay

Interaction signals decay with a 30-day half-life. Recent signals carry more weight than older ones, keeping recommendations responsive to shifting user interests and seasonal trends.

Feature Cache

For each product, the system maintains a pre-computed feature set (quality score, brand tier, popularity, price percentile, enrichment depth) that is cached for fast retrieval during scoring. This avoids recomputation on every request while keeping scores fresh through periodic recalculation.

Impression Tracking

Every product shown to a user is logged with its display position. This creates a feedback loop: the system can distinguish between products that were seen and ignored vs products that were never shown, enabling accurate conversion-rate estimation and position-bias correction.

Checkout Sessions

Once an agent selects a product for purchase, it creates a checkout session:
POST /api/v1/agentic/checkout/sessions
{
  "productId": "prod_abc123",
  "quantity": 1,
  "userId": "user_xyz",
  "shippingAddress": {
    "street": "123 Main St",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94102",
    "country": "US"
  },
  "paymentMethod": "x402"
}
The session returns payment details for x402 execution or Stripe checkout URL. See x402 Payments for the machine-native payment flow.

Integration Patterns

Minimal Agent Integration

// 1. Discover products
const feed = await fetch('https://api.podium.build/api/v1/agentic/products/feed?limit=10');
const { products } = await feed.json();

// 2. Filter by agent logic (e.g., match user preferences)
const matches = products.filter(p =>
  p.attributeBaselines.some(b =>
    b.type === 'skin_type_suitability' && b.topValue === 'oily'
  )
);

// 3. Create checkout session for best match
const session = await fetch('https://api.podium.build/api/v1/agentic/checkout/sessions', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    productId: matches[0].id,
    quantity: 1,
    userId: 'user_xyz',
    paymentMethod: 'x402'
  })
});

With Companion API (Personalized)

For agents that maintain user profiles:
import { createPodiumClient } from '@podium-sdk/node-sdk'
const client = createPodiumClient({ apiKey: process.env.PODIUM_API_KEY })

const { data: profile } = await client.companion.listProfile({ userId })

const { data: recs } = await client.companion.listRecommendations({ userId })

const feed = await client.agentic.listProductsFeed({ page: 1, limit: 20 })
const enriched = feed.products.map(p => ({
  ...p,
  matchScore: computeMatch(profile, p.attributeBaselines)
}))