| name | commet |
| description | Integrate Commet billing and payments into any application. Use when working with @commet/node, @commet/next, @commet/better-auth, the Commet CLI, or building billing features like subscriptions, usage tracking, seat management, checkout, customer portal, webhooks, feature gating, or payment flows. Triggers on imports from "@commet/node", "@commet/next", "@commet/better-auth", commet SDK usage, billing integration tasks, or mentions of Commet. |
| license | MIT |
| metadata | {"author":"commet","version":"1.0.0","homepage":"https://commet.co","source":"https://github.com/commet-labs/commet-skills"} |
| inputs | {"COMMET_API_KEY":{"required":true},"COMMET_WEBHOOK_SECRET":{"required":false}} |
| references | ["references/sdk.md","references/nextjs.md","references/ai-sdk.md","references/better-auth.md","references/billing-concepts.md"] |
Commet Integration
Commet is an all-in-one billing and payments platform. Merchant of Record handling taxes, compliance, refunds, and payouts. Integrate with a few lines of code.
Packages
| Package | Purpose | Install |
|---|
@commet/node | Core SDK - customers, subscriptions, usage, seats, features, portal, webhooks | npm i @commet/node |
@commet/next | Next.js helpers - webhook handler, customer portal, pricing markdown | npm i @commet/next |
@commet/ai-sdk | Vercel AI SDK middleware - automatic AI token usage billing | npm i @commet/ai-sdk |
@commet/better-auth | Better Auth plugin - auto customer sync, auth-scoped billing | npm i @commet/better-auth |
commet | CLI - login, link, config push/pull, webhook forwarding, scaffold projects from templates | npm install -g commet |
Quick Start
import { Commet } from "@commet/node";
const commet = new Commet({
apiKey: process.env.COMMET_API_KEY!,
});
One URL, one key: the organization behind the API key decides sandbox vs live. A sandbox organization's key only touches sandbox data; a live organization's key touches live data. There is no environment option.
Integration Workflow
- Setup:
commet login -> commet link -> commet pull (syncs your billing config into commet.config.ts)
- Create customer: On user signup, create Commet customer with
id = your user ID
- Create subscription: Call
subscriptions.create() -> redirect to checkoutUrl
- Check state: Query
subscriptions.getActive() to check subscription status (preferred over webhooks)
- Track usage:
usage.track() for metered features, seats.add/remove/set() for seats
- Feature gating:
featureAccess.get(), featureAccess.canUse(), featureAccess.list()
- Customer portal:
portal.getUrl() -> redirect for self-service billing management
SDK Reference
See references/sdk.md for the complete API surface of @commet/node.
Next.js Integration
See references/nextjs.md for @commet/next webhook handlers, customer portal routes, and pricing markdown.
AI SDK Integration
See references/ai-sdk.md for @commet/ai-sdk middleware that auto-tracks AI token usage for billing.
Better Auth Integration
See references/better-auth.md for the @commet/better-auth plugin that auto-syncs customers and provides auth-scoped billing endpoints.
Billing Concepts
See references/billing-concepts.md for plan structure, feature types, consumption models, and charging behavior.
Key Patterns
Query-first, webhooks optional
Always query subscription/feature state directly with the SDK instead of relying on webhooks to sync state. The recommended pattern is to call subscriptions.getActive(), featureAccess.get(), or featureAccess.list() when you need to know a customer's status. Webhooks are useful for background tasks (sending emails, provisioning resources) but should never be the source of truth for access control.
const { data: sub } = await commet.subscriptions.getActive({ customerId: "user_123" });
if (sub?.status === "active") { }
const { data } = await commet.featureAccess.get({ code: "advanced_analytics", customerId: "user_123" });
if (!data?.allowed) { }
Customer identification
Always use customerId (your user/org ID) to identify customers. The SDK accepts both your own IDs and Commet's cus_xxx IDs.
Idempotency
All POST requests auto-generate idempotency keys. For critical operations, pass explicit keys:
await commet.usage.track({
customerId: "user_123",
feature: "api_calls",
idempotencyKey: `req_${requestId}`,
});
Error handling
import { CommetAPIError, CommetValidationError } from "@commet/node";
try {
await commet.subscriptions.create({ ... });
} catch (error) {
if (error instanceof CommetValidationError) {
console.log(error.validationErrors);
}
if (error instanceof CommetAPIError) {
console.log(error.statusCode, error.code);
}
}
Environment variables
COMMET_API_KEY=ck_xxx # API key from dashboard - the key's organization decides sandbox vs live
COMMET_WEBHOOK_SECRET=whsec_xxx # Optional - webhook secret for signature verification