Install the Commet v7 to v8 migration skill so your coding agent can update SDK calls, API pins, CLI commands, and webhook versions.
npx skills add commet-labs/skills --skill migrate-commet-v7-to-v8If you only need to upgrade an existing integration, use the migration skill above. Read on to understand what changed and how the new pieces work together.
Pricing defines the amount and package a customer can buy. Offers define how that price changes over time. They stay separate in the catalog and come together when the customer subscribes.
Pricing
Start with one Pro plan. It can keep its standard monthly price, show a local price in Argentina, and offer a selectable launch package without duplicating the plan.
- Currency Pricing sets a value for a currency.
- Markets group countries that should see a specific price and currency.
- Selectable variants represent packages a customer can deliberately choose while inheriting the base price everywhere else.
A Market is reusable across prices and does not require a plan when you create it:
const argentina = await commet.pricing.createMarketGroup({
name: 'Argentina',
countryCodes: ['AR'],
})A selectable variant links back to its base through inheritsFromPriceId. Pass its public priceId when the customer chooses that package; omit it when Commet should resolve the normal price from the billing country.
The subscription remembers that choice. Future renewals use the current catalog value for the selected package. Once the price is selected, an Offer can change its terms over time without duplicating the pricing configuration.
Offers
Pricing answers “how much?” An Offer answers “how does that amount change over time?” It can add a trial, a discount for several billing cycles, or a fixed introductory price without creating another package.
| Purpose | Selection | Phases |
|---|---|---|
introductory | Automatic from one base plan price | Optional free trial, then percentage or amount off |
promotional | Explicit offerId or a Promo Code | Percentage, amount off, or fixed price across ordered phases |
const launchOffer = await commet.offers.create({
name: 'Launch pricing',
purpose: 'promotional',
planPriceIds: ['pp_pro_monthly'],
phases: [
{ type: 'percentage', durationCycles: 2, percentage: 5000 },
{ type: 'percentage', durationCycles: 2, percentage: 2500 },
],
})When a customer accepts an Offer, Commet saves those phases as their agreed terms. Editing or archiving the catalog Offer changes future applications, not the deal an existing customer already accepted.
Combine them at subscription creation
The subscription is where both decisions meet: the price selects the package and the Offer defines its promotional schedule. In the API, priceId and offerId make those choices explicit.
await commet.subscriptions.create({
customerId: 'user_123',
planCode: 'pro',
priceId: 'pp_pro_launch',
offerId: 'ofr_launch_2026',
})Price variants inherit Offer eligibility from their base price. If you omit offerId, Commet keeps automatic Introductory Offer selection. An explicit Promotional offerId cannot be combined with promoCode, customTrialDays, or skipTrial: true.
That explicit combination also gives each experiment cohort one stable billing outcome.
A/B tests
For example, the control group can receive the standard monthly package while the variant receives a launch package with a Promotional Offer. Assign each customer to a stable cohort in your application or experimentation system, then pass the selected terms:
const selection =
experimentVariant === 'control'
? { priceId: 'pp_pro_monthly' }
: {
priceId: 'pp_pro_launch',
offerId: 'ofr_launch_2026',
}
await commet.subscriptions.create({
customerId: 'user_123',
planCode: 'pro',
...selection,
})Commet bills and renews the selected terms. Your application still owns cohort assignment and conversion measurement.
All v8 changes
Pricing, Offers, and their explicit composition shipped with API version 2026-07-24, SDK v8, and CLI v4. The same release aligns the rest of the public contract around direct resource results, exact request alternatives, and the current usage API.
Existing integrations keep working until you upgrade the SDK, change an explicit commet-version header, update an organization pin, or repin a webhook endpoint.
| v7 | v8 |
|---|---|
| Singular results used SDK response wrappers | Singular operations return the resource directly |
featureAccess.canUse(...) | usage.check(...) |
usage.trackEvent(...) | usage.track(...) |
Raw usage field feature | featureCode |
| SDK-generated event identifier | Optional caller-owned eventId |
| Inline introductory and promo discount fields | First-class Offers and Promo Codes that reference Promotional Offers |
| Default plan price only | Optional selectable priceId, reusable Markets, and inherited price variants |
| Broad request and response shapes | Exact discriminated unions from the API contract |
feature-access can-use and usage track --feature in the CLI | usage check and usage track --feature-code |
List methods still return { object, data, hasMore, nextCursor }. Authentication, request idempotency, webhook signature verification, and framework helpers remain ergonomic SDK capabilities.
Upgrade the SDK
# Node.js
npm install @commet/node@^8
# Python
pip install "commet-sdk>=8,<9"
# Go
go get github.com/commet-labs/commet-go/v8
# PHP
composer require commet/commet-php:^8.0
# Java
# co.commet:commet-java:8.0.0Remove singular response wrappers
// v7
const { data: customer } = await commet.customers.create({
id: 'user_123',
email: 'user@example.com',
})
// v8
const customer = await commet.customers.create({
id: 'user_123',
email: 'user@example.com',
})Keep data for list operations:
const { data: customers, hasMore, nextCursor } = await commet.customers.list()Update usage
const availability = await commet.usage.check({
customerId: 'user_123',
featureCode: 'api_calls',
})
const event = await commet.usage.track({
customerId: 'user_123',
featureCode: 'api_calls',
value: 1,
eventId: 'request_01JXYZ',
})eventId identifies the business event and makes retries safe. Transport idempotency remains a request option and maps to the Idempotency-Key header.
Upgrade the CLI
CLI v4 adds Offers, pricing Market Groups, selectable price variants, Offer-aware subscription flows, and the current usage commands.
npm install -g commet@^4
commet offers list
commet pricing list-market-groups
commet usage check --customer-id customer_123 --feature-code api_callsUse --feature-code instead of --feature when tracking usage, and pass the caller-owned event identifier with --event-id. usage check replaces feature-access can-use. Promo Code commands now reference a Promotional Offer with --offer-id.
Use exact request alternatives
SDK v8 models mutually exclusive request shapes as discriminated unions:
- Subscription creation uses exactly one of
planIdorplanCode. - Quota mutations identify the customer with exactly one of
customerIdorexternalId. - Add-on fields must match the selected
consumptionModel. - Portal sessions use exactly one of
emailorcustomerId. - Payout verification uses either the individual or company payload.
- Test Clock updates use either
advanceDaysorfrozenTime.
Direct API integrations must also move legacy /manage operations to their canonical resource paths, use PATCH for partial updates, and send Idempotency-Key for idempotent writes. SDK v8 already uses these routes.
Verify version boundaries
- Search for an explicit
commet-versionheader and decide whether it should move to2026-07-24. - Check the organization's API version in Settings → Development → API Versions.
- Repin webhook endpoints separately when you are ready for v8 webhook payloads.
- Exercise create, retrieve, list, usage check, usage track, and webhook verification in sandbox.
Runtime behavior that did not change
- Existing Currency Pricing remains valid; Markets are an additive pricing layer.
- Omitting
priceIdkeeps default price resolution. - Archiving a selected price hides it from new selection but does not break existing subscriptions.
- Accepted Offer phases remain immutable snapshots.
- v7 traffic remains compatible through the API-version engine.
See Offers, Introductory Offers, Promotional Offers, Regional pricing, and API versioning.