Product Schema
Product Noun type definition and data structure
Product Schema
The Product Noun represents anything a business sells - from SaaS applications to APIs, datasets, and headless services. Every Product has a defined schema that determines its behavior, pricing, and rendering.
Product Type Definition
export interface Product {
id: string
name: string
business?: string | Business
type: 'SaaS' | 'API' | 'Data' | 'Headless'
stripeProductId?: string | null
description?: string | null
isActive?: boolean | null
// Categorization
industries?: (string | Industry)[] | null
productCategories?: (string | ProductCategory)[] | null
// Features & Pricing
features?: {
docs?: (string | Feature)[]
hasNextPage?: boolean
totalDocs?: number
}
prices?: (string | Price)[] | null
// Interface Types
interfaces?: {
hasAPI?: boolean
hasRPC?: boolean
hasMCP?: boolean
hasSDK?: boolean
hasCLI?: boolean
}
// Metadata
updatedAt: string
createdAt: string
}Product Types
Each product type has different characteristics and business models:
| Type | Revenue Model | Interface | Example |
|---|---|---|---|
| SaaS | MRR (subscription) | Web app + API | Figma, Notion |
| API | Usage-based | REST/GraphQL/tRPC | Stripe API, OpenAI API |
| Data | MRR + Usage | API + downloads | Clearbit, PeopleDataLabs |
| Headless | Usage-based | API + MCP only | AI services, automation tools |
MDXLD Schema
Products can be defined declaratively in MDXLD:
---
$context: https://schema.org.ai
$type: Product
$id: https://acme.com/products/api
name: Acme API
type: API
business: https://acme.com
description: RESTful API for data enrichment
isActive: true
# Categorization
industries:
- B2B SaaS
- Data & Analytics
productCategories:
- API Platform
- Data Enrichment
# Interfaces
interfaces:
hasAPI: true
hasMCP: true
hasSDK: true
hasCLI: false
# Pricing
prices:
- $id: price_basic
amount: 0.001
currency: USD
type: usage
interval: request
- $id: price_pro
amount: 0.0008
currency: USD
type: usage
interval: request
minVolume: 1000000
---
# {name}
{description}
## Features
<Features products={[$id]} />
## Pricing
<Pricing prices={prices} />
## Documentation
<APIReference product={$id} />Schema Properties
Core Fields
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier |
name | string | Yes | Product display name |
type | enum | Yes | Product type (SaaS, API, Data, Headless) |
business | reference | Yes | Owning business |
description | string | No | Product description |
isActive | boolean | No | Whether product is currently offered |
Categorization
| Field | Type | Description |
|---|---|---|
industries | Industry[] | Market verticals this product serves |
productCategories | ProductCategory[] | Product classification (CRM, Analytics, etc.) |
Features & Pricing
| Field | Type | Description |
|---|---|---|
features | Feature[] | Product capabilities and features |
prices | Price[] | Pricing plans and tiers |
Interface Types
Products expose different interface types:
| Interface | Protocol | Use Case |
|---|---|---|
| API | REST/GraphQL | Programmatic access |
| RPC | tRPC/gRPC | Type-safe remote calls |
| MCP | Model Context Protocol | AI agent tools |
| SDK | Language-specific | Client libraries |
| CLI | Command-line | Terminal interface |
Related Nouns
Feature
Individual product capabilities:
interface Feature {
id: string
name: string
description?: string
product: string | Product
isEnterprise?: boolean
}Price
Pricing structure for a product:
interface Price {
id: string
product: string | Product
stripePriceId?: string
amount: number
currency: string
type: 'subscription' | 'usage' | 'one_time'
interval?: 'month' | 'year' | 'request' | 'seat'
minVolume?: number
}ProductCategory
Product classification:
interface ProductCategory {
id: string
name: string
slug: string
description?: string
parent?: string | ProductCategory
}Examples: CRM, Analytics Platform, Data Enrichment, Payment Gateway
Payload CMS Collection
Products are stored in the products Payload collection:
// Query via REST API
GET /api/products
GET /api/products/:id
POST /api/products
PATCH /api/products/:id
DELETE /api/products/:id
// Query params
?where[type][equals]=API
?where[isActive][equals]=true
?where[business][equals]=123
&limit=20&page=1GraphQL
query {
Products(where: { type: { equals: API } }) {
docs {
id
name
type
business {
name
}
features {
docs {
name
description
}
}
prices {
amount
currency
type
}
}
}
}Auto-Wiring
Product components auto-wire to the Payload collection:
// Automatically queries products collection
<ProductList type="API" />
<ProductCard product={productId} />
<ProductPage product={productId} />
// Full product application
<ProductApp product={productId} />Validation
Zod Schema
import { z } from 'zod'
export const ProductSchema = z.object({
name: z.string().min(1),
type: z.enum(['SaaS', 'API', 'Data', 'Headless']),
business: z.string(),
description: z.string().optional(),
isActive: z.boolean().default(true),
stripeProductId: z.string().optional(),
industries: z.array(z.string()).optional(),
productCategories: z.array(z.string()).optional(),
})Type Guards
export function isSaaSProduct(product: Product): boolean {
return product.type === 'SaaS'
}
export function hasAPI(product: Product): boolean {
return product.interfaces?.hasAPI === true
}
export function isUsageBased(product: Product): boolean {
return product.type === 'API' || product.type === 'Headless'
}Business Logic
Revenue Model by Type
export function getRevenueModel(product: Product): string {
switch (product.type) {
case 'SaaS':
return 'MRR (Monthly Recurring Revenue)'
case 'API':
return 'Usage-based (pay-per-call)'
case 'Data':
return 'MRR + Usage'
case 'Headless':
return 'Usage-based'
}
}Interface Requirements
export function getRequiredInterfaces(type: Product['type']): string[] {
switch (type) {
case 'SaaS':
return ['Web App', 'API']
case 'API':
return ['REST API']
case 'Data':
return ['API', 'Downloads']
case 'Headless':
return ['API', 'MCP']
}
}Next Steps
- SaaS Products - Subscription software with UI
- API Products - Pay-per-call and usage-based APIs
- Data Products - Data subscriptions and datasets
- Headless Products - API-only for AI agents