mcpField
S
stigg-webhooks

stigg-webhooks

github.com/stiggioDevelopment2118 installsUpdated 1w ago
Repository

About stigg-webhooks

stigg-webhooks is a skill for developers implementing handlers for Stigg webhook events. It covers endpoint setup, secret verification, deduplication, retries, and out-of-order delivery.

Key features

  1. 01Register webhook endpoints
  2. 02Verify events with a secret
  3. 03Deduplicate using messageId
  4. 04Handle retries and out-of-order events
  5. 05Cover subscription, trial, and credit events

Use cases

  1. 01Receive subscription lifecycle notifications
  2. 02Handle trial and credit changes
  3. 03Build idempotent event handlers

MCP support

The skill recommends querying Stigg event definitions through the Stigg docs MCP; the skill itself is not an MCP server.

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/stiggio/skills --skill stigg-webhooks

After installing, type/stigg-webhooksin Claude Code to confirm it loaded.

Bundled filesreferences/event-catalog.mdreferences/handler-patterns.md

Details

From the project README

Stigg Webhooks — Receive and Handle Events

Stigg notifies your app about changes via webhooks: subscription lifecycle, trial transitions, credit balance thresholds, auto-recharge attempts, entitlement-usage exceeded, and more. This skill covers receiving them — registering the endpoint, verifying authenticity, handling retries, and the payload envelope.

Before You Start

Per the umbrella stigg skill: search first. Webhook event names and payloads evolve. Use the Mintlify Stigg docs MCP — query_docs_filesystem_stigg against /documentation/native-integrations/webhooks/events.mdx and the per-event reference pages — to confirm the exact payload schema before authoring handler code.

Registering a Webhook

In the Stigg app: Settings → Integrations → Webhooks → + New webhook.

FieldNotes
Service nameHuman-friendly label (e.g. "Production webhooks", "Dev").
Endpoint URLYour handler — e.g. https://yourapp.com/api/stigg/webhooks. Must respond 2XX within 30 seconds or Stigg retries.
Events to sendPick from the catalog (subscription, trial, credits, entitlement, customer, etc.).

Created webhooks activate immediately. Use Send test event (⋮ menu on a specific event) to verify your handler before wiring real events.

Authenticity — Verify the Secret

Every webhook event carries a header:

Stigg-Webhooks-Secret: <secret>

Compare this header value to the secret shown in the webhook's detail page. They must match.

HMAC signature support is on Stigg's roadmap. Today, verification is plain secret comparison — treat the secret like an API key (env var, never in source).

Payload Envelope

Every webhook event has a top-level shape (per-event details vary; verify the per-event page):

{
  "messageId": "msg_abc123",     // unique per event delivery — use for idempotency
  "type": "subscription.created", // event type
  "createdAt": "2026-01-15T10:30:00Z",
  "data": { /* event-specific payload */ }
}

The exact field names may vary slightly across event types — always confirm against the live event reference page (/documentation/native-integrations/webhooks/events.mdx and the per-event subpages).

Idempotency — De-Duplicate via messageId

Stigg may deliver the same event multiple times (retries, network, edge cases). Always:

  1. Read messageId from the payload.
  2. Check it against a deduplication store (Redis, DB row, idempotency table).
  3. If already processed, return 200 immediately — don't re-execute the handler.
  4. If new, process the event, then record messageId as processed.

Order Is NOT Guaranteed

Stigg does not guarantee delivery order. Your handlers must tolerate out-of-order events:

  • A subscription.canceled may arrive before the matching subscription.updated it followed in time.
  • A credit.balance.depleted may arrive after a follow-up grant has already been issued.

When order matters, fetch fresh state from the Stigg API rather than reconstructing it from the event stream.

Retry Behavior

If your endpoint returns non-2XX or times out (>30s), Stigg retries:

  1. 3 immediate retries (no backoff).
  2. 3 more retries every 30 seconds.

After 6 total failures the event is failed. Failed events are stored on Stigg's backend and can be resent on request (contact support; a self-service replay UI is on the roadmap). Stigg also actively monitors webhook delivery failures and reaches out when failure rates spike.

Always return 200 fast. Acknowledge receipt, then queue the work async. A handler that synchronously processes complex logic risks the 30-second timeout and unnecessary retries.

IP Allowlist

Webhook events originate from Stigg's IPs. At the time of writing: 18.119.35.43. The list may change — re-fetch from /documentation/native-integrations/webhooks/index.mdx before pinning.

Event Catalog (by domain)

The full event list lives at /documentation/native-integrations/webhooks/events.mdx. Re-fetch for the canonical set; below is a curated map by domain:

DomainCommon events
Customercustomer.created, customer.updated, customer.deleted, customer.payment_failed, payment_method.attached, payment_method.detached
Subscriptionsubscription.created, subscription.updated, subscription.canceled, subscription.creation_failed, subscription.expired_non_recurring, billing.month_ends_soon, subscription.spend_limit_exceeded
Trialtrial.started, trial.ends_soon (7 days before expiry), trial.expired, trial.converted
Entitlemententitlement.usage_exceeded, entitlements.updated
Credits — balancecredit.balance.low, credit.balance.depleted
Credits — grantscredit.grant.created, credit.grant.updated, credit.grant.depleted, credit.grant.expired, credit.grant.balance_low
Credits — auto-rechargeautomatic_recharge.operation.attempted, credits.automatic_recharge_limit_exceeded (80/90/100% of cap), automatic_recharge.configuration.changed
Promotional entitlementspromotional_entitlement.granted, promotional_entitlement.updated, promotional_entitlement.revoked, promotional_entitlement.expired, promotional_entitlement.ends_soon
Catalogplan.created, plan.updated_new_version_published, plan.deleted, addon.created, addon.updated_new_version_published, addon.deleted, feature.created, feature.updated, feature.deleted, coupon.created, coupon.updated, coupon.archived
Third-partythird_party_sync_failed

Exact event names may evolve — always re-confirm in the docs.

Handler Skeleton (Next.js App Router + Node)

// app/api/stigg/webhooks/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { redis } from '@/lib/redis';

const SECRET = process.env.STIGG_WEBHOOK_SECRET!;

export async function POST(req: NextRequest) {
  // 1. Verify the secret
  const headerSecret = req.headers.get('Stigg-Webhooks-Secret');
  if (headerSecret !== SECRET) {
    return NextResponse.json({ error: 'Invalid secret' }, { status: 401 });
  }

  const event = await req.json();
  const { messageId, type, data } = event;

  // 2. Idempotency
  const seen = await redis.set(
    `stigg:webhook:${messageId}`,
    '1',
    { NX: true, EX: 60 * 60 * 24 * 7 }, // 7-day window
  );
  if (!seen) {
    return NextResponse.json({ ok: true, dedup: true }); // already processed
  }

  // 3. Acknowledge fast — queue heavy work async
  await queue.enqueue({ type, data });
  return NextResponse.json({ ok: true });
}

Keep the handler under ~500ms; do all real work in a worker. Stigg only cares about the 2XX.

When NOT to Use This Skill

  • Calling Stigg APIs outbound (provisioning, gating, reporting) — use stigg-api, stigg-subscriptions, stigg-entitlements, stigg-credits.
  • Listening for frontend state changes (cache refresh after checkout, etc.) — that's an SDK concern, not a webhook concern.
  • Setting up the Stigg MCP server — use stigg-mcp.

Common Mistakes

MistakeFix
Skipping signature verificationThe Stigg-Webhooks-Secret header is the only authenticity check today. Compare it.
Processing synchronously in the handlerReturn 2XX fast; queue heavy work async. Sync processing risks the 30-second timeout.
Assuming event orderStigg explicitly does not guarantee order. Either tolerate out-of-order or fetch fresh state from the API.
No idempotency on messageIdStigg retries on failure — without dedup, you'll process the same event twice.
Trusting the IP allowlist as your only checkThe IP list can change. Use both IP allowlisting AND secret verification.
Returning 4XX for "I don't recognize this event"That triggers retries. Return 2XX and silently ignore unknown event types.
Hand-coding HMAC verificationHMAC support isn't shipped yet — a roadmap item. Today, plain secret comparison is the contract.
Not handling failed deliveryIf Stigg's 6-attempt schedule fails, events are stored but not auto-replayed. Contact support to resend; build operational alerting for sustained failures.
Treating webhooks as the only source of truthOrder isn't guaranteed and replay isn't self-service. Pair webhooks with periodic state reconciliation against the Stigg API.
Subscribing to "all events"Noisy, expensive on your side. Pick the events you actually act on.

Comments

Markdown supported