Commet
  • Pricing
Log InTry out

Commet API 2026-06-07 and SDKs v6

Unified, nested response shapes, new Payouts and Test Clock APIs, and two new lookups. One coordinated release across the REST API (version 2026-06-07) and every SDK — Node, Python, Go, Java, and PHP at 6.0.0.

D
Decker Urbano·@0xDecker·June 9, 2026
Changelog

Use this pre-built prompt to migrate to API 2026-06-07 and SDK v6 from any version with AI assistants.

This release ships together to the REST API (version 2026-06-07) and all five SDKs (Node, Python, Go, Java, PHP at 6.0.0): new Payouts and Test Clock APIs, two new lookups, and a big cleanup of request/response shapes — unified, nested objects instead of flat field soup.

API response shapes are now unified and nested

The biggest change. Subscription and Plan responses used to be several types with dozens of flat fields. They're now one type each, with nested objects.

A subscription response, before and after 2026-06-07:

// pinned before 2026-06-07 (flat)
{
  "id": "sub_xxx",
  "planId": "pln_abc",
  "planName": "Pro",
  "currentPeriodStart": "2026-06-01T00:00:00Z",
  "currentPeriodEnd": "2026-07-01T00:00:00Z",
  "discountType": "percentage",
  "discountValue": 20
}

// 2026-06-07 (nested)
{
  "id": "sub_xxx",
  "plan": { "id": "pln_abc", "name": "Pro", "basePrice": 2900 },
  "currentPeriod": {
    "start": "2026-06-01T00:00:00Z",
    "end": "2026-07-01T00:00:00Z",
    "daysRemaining": 12
  },
  "discount": { "type": "percentage", "value": 20 }
}

The full set of 2026-06-07 shape changes (all version-gated — pin earlier to keep the old shape):

ResourceChange
SubscriptionOne unified type. plan, currentPeriod, discount are now nested objects (were flat planId / planName / currentPeriodStart / currentPeriodEnd / discount*).
PlanOne unified type (was PlanListItem / PlanDetail). A feature's overage is nested under overage (was flat overageEnabled / overageUnitPrice).
Subscription / Feature usageoverage → overageQuantity (in features[].usage).
Plan priceIntro offer nested under introOffer (was flat introOfferEnabled / introOfferDiscountType / introOfferDiscountValue / introOfferDurationCycles).
CustomerbillingEmail → email (requests and responses, including batch create).
Promo codeisActive → active.
Usage checkresponse feature → featureCode.

New resource: Payouts

Manage payout bank accounts, request payouts, and complete account verification — programmatically for the first time.

await commet.payouts.addBankAccount({
  accountNumber: "000123456789",
  accountHolderName: "Acme Inc.",
  routingNumber: "110000000",
  accountType: "checking",
  setDefault: true,
});

// amount is in cents, minimum 1000 ($10)
await commet.payouts.request({
  amount: 50000,
  description: "Weekly payout",
});

await commet.payouts.completeVerification({
  email: "owner@acme.com",
  businessType: "company",
  businessUrl: "https://acme.com",
  documentUrl: "https://files.acme.com/incorporation.pdf",
  bank: { accountNumber: "000123456789", routingNumber: "110000000" },
  company: { name: "Acme Inc.", taxId: "12-3456789" },
});

request() rejects amounts below 1000 cents. Pass either individual or company to completeVerification() depending on businessType.

REST: POST /payouts/bank-accounts · POST /payouts · POST /payouts/verification

New resource: Test Clock

Simulate the passage of time in sandbox to test renewals, trials, and billing cycles without waiting.

Sandbox only. Test Clock methods throw against live organizations.

await commet.testClock.get();

await commet.testClock.advance({ advanceDays: 30 });
// or jump to an exact moment
await commet.testClock.advance({ frozenTime: "2026-07-01T00:00:00Z" });

await commet.testClock.processBilling();

advance() moves the clock forward. processBilling() runs the billing engine against the current clock time so you can assert invoices and renewals immediately.

REST: GET /test-clock · POST /test-clock · POST /test-clock/process-billing

New methods on existing resources

subscriptions.get() fetches a single subscription by id — distinct from getActive(), which resolves the active subscription for a customer.

const sub = await commet.subscriptions.get({ id: "sub_xxx" });

REST: GET /subscriptions/{id}

plans.setRegionalPricing() configures local-currency pricing for a plan in one call.

