Back to Blog
Integrations & systems

How to Integrate Webhooks into a SaaS Without Lost Events or Duplicate Actions

A practical approach to SaaS webhook integration, from durable intake and retries to idempotency, monitoring, testing, and a limited rollout.

Published 5 min read

A customer changes their subscription in another system, but your SaaS never updates their access. Later, the same notification arrives again and triggers a duplicate adjustment. From the customer's perspective, both are product failures, regardless of where the integration broke. A dependable webhook integration must account for what happens before an event is accepted, while it is processed, and after something fails.

Webhooks notify one system when something changes in another. They can remove the need for constant polling, but the notification alone does not guarantee one-time delivery, correct ordering, or continuous availability on either side. The realistic goal is to preserve work that has not finished, prevent repeated business effects, and make exceptions visible enough to resolve.

Start with the event contract and ownership

Map one business workflow before building an endpoint. Which system owns the change? Which event does it send? How will your SaaS identify the affected customer and decide what to do? Name the source of truth. If an external system owns subscription status, its webhook may prompt your application to refresh that status rather than serve as the sole record of it.

Write down event types, stable identifiers, schema versions, and the expected result for each type. Treat “received” and “completed” as separate states: accepting a plan-change notification is not the same as updating access. Assign ownership for contract changes, failed deliveries, and data discrepancies. Otherwise, a failure queue may fill up without anyone knowing who should act.

Keep the first release narrow. Choose one event with an outcome you can verify, rather than wiring billing, permissions, and communications into a single callback. A limited scope makes retries safer and lets the team determine which step failed without replaying unrelated actions.

Acknowledge only after a durable handoff

At the receiving endpoint, authenticate the sender, perform essential validation, and persist the event before acknowledging it. Depending on the provider's contract, that may mean checking a signature against the raw request body and rejecting timestamps outside an acceptable window. Use HTTPS, protect signing secrets, and prepare a way to rotate them. Avoid logging entire payloads containing sensitive information for the sake of convenient debugging.

A separate worker can then perform the business operation. This keeps a slow internal dependency from delaying the response to the sender. If the event cannot be stored, do not acknowledge it as received; let the provider retry under its delivery policy. If reliable retries are not available, plan another recovery path, such as periodically comparing records through the provider's API where possible.

Maintain an intake record with the event identifier, source, customer or tenant scope, type, processing state, and attempt times. Store and retain only what the workflow needs. A successful endpoint response should mean “accepted for processing,” not “the downstream change definitely happened.” That distinction should also appear in operational dashboards and incident procedures.

Make retries safe at both the event and action level

Retries handle temporary network and service failures, but they also create duplicates. A sender might retry an event that your application processed because its acknowledgment was lost. Use a unique key based on the source and stable event ID, including tenant scope where needed. Check and record that key atomically so two workers cannot act on the same delivery at once.

Deduplicating deliveries is only part of the job. If processing grants access, creates a charge, or sends a notification, give that business effect its own idempotency rule. Do not mark an event complete before its effect is confirmed: a crash in between would conceal unfinished work. When several services or databases are involved, model intermediate states and provide a safe way to resume or reconcile them. A local transaction cannot make a distributed workflow automatically atomic.

Retry transient failures with increasing delays and a limit. An invalid signature or incompatible payload needs a different response from a temporarily unavailable dependency. Move persistent failures to a review state or dead-letter queue, retaining enough context to investigate and retry without repeating completed effects. If events can arrive out of order, compare object versions or check the current source-of-truth state before applying an older update.

Test failure paths and roll out gradually

The happy path is not a sufficient release test. Send duplicate, concurrent, late, and out-of-order events. Simulate a lost acknowledgment, storage failure, schema change, and secret rotation. Verify both the business outcome and the processing record. If your SaaS also sends webhooks, use a comparable approach on the outbound side: record the product change and intent to notify consistently, retry deliveries, and include stable event IDs so receivers can deduplicate.

In production, track received, pending, completed, and review-required events, along with the time it takes to finish processing. Alert on growing backlogs and persistent errors, and give someone responsibility for investigating them. Where feasible, periodically compare your SaaS state with the source of truth. Delivery metrics alone cannot prove that the underlying business records agree.

Begin with one event type and a small set of internal accounts or customers. Decide in advance how to pause processing, correct bad data, and replay safely. Expand only after the team can explain observed failures and recover from them without creating duplicate actions.

If you are planning this integration, Cibercoding can help review the event contract, operational controls, and scope of a first production release.

Topics

  • Webhooks
  • SaaS Integrations
  • Idempotency
  • Software Architecture
  • Operations