Catalog

Creating a Catalog

Define products using declarative YAML manifests

Before thinking about pricing, you need to clearly define what you're selling. This means identifying the features that differentiate your tiers and structuring your catalog accordingly.

MoneyMQ catalogs are defined using declarative YAML files, enabling version control, code review, and GitOps workflows. This keeps your revenue model in sync with your codebase — and works seamlessly with coding agents.

Directory Structure

Products follow a hierarchical folder structure inside your catalog path (default: billing/v1). Each product is a directory containing a product.yaml with optional nested variants:

billing/v1/
└── products/
    └── weather-api/
        ├── product.yaml          # Base product definition
        └── variants/
            ├── starter/
            │   └── product.yaml  # Starter tier
            ├── pro/
            │   └── product.yaml  # Pro tier
            └── enterprise/
                └── product.yaml  # Enterprise tier
billing/v1/
└── products/
    └── api-credits/
        ├── product.yaml          # Base product definition
        └── variants/
            ├── small/
            │   └── product.yaml  # 1,000 credits
            ├── medium/
            │   └── product.yaml  # 10,000 credits
            └── large/
                └── product.yaml  # 100,000 credits

Variants inherit from their parent and can override any attribute.

Product IDs are auto-generated from the directory structure. For example, weather-api/variants/pro/product.yaml becomes weather-api-pro.

Base Product Definition

A base product defines common attributes and the feature schema:

billing/v1/products/weather-api/product.yaml
---
# MoneyMQ Product - API version v1
name: Weather API
description: Real-time weather data
product_type: service
unit_label: request
active: true

features:
  requests_per_day:
    name: Daily Requests
    description: API calls included per day
  forecast_days:
    name: Forecast Range
    description: Days of forecast data available
  historical_data:
    name: Historical Data
    description: Access to past weather records

The base product defines the feature schema — what fields exist and what they mean. Variants then set specific values for each tier.

Creating Variants

Variants inherit from their parent and define tier-specific values and pricing:

billing/v1/products/weather-api/variants/starter/product.yaml
---
# MoneyMQ Product - API version v1
name: Weather API - Starter
description: Perfect for hobby projects and prototypes.

features:
  requests_per_day:
    value: 100
  forecast_days:
    value: 3
  historical_data:
    value: false
billing/v1/products/weather-api/variants/pro/product.yaml
---
# MoneyMQ Product - API version v1
name: Weather API - Pro
description: For apps that need reliable weather data.

features:
  requests_per_day:
    value: 10000
  forecast_days:
    value: 14
  historical_data:
    value: true

price:
  amounts:
    usd: 29.00
  pricing_type: recurring
  recurring:
    interval: month
billing/v1/products/weather-api/variants/enterprise/product.yaml
---
# MoneyMQ Product - API version v1
name: Weather API - Enterprise
description: Unlimited forecasts with dedicated support.

features:
  requests_per_day:
    value: -1           # -1 = unlimited
  forecast_days:
    value: 30
  historical_data:
    value: true

price:
  amounts:
    usd: 199.00
  pricing_type: recurring
  recurring:
    interval: month

One-Time Products

For one-time purchases like credit packs or licenses:

billing/v1/products/api-credits/product.yaml
---
# MoneyMQ Product - API version v1
name: API Credits
description: Prepaid API call credits
product_type: good
active: true

features:
  credits:
    name: Credits
    description: Number of API calls included

One-Time Variants

billing/v1/products/api-credits/variants/small/product.yaml
---
# MoneyMQ Product - API version v1
name: 1,000 Credits
description: Good for testing and small projects.

features:
  credits:
    value: 1000

price:
  amounts:
    usd: 9.00
billing/v1/products/api-credits/variants/medium/product.yaml
---
# MoneyMQ Product - API version v1
name: 10,000 Credits
description: Best value for growing teams.

features:
  credits:
    value: 10000

price:
  amounts:
    usd: 79.00
billing/v1/products/api-credits/variants/large/product.yaml
---
# MoneyMQ Product - API version v1
name: 100,000 Credits
description: For high-volume applications.

features:
  credits:
    value: 100000

price:
  amounts:
    usd: 599.00

Nested Variants

Variants can have their own variants, enabling A/B testing and regional pricing:

billing/v1/products/weather-api/variants/pro/
├── product.yaml
└── variants/
    ├── annual/
    │   └── product.yaml    # Annual billing (20% off)
    └── trial/
        └── product.yaml    # 14-day free trial

Nested variant IDs combine all levels: weather-api-pro-annual, weather-api-pro-trial. This recursive structure lets you experiment with pricing without cluttering your main catalog.

Product Schema Reference

Base Product Fields

FieldTypeDescription
namestringProduct name
descriptionstringProduct description
product_typeservice | goodProduct type (inherited by variants)
unit_labelstringDisplay label (e.g., "per seat", "per request")
activebooleanWhether the product is active (default: true)
featuresobjectFeature schema (name/description for each field)

Variant Fields

FieldTypeDescription
namestringProduct name (required for variants)
descriptionstringProduct description
activebooleanOverride active status
featuresobjectFeature values (key → { value: X })
priceobjectPrice configuration (see Configuring Prices)

Features: Schema + Values

Features follow a schema-value pattern:

  • Base product: Define the schema (name, description for each field)
  • Variants: Provide the values
Base product - defines schema
features:
  requests_per_day:
    name: Daily Requests
    description: API calls included per day
  support_tier:
    name: Support Level
    description: Response time guarantee
Variant - provides values
features:
  requests_per_day:
    value: 10000
  support_tier:
    value: "24h response"

This pattern enables consistent feature displays across your pricing page while allowing each tier to set its own limits.

Next Steps

On this page