await commet.plans.setRegionalPricing({
  id: "pln_abc",
  currency: "BRL",
  exchangeRate: 5.2,
  prices: [{ priceId: "price_xxx", price: 14900 }],
  features: [{ featureId: "feat_xxx", overageUnitPrice: 50 }],
  introOffers: [{ priceId: "price_xxx", discountType: "percentage", discountValue: 20, durationCycles: 3 }],
});

REST: PUT /plans/{id}/regional

SDK breaking changes

The nested shapes above land in the SDKs as v6 breaking changes. The examples are TypeScript; each SDK uses its own idiomatic naming.

Intro offers on subscriptions.create()

customIntroOffer is now introOffer, a nested object. The flat fields introOfferEndsAt, introOfferDiscountType, and introOfferDiscountValue were removed from the subscription object.

// v5
await commet.subscriptions.create({
  customerId: userId,
  planCode: "pro",
  customIntroOffer: {
    introOfferDiscountType: "percentage",
    introOfferDiscountValue: 50,
    introOfferEndsAt: "2026-09-01T00:00:00Z",
  },
});

// v6
await commet.subscriptions.create({
  customerId: userId,
  planCode: "pro",
  introOffer: {
    discountType: "percentage",
    discountValue: 50,
    durationCycles: 3,
  },
});

Customer email: billingEmail → email

The field is email on create/update params and on the customer object.

// v5
await commet.customers.create({ id: "user_123", billingEmail: "user@co.com" });
const email = customer.billingEmail;

// v6
await commet.customers.create({ id: "user_123", email: "user@co.com" });
const email = customer.email;

Exported type names

CreateParams and UpdateParams are now CreateCustomerParams and UpdateCustomerParams. CreateAddonParams is a single interface — it was previously a union.

// v5
import type { CreateParams, UpdateParams } from "@commet/node";

// v6
import type { CreateCustomerParams, UpdateCustomerParams } from "@commet/node";

quota.add() / quota.remove() require count

count no longer defaults to 1. Pass it explicitly.

// v5
await commet.quota.add({ customerId: userId, featureCode: "seats" });

// v6
await commet.quota.add({ customerId: userId, featureCode: "seats", count: 1 });

Calling the API directly

Set the version with the commet-version header. New endpoints are additive — they work on any pinned version:

  • POST /payouts/bank-accounts · POST /payouts · POST /payouts/verification
  • GET /test-clock · POST /test-clock · POST /test-clock/process-billing
  • GET /subscriptions/{id}
  • PUT /plans/{id}/regional
curl https://commet.co/api/v1/subscriptions/sub_xxx \
  -H "Authorization: Bearer ck_..." \
  -H "commet-version: 2026-06-07"

Request 2026-06-07 to get the nested shapes; omit it or pin earlier and the API transforms responses back to the flat shape your integration already expects.

Every language, same API

Node, Python, Go, Java, and PHP all ship v6 with the same resources and methods. Each SDK follows its language's idiomatic naming — TypeScript, PHP, and Java are camelCase, Python is snake_case, and Go uses exported PascalCase fields.

npm install @commet/node@6
pip install commet-sdk==6.0.0
go get github.com/commet-labs/commet-go/v6
composer require commet/commet-php:^6.0
implementation("co.commet:commet-java:6.0.0") // Gradle

For Go, the major version is now part of the import path (/v6).

Every API version ever released still works. From v1 to v6, every version is accepted. The shape changes above apply when you request 2026-06-07 — pin an earlier version with the commet-version header and the API keeps returning the previous (flat) shape, derived automatically. You migrate on your own schedule.

Visit the API versioning docs to see how version pinning works, or the SDK reference for the full v6 surface.

Developers

  • Documentation
  • Templates
  • GitHub

Frameworks

  • Next.js
  • Remix
  • Nuxt
  • SvelteKit
  • Astro
  • Express
  • Hono
  • Django
  • FastAPI

Resources

  • Blog
  • Changelog
  • Pricing

AI

  • Agents
  • MCP Server
  • Agent Skills
  • Claude Code
  • Codex
  • Cursor

Learn

  • Guides
  • Glossary
  • Solutions
  • Billing for AI Models
  • Comparison

Compare

  • Stripe alternative
  • Orb alternative
  • Recurly alternative
  • Paddle alternative
  • Chargebee alternative
  • Lago alternative

Company

  • About
  • Open Source
  • Terms
  • Privacy

Countries

  • Mexico
  • Argentina
  • Colombia
  • Chile
  • Peru
  • Ecuador
  • Uruguay
  • Paraguay
  • Bolivia
  • Panama
  • El Salvador
  • Brazil
System statusXLinkedInGitHub