Commet
  • Pricing
Log InTry out
Introduction

Subscription Events

subscription.createdsubscription.activatedsubscription.canceledsubscription.updatedsubscription.plan_changed

Payment Events

payment.receivedpayment.failed

Invoice Events

invoice.created
DocumentationKnowledge BaseBuild with AIAPI ReferenceWebhooks

Introduction

Receive real-time notifications when events happen in your Commet account.

Webhooks let your application receive real-time HTTP notifications when events happen in Commet — like a subscription being activated, a payment failing, or an invoice being created.

How it works

  1. You register an endpoint URL in the Commet dashboard
  2. You select which events you want to receive
  3. When an event occurs, Commet sends a POST request to your URL with the event data

Payload structure

Every webhook delivers a JSON payload with this envelope:

{
  "event": "subscription.activated",
  "timestamp": "2026-03-25T14:30:00.000Z",
  "organizationId": "org_abc123",
  "data": {
    // Event-specific fields
  }
}
FieldTypeDescription
eventstringThe event type (e.g. subscription.activated)
timestampstringISO 8601 datetime when the event was emitted
organizationIdstringYour organization ID
dataobjectEvent-specific payload — see Webhook Events

Handling webhooks with Next.js

The @commet/next package provides a handler that verifies signatures and routes events automatically.

app/api/webhooks/commet/route.ts
import { Webhooks } from "@commet/next";

export const POST = Webhooks({
  webhookSecret: process.env.COMMET_WEBHOOK_SECRET!,

  onSubscriptionActivated: async (payload) => {
    // Grant access to your product
    await db.update(users)
      .set({ isPaid: true })
      .where(eq(users.id, payload.data.customerId));
  },

  onSubscriptionCanceled: async (payload) => {
    // Revoke access
    await db.update(users)
      .set({ isPaid: false })
      .where(eq(users.id, payload.data.customerId));
  },

  // Catch-all for events without a specific handler
  onPayload: async (payload) => {
    console.log(`Received: ${payload.event}`);
  },
});

Verifying signatures manually

If you're not using @commet/next, verify the HMAC-SHA256 signature yourself using @commet/node:

import { Commet } from "@commet/node";

const commet = new Commet({ apiKey: process.env.COMMET_API_KEY! });

export async function POST(request: Request) {
  const rawBody = await request.text();
  const signature = request.headers.get("x-commet-signature");

  const payload = commet.webhooks.verifyAndParse({
    rawBody,
    signature,
    secret: process.env.COMMET_WEBHOOK_SECRET!,
  });

  if (!payload) {
    return new Response("Invalid signature", { status: 403 });
  }

  // Handle the event
  switch (payload.event) {
    case "subscription.activated":
      // Grant access
      break;
    case "subscription.canceled":
      // Revoke access
      break;
  }

  return new Response("OK", { status: 200 });
}

Headers

Commet sends these headers with every webhook request:

HeaderDescription
X-Commet-SignatureHMAC-SHA256 hex signature of the raw body
X-Commet-EventThe event type (e.g. subscription.activated)
X-Commet-TimestampISO 8601 datetime when the event was emitted
Content-Typeapplication/json

Retry policy

If your endpoint returns a non-2xx status or times out (10 seconds), Commet retries with exponential backoff:

AttemptDelay
1st retry1 minute
2nd retry5 minutes
3rd retry15 minutes
4th retry30 minutes
5th retry1 hour
6th retry2 hours
7th retry4 hours
8th retry6 hours

After 8 failed attempts, the delivery is marked as failed. You can monitor delivery status in the Commet dashboard.

Related

  • Webhook Events — all events and their payloads

How is this guide?

subscription.created

Fired when a new subscription is created

On this page

How it works
Payload structure
Handling webhooks with Next.js
Verifying signatures manually
Headers
Retry policy
Related