Operate the product catalog
This guide documents operational rules for product and price catalog operations.
It focuses on behavior and constraints. For endpoint request/response shapes, use API reference.
Prereqs
- A Service Key for
/mgt/v1. - You have chosen stable codes: Define your product catalog.
API surfaces
Management (write/read):
/mgt/v1/ops/catalog/products*/mgt/v1/ops/catalog/prices*
Public catalog read:
/api/v1/catalog/products/api/v1/catalog/prices
Authoritative schema:
Product lifecycle behavior
- Create accepts
draft,active,archived. - Delete is soft archive (
status = archived), not hard delete. - Patch with no effective fields returns current record unchanged.
presentation_configmust be a JSON object (array is invalid).
Price lifecycle behavior
- Create defaults
statustoactivewhen omitted. - Delete is soft archive (
status = archived), not hard delete. - Patch with no effective fields returns current record unchanged.
- Price must belong to an existing product in the same realm.
Recurring and subscription-group rules
Recurring shape rules:
recurring_intervalandrecurring_countmust be provided together.- If recurring is set,
subscription_group_idis required.
Group pairing rules:
subscription_group_idandsubscription_group_keymust be provided together.- Group id must reference an existing subscription group.
Deterministic ordering and default selection
Price ordering is deterministic:
display_priorityascendingunit_amountascending- deterministic final tiebreaker
Implications:
- Public catalog APIs return prices in this order.
- Default price selection follows this order after filters.
- In product detail reads, if a price exists in
default_currency, it is preferred as default; otherwise the first ordered price is used.
Validation and uniqueness rules
product_codeis unique.(provider, provider_product_id)is unique.price_codeis unique.provider_price_idis unique.default_currencyandcurrencymust be 3-letter uppercase.unit_amount >= 0.recurring_count > 0when recurring is set.
Conflicting writes against these rules are rejected; retries with the same invalid input do not succeed.
Metadata keys that drive system behavior
Product metadata
billing_plan_codegrants[]
Price metadata
billing_plan_codegrants[]gating.bundle
Rules and precedence
metadata.grantsmust not contain duplicate grant program codes within the same metadata object.- Grant binding merge reads product + price grants:
- same program code on both levels: price-level values override product-level values.
- Billing plan mapping prefers price-level
billing_plan_code; falls back to product-level when price-level is absent. - Gate bundle projection reads
metadata.gating.bundlefrom price metadata.
Public catalog read semantics
- Public
/catalog/productsand/catalog/pricesreturn only active products and active prices. /catalog/pricesrequiresproduct_id.- Optional expansions enrich products/prices with:
- subscription-state hints
- feature-family projections
This makes catalog usable as a storefront index while keeping write operations on the management surface.
Operational workflow recommendation
- Create products in
draft. - Attach prices and validate recurring/group constraints.
- Verify metadata wiring (
billing_plan_code,grants,gating.bundle). - Promote to
active. - Archive old products/prices instead of deleting history.
Verify
- Create/update/delete operations satisfy recurring/group pairing rules.
- No duplicate program codes exist inside each
metadata.grants. - Public catalog returns expected active products/prices and order.
- Checkout/subscription flows resolve expected plan/grant/gate outcomes from metadata.
Next
- Metadata contracts overview: Metadata-driven configuration
- Plan/package design: Plans overview