Subscription renewal webhook triggers twice for same contract creating billing errors

We’re experiencing critical billing errors because the Subscription API webhook fires two identical renewal events for the same contract within minutes of each other. This causes our billing system to generate duplicate invoices, creating significant reconciliation issues.

Here’s the duplicate payload we receive:

{
  "eventId": "evt_12345",
  "contractId": "CNT-2025-001",
  "eventType": "subscription_renewed"
}

Both webhooks have the same eventId and contractId but arrive 3-5 minutes apart. The webhook idempotency design seems flawed - shouldn’t the eventId prevent duplicate processing? Our event payload design doesn’t include enough metadata to detect duplicates reliably, and the contract renewal workflow appears to be triggering the webhook multiple times. How do we ensure webhook idempotency for subscription events?

We’re already checking eventId for duplicates, but we still occasionally see different eventIds for what appears to be the same renewal. Is there additional metadata in the event payload that we should be using for more reliable deduplication?

For subscription webhooks in ICS 2022, you should also check the webhook configuration’s event filters. Make sure you’re only subscribed to the final renewal event, not intermediate status changes. The contract renewal workflow has multiple stages, and by default webhooks fire for each stage transition.

Different eventIds for the same renewal suggests multiple webhook triggers from the workflow. You need to use a combination of contractId and renewal_date as your deduplication key, not just eventId. The eventId is unique per webhook delivery attempt, not per business event.