Skip to main content

Resend or reconcile: recovering a signature webhook your endpoint missed

· 4 min read
IgniSign Team
IgniSign Team

Your product embeds a signature step, and your backend waits for IgniSign's webhook to move the flow forward. Then a deploy goes wrong, or a TLS certificate expires on your server, and the endpoint answers with errors for twenty minutes. Users kept signing during that window. The question for the integrating developer is simple: how does your backend catch up on the events it missed? There are two answers, and they do different jobs.

What IgniSign gives you​

Webhooks are configured per topic, and each delivery carries a verification token your handler should check. Every event sent to your endpoint is recorded in the webhook event log, where you can see what was sent and resend it manually.

One point matters for this decision: if your endpoint does not accept an event when it is sent, the event is not delivered again on its own. Recovery is something your team decides on, not something you can assume.

That leaves two tools:

  • Resend from the event log. You find the events that failed during the incident and send them again. Your normal handler processes them as if nothing happened.
  • Reconcile through the API. Your backend lists its own records that are still waiting for a signature, asks the API for the current state of each signature request, and updates the record from the answer.

When resending is the right call​

Resending is for a known incident with a clear start and end. You know the window, you can see the failed deliveries, and you want the exact same events to go through the exact same code path.

This keeps one source of truth for state changes: the webhook handler. Nothing in your codebase has to interpret a signature request's status a second way. For most teams, it is the first thing to do after an outage.

Its limit is that it needs a person. Someone has to notice the incident, open the log and resend. If nobody notices, nothing happens.

When reconciling is the right call​

Reconciling is for what nobody noticed. A handler that returned success but threw later, a queue that dropped a message, a record created just before a release. These do not show up as failed deliveries, so resending will not find them.

A small scheduled job covers this. For example, every hour:

  1. Select records that have been waiting for a signature longer than you expect for that flow.
  2. For each one, read the signature request's current state through the API, using the identifier you stored when you created it.
  3. If the request has moved on, run the same update your webhook handler would have run.

The job does not replace the webhook. It is a safety net that only acts when the record and the request disagree.

Make both paths safe to repeat​

Whichever you use, the same event can now arrive twice: once late through a resend, once through the reconciler, or twice through two resends. Write the update so a repeat changes nothing. Key it on the signature request and the document, check the record's current state before writing, and skip work that is already done, such as downloading a signed PDF you already stored.

Log which path applied each change, for example source: webhook or source: reconcile. When a record looks wrong later, you can tell whether the webhook ever arrived.

The decision​

Treat the webhook as the main path, and give it two backups with separate jobs:

  • After a known outage, resend the failed events from the event log.
  • All the time, run a reconciliation job that catches the records nobody noticed.

Build the reconciler before production, while you still run in the development environment. Stop your endpoint on purpose, sign a test request, and check that the job brings the record up to date on its next pass. Then turn the endpoint back on and resend the same event from the log, and check that your handler does nothing the second time.