Skip to main content
Products are the line items inside a contract. Each product defines what is being charged, how it is scheduled, and what pricing model applies.

Base fields

FieldTypeRequiredDescription
displayNamestringYesLabel shown on invoices
schedulingobjectYesWhen and how often the product bills
pricingobjectYesThe pricing model
catalogProductIdstringNoLinks to a catalog product — required for all usage-based pricing
descriptionstringNoInternal description
paymentTermstringNoprepayment or postpayment — defaults based on pricing type
isCalendarAlignedbooleanNoAlign invoice periods to calendar months (default: false)
commitmentobjectNoMinimum committed units — see Commitment
productErpIdstringNoERP identifier for accounting sync

Scheduling

{
  "scheduling": {
    "billingDay": 1,
    "duration": { "unit": "MONTH", "value": 1 }
  }
}
FieldTypeDescription
billingDayinteger (1–31)Day of month the billing period starts. Defaults to 1. Should match the contract start date to avoid proration.
duration.unitstringDAY, WEEK, MONTH, or YEAR
duration.valueinteger (0–1000)Number of units per billing period

Pricing models

ONE_TIME

A single charge billed when the contract starts. Duration must be 1 day.
{
  "pricing": {
    "type": "ONE_TIME",
    "price": 500.00
  }
}

SUBSCRIPTION

Recurring fixed fee. The subscriptionCadence controls how often the charge accumulates within the billing period.
{
  "pricing": {
    "type": "SUBSCRIPTION",
    "price": 99.00,
    "subscriptionCadence": { "unit": "MONTH", "value": 1 }
  }
}
A product with a 3-month duration and monthly subscriptionCadence bills 3× 99=99 = 297 per invoice.

CONTRACT_TERMS

A total contract fee, optionally split into installments at specific dates.
{
  "pricing": {
    "type": "CONTRACT_TERMS",
    "price": 12000.00,
    "installments": [
      { "installmentDate": "2026-01-01T00:00:00Z", "amount": 6000.00 },
      { "installmentDate": "2026-07-01T00:00:00Z", "amount": 6000.00 }
    ]
  }
}

PER_UNIT

Pay-as-you-go. Requires catalogProductId.
{
  "pricing": {
    "type": "PER_UNIT",
    "price": 0.002,
    "chunkSize": 1000,
    "baseAmount": 500,
    "usageReset": 1
  }
}
FieldTypeDescription
pricenumberPrice per unit (or per chunk if chunkSize is set)
chunkSizenumberBilling granularity — usage is rounded up to the nearest chunk
baseAmountnumberFree units included before metered charges begin
usageResetnumberReset accumulated usage every N months — must be 1, 2, 3, 6, or 12

TIERED

Volume-based pricing with different rates or flat fees per tier. Requires catalogProductId.
{
  "pricing": {
    "type": "TIERED",
    "tiers": [
      { "fromInclusive": 0, "toExclusive": 1000, "rate": 0.10 },
      { "fromInclusive": 1000, "toExclusive": 10000, "rate": 0.07 },
      { "fromInclusive": 10000, "rate": 0.04 }
    ],
    "subscriptionCadence": { "unit": "MONTH", "value": 1 },
    "autoUpgrade": false,
    "prorate": false,
    "baseAmount": 0,
    "usageReset": 1
  }
}
Tier fieldTypeDescription
fromInclusivenumberLower bound of the tier (inclusive)
toExclusivenumber | nullUpper bound (exclusive). Omit or null for the final open-ended tier
ratenumberPer-unit rate in this tier
flatFeenumberFlat fee charged when usage enters this tier
packageSizenumberUnits grouped into a package for billing
Tiered optionTypeDescription
subscriptionCadenceobjectMakes tiered pricing subscription-based (charges flat fees on a cadence)
autoUpgradebooleanAutomatically move to the next tier in the following billing period
proratebooleanProrate flat fees based on when the tier was entered mid-period
isRevSharebooleanRevenue share mode — rate is treated as a percentage
baseAmountnumberFree units before tiered charges apply
usageResetnumberReset usage every N months: 1, 2, 3, 6, or 12

Commitment

Attach a minimum committed usage to any usage-based product.
{
  "commitment": {
    "units": 10000,
    "price": 500.00,
    "overageStrategy": "IGNORE"
  }
}
FieldTypeDescription
unitsnumberCommitted usage units
pricenumberPrice charged for the committed amount
overageStrategystringWhat happens when usage exceeds the commitment — IGNORE (default)
schedulingobjectFor recurring commitments — same shape as product scheduling

Product groups

Products can be grouped to share ERP settings, commitments, and a combined line item on invoices.
{
  "productGroups": [
    {
      "displayName": "Platform Bundle",
      "products": [
        {
          "displayName": "Base Subscription",
          "scheduling": { "billingDay": 1, "duration": { "unit": "MONTH", "value": 1 } },
          "pricing": { "type": "SUBSCRIPTION", "price": 500.00, "subscriptionCadence": { "unit": "MONTH", "value": 1 } }
        },
        {
          "displayName": "API Usage",
          "scheduling": { "billingDay": 1, "duration": { "unit": "MONTH", "value": 1 } },
          "pricing": { "type": "PER_UNIT", "price": 0.001, "chunkSize": 100 },
          "catalogProductId": "cat_abc123"
        }
      ]
    }
  ]
}
Products inside a productGroup cannot use isCalendarAligned. Group-level settings like commitment and ERP fields apply to all products in the group.