Products & Prices
Define products with multiple pricing tiers, intervals, and UI configuration
Products & Prices
Products represent what you sell, and prices define how much customers pay. OmniBase supports per-unit pricing, tiered pricing, and usage-based billing.
Product Configuration
Basic Product Structure
{
"id": "pro",
"name": "Professional Plan",
"description": "For growing businesses",
"type": "service",
"stripe_id": "prod_xxx",
"prices": [],
"ui": {}
}| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier for the product (config ID) |
name | string | Yes | Product name displayed in Stripe and your UI |
description | string | No | Product description |
type | string | No | service (subscriptions) or good (one-time) |
stripe_id | string | No | Existing Stripe product ID (for migrations) |
prices | array | Yes | Array of price definitions (minimum 1) |
ui | object | No | UI display configuration |
Product Types
| Type | Use Case | Example |
|---|---|---|
service | Recurring subscriptions | SaaS plans, memberships |
good | One-time purchases, usage | Infrastructure, API calls |
Price Configuration
Per-Unit Pricing
The simplest pricing model charges a fixed amount:
{
"id": "pro_monthly",
"amount": 4900,
"currency": "usd",
"interval": "month",
"interval_count": 1,
"usage_type": "licensed",
"billing_scheme": "per_unit",
"public": true,
"default": true,
"stripe_id": "price_xxx",
"ui": {}
}| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique price identifier |
amount | number | Yes | Price in smallest currency unit (cents for USD) |
currency | string | Yes | 3-letter ISO currency code (lowercase) |
interval | string | No | Billing interval: day, week, month, year |
interval_count | integer | No | Number of intervals between billings (default: 1) |
usage_type | string | No | licensed (fixed) or metered (usage-based) |
billing_scheme | string | No | per_unit (default) or tiered |
public | boolean | No | Visible in public API (true/null = public) |
default | boolean | No | Default price for the product |
tax_included_in_price | boolean | No | Whether tax is included |
stripe_id | string | No | Existing Stripe price ID (for migrations) |
ui | object | No | UI display configuration |
Tiered Pricing
For volume-based or graduated pricing:
{
"id": "api_calls_tiered",
"currency": "usd",
"interval": "month",
"usage_type": "metered",
"meter": "api_calls",
"billing_scheme": "tiered",
"tiers_mode": "graduated",
"tiers": [
{ "up_to": 1000, "unit_amount": 0 },
{ "up_to": 10000, "unit_amount": 100 },
{ "up_to": 100000, "unit_amount": 50 },
{ "up_to": "inf", "unit_amount": 25 }
]
}| Field | Type | Required | Description |
|---|---|---|---|
billing_scheme | string | Yes | Must be tiered |
tiers_mode | string | Yes | graduated or volume |
tiers | array | Yes | Array of tier definitions |
Tier Modes
Graduated Pricing — Each tier's price applies only to units within that tier:
Example: 15,000 API calls
- First 1,000: Free (1,000 × $0.00)
- Next 9,000: $0.01 each (9,000 × $0.01 = $90)
- Next 5,000: $0.005 each (5,000 × $0.005 = $25)
Total: $115Volume Pricing — The applicable tier's price applies to ALL units:
Example: 15,000 API calls (falls in 10,001-100,000 tier)
- All 15,000: $0.005 each (15,000 × $0.005 = $75)
Total: $75Tier Structure
{
"up_to": 1000,
"flat_amount": 0,
"unit_amount": 100
}| Field | Type | Description |
|---|---|---|
up_to | integer or "inf" | Upper limit of this tier. Use "inf" for the final tier |
flat_amount | integer | Flat fee for this tier (in cents) |
unit_amount | integer | Per-unit price for this tier (in cents) |
The final tier must have "up_to": "inf" to handle any quantity.
Sub-Cent Pricing
For high-volume usage pricing, you may need sub-cent amounts:
{
"id": "compute_hourly",
"amount": 0.684,
"currency": "usd",
"interval": "month",
"usage_type": "metered"
}OmniBase supports decimal amounts for precise pricing.
Free Tiers
Unlike Stripe, OmniBase supports $0 prices:
{
"id": "free",
"amount": 0,
"currency": "usd",
"interval": "month",
"ui": {
"price_display": {
"custom_text": "Free"
}
}
}Free prices are stored in PostgreSQL and bypass Stripe checkout.
Enterprise Pricing
Template-Based Pricing
Create discount templates for enterprise tiers:
{
"id": "pro_monthly_enterprise_tier1",
"amount": 4410,
"currency": "usd",
"interval": "month",
"public": false,
"enterprise_template": "tier1_10pct_off"
}Custom Per-Tenant Pricing
Create custom pricing for specific customers:
{
"id": "pro_monthly_acme",
"amount": 3920,
"currency": "usd",
"interval": "month",
"public": false,
"enterprise_id": "acme_corp"
}See Enterprise Pricing for details.
UI Configuration
Product UI
{
"ui": {
"display_name": "Pro",
"tagline": "For growing teams",
"features": [
"Unlimited projects",
"Priority support",
"Advanced analytics"
],
"badge": "Most Popular",
"cta_text": "Upgrade to Pro",
"highlighted": true,
"sort_order": 3
}
}| Field | Type | Description |
|---|---|---|
display_name | string | Display name in UI |
tagline | string | Short description/tagline |
features | string[] | List of product features |
badge | string | Badge text ("Most Popular", "Best Value", etc.) |
cta_text | string | Call-to-action button text |
highlighted | boolean | Highlight this product in pricing table |
sort_order | integer | Display order (lower = first) |
Price UI
{
"ui": {
"display_name": "Monthly",
"billing_period": "per month",
"price_display": {
"custom_text": "Custom",
"show_currency": true,
"suffix": "/month"
},
"features": [
"Everything in Free",
"API access"
],
"limits": [
{
"text": "0.75% transaction fee",
"value": 0.75,
"unit": "percent"
},
{
"text": "Unlimited instances",
"value": null,
"unit": "instances"
}
]
}
}| Field | Type | Description |
|---|---|---|
display_name | string | Price tier name |
billing_period | string | Human-readable period ("per month", "Forever") |
price_display | object | Custom price display options |
features | string[] | Features specific to this price |
limits | array | Usage limits for this price |
Price Display Options
{
"price_display": {
"custom_text": "Free",
"show_currency": false,
"suffix": "/month"
}
}| Field | Type | Description |
|---|---|---|
custom_text | string | Custom text instead of price ("Free", "Custom") |
show_currency | boolean | Whether to show currency symbol |
suffix | string | Text after price ("/month", "/year") |
Price Limits
{
"limits": [
{
"text": "2 instances",
"value": 2,
"unit": "instances"
},
{
"text": "2.5% transaction fee",
"value": 2.5,
"unit": "percent"
}
]
}Complete Example
{
"$schema": "https://dashboard.omnibase.tech/api/stripe-config.schema.json",
"version": "1.0.0",
"products": [
{
"id": "free",
"name": "Free Plan",
"description": "Get started with OmniBase",
"type": "service",
"prices": [
{
"id": "free",
"amount": 0,
"currency": "usd",
"interval": "month",
"public": true,
"ui": {
"display_name": "Free",
"billing_period": "Forever",
"price_display": { "custom_text": "Free" },
"limits": [
{ "text": "2 instances", "value": 2, "unit": "instances" },
{ "text": "2.5% transaction fee", "value": 2.5, "unit": "percent" }
]
}
}
],
"ui": {
"display_name": "Free",
"tagline": "For personal projects",
"sort_order": 1
}
},
{
"id": "starter",
"name": "Starter Plan",
"type": "service",
"prices": [
{
"id": "starter_monthly",
"amount": 1900,
"currency": "usd",
"interval": "month",
"public": true,
"default": true
}
],
"ui": {
"display_name": "Starter",
"tagline": "For small teams",
"sort_order": 2
}
},
{
"id": "pro",
"name": "Pro Plan",
"type": "service",
"prices": [
{
"id": "pro_monthly",
"amount": 4900,
"currency": "usd",
"interval": "month",
"public": true,
"default": true
},
{
"id": "pro_yearly",
"amount": 49000,
"currency": "usd",
"interval": "year",
"public": true
}
],
"ui": {
"display_name": "Pro",
"tagline": "For growing teams",
"badge": "Most Popular",
"highlighted": true,
"sort_order": 3
}
},
{
"id": "enterprise",
"name": "Enterprise",
"type": "service",
"prices": [
{
"id": "enterprise",
"amount": 0,
"currency": "usd",
"public": true,
"ui": {
"price_display": { "custom_text": "Custom" }
}
}
],
"ui": {
"display_name": "Enterprise",
"tagline": "For large organizations",
"cta_text": "Contact Sales",
"sort_order": 4
}
}
]
}API Usage
Get Price Details
import { V1StripeApi } from '@omnibase/core-js';
const stripeApi = new V1StripeApi(config);
// Get price by config ID
const { data } = await stripeApi.getPriceByID({ priceId: 'pro_monthly' });
console.log(data.price.amount); // 4900
console.log(data.product.name); // "Pro Plan"Calculate Cost
// Calculate cost for a quantity
const { data } = await stripeApi.calculatePriceCost({
priceId: 'api_calls_tiered',
calculatePriceCostRequest: { quantity: 15000 },
});
console.log(data.cost_cents); // Cost in cents
console.log(data.effective_unit_cost_cents); // Average cost per unit
console.log(data.tiers_mode); // "graduated" or "volume"Get All Products
const { data: stripeConfig } = await stripeApi.getStripeConfig();
// Filter to public products
const publicProducts = stripeConfig.products.filter(p =>
p.prices.some(price => price.public !== false)
);Related
- Configuration Guide — Full configuration reference
- Metering — Usage-based pricing with meters
- Enterprise Pricing — Custom pricing for enterprises
- Checkout & Portal — Creating checkout sessions