Webhook state management: E-signature events into your ERP without polling

Polling for signature status creates load, latency and inconsistency. This article shows how webhooks work as a state bridge into ERP and CRM: event types, idempotency, retries, state machine and typical failure patterns.

Kontakt aufnehmen
Webhook state management: E-signature events into your ERP without polling

Why polling for signature status fails

Most signing integrations start with a loop. A background job asks the API every few minutes whether a document is signed and then updates the status in your own system. For a prototype that works, for production it does not. Webhook state management replaces the loop by reversing responsibility: the signing flow reports state changes actively, and your system processes them as events. It sounds like a technical detail yet is one of the most consequential architecture decisions in a signing integration.

Polling has three structural problems. The first is load without information. With a thousand open transactions and a five-minute interval you generate thousands of requests, most reporting “nothing new”. That burdens your infrastructure, the vendor's API and your rate limits, and scales poorly as tenants grow. The second is latency. If a contract is signed at 10:01 and your job asks at 10:05, the user sees a stale state for four minutes. In processes hanging on the signature, such as approvals or provisioning, that is noticeable.

The third problem is inconsistency. Polling yields snapshots, not history. If a transaction changes state twice between two polls, say from opened via declined to restarted, you see only the end. Audit and troubleshooting lack the story, and business follow-ups lack their triggers. How important that story is for evidence is shown in DORA Article 30 and the API audit trail, which treats events as evidence.

Webhooks solve these problems but bring requirements of their own. They make your system a receiver that must accept messages at any time, including duplicate, late or unordered ones. Treating webhooks like a plain function call swaps the problems of polling for subtler bugs: follow-up processes fired twice, events lost in outages, states jumping backwards. The art lies in building a state model that copes with the imperfection of delivery.

The one hard distinction of this article is therefore: a webhook is a hint, not a command. It tells you something has changed. Whether and how your system reacts is decided by your state model, not by the order of incoming messages. Internalise that sentence and you avoid most classic mistakes. For practical entry, documentation and sandbox are in the developer hub, and how webhooks work in a native flow is described in white-label signing without context switching.

There are cases where polling stays useful as a reconciliation. A daily job that checks open transactions against the API state catches lost events and serves as a safety net. The difference from a pure polling approach: reconciliation is the exception, not the main path. It runs rarely, barely burdens systems and provides a control you can show in audits as evidence of diligence.

Event types and their state model

Before writing code you need a model. A signing transaction passes through states, and webhooks signal the transitions. Take exact event names from the documentation in the developer hub. Conceptually the events fall into four groups you should treat differently in your system.

Lifecycle events mark the course: transaction created, invitation sent, document opened, signer acted, transaction completed. Result events describe the outcome: signed, declined, expired, revoked. Identification events prove that a signer completed the required check, especially relevant for AES and QES. Error and status events report disruptions: delivery failed, document not processable, partner service unreachable.

From these events you build a state machine in your system. Each transaction has a current state, and there is a defined set of allowed transitions. A transaction may move from “sent” to “opened” or “expired” but not from “completed” back to “sent”. If an event arrives that triggers no valid transition in your machine, do not ignore it silently but log it as an anomaly. Often it is a late event overtaken by another, and sometimes a real problem.

Alongside the current state, store the event history. Each row holds transaction ID, event type, event time according to the source, arrival time at your end, a unique event ID and where applicable the payload or a reference. With this history you can reconstruct states, explain anomalies and supply evidence. The current state is derived from the history, not the other way round. This way of treating events as primary truth comes from event sourcing and can be applied in a leaner form without a full framework.

Functionally, distinguish which events trigger follow-up processes. Typically only a few: completion, decline and expiry. All others serve display and evidence. This separation prevents a late “document opened” from accidentally triggering an approval. For each triggering event define exactly what happens and how often it may happen at most. The latter leads directly to idempotency.

The signature level shapes the model too. With a simple signature (SES) the path is short. AES and QES add identification steps, and for QES a partner QTSP such as Sign8 works in the background, since Sign2x itself is not a QTSP. Your machine should model these steps as their own states or substates so you can build progress displays users understand. An overview of the levels is in SES, AES and QES in SaaS, and the path to the first QES flow is in from sandbox to your first QES path.

Idempotency, ordering and retries

Webhook delivery is fundamentally at least once: the source retries until it receives an acknowledgement, which can cause duplicates. Networks are unreliable, responses get lost, and senders repeat to be safe. Your receiver must therefore be idempotent: processing the same message several times may yield the same result as once. The term comes from HTTP semantics (RFC 9110) and applies analogously to your processing logic.

The practical pattern is simple. Each event carries a unique identifier. On arrival you check whether it already sits in your event history. If so, acknowledge and do nothing. If not, write the identifier and the state change in the same transaction, so a state never exists without a history entry or vice versa. A uniqueness constraint in the database enforces the rule even if two messages arrive simultaneously.

On ordering: never assume events arrive in the order they occurred. Two webhooks can overtake each other, especially with retries after outages. Check against your state machine and use the source's event time rather than arrival time when deciding which event is newer. For conflicts, asking the API is the safest solution: read the current state of the transaction and reconcile rather than guess from message order.

For responding the rule is “acknowledge fast, process later”. Your endpoint should verify the message, put it into a queue and answer immediately with a success code. The actual processing, with database access, calls to other systems and follow-ups, runs asynchronously. That avoids timeouts that trigger retries at the sender and raise the duplicate rate. Answer with an error code only when the message truly could not be accepted, so a retry makes sense.

On the receiving side you also need your own retries. If processing fails because your ERP is briefly unreachable, the event must not be lost. Put failed processing into a retry queue with growing intervals and a cap. After the cap the event lands in a dead-letter store a human reviews. It is important the store is visible: a dashboard or alert that fires when something sits there prevents silent failures from going unnoticed for weeks.

On authenticity: a webhook endpoint is reachable from outside, and anyone could try sending forged events. Verify that the message really comes from the signing flow, for example through header signatures or a shared secret as the documentation describes. Limit message size, validate the schema and process only fields you need. General guidance on secure interface design is available from the BSI.

Connecting ERP and CRM: from event to business process

At the centre of integration is a clear translation: an event from the signing flow becomes a business state change in the ERP or CRM. “Transaction completed” becomes “contract signed”, which may trigger order release in the ERP, closing an opportunity in the CRM and filing the signed document in document management. This translation belongs in its own layer, the adapter, not scattered across business modules.

The adapter has three jobs. It accepts events, validates them and writes them into the history. It applies the state machine and determines whether a business follow-up is due. And it calls the business systems through their interfaces, with its own retry logic and error handling. Because business systems are often slower and more error-prone than the signing flow, the adapter decouples both sides. If the ERP is down for an hour, events queue in the adapter and are worked off afterwards instead of webhooks being lost.

A key decision is the reference. When creating the transaction, pass your own identifiers such as contract number, tenant and document type. These references come back in the webhooks and allow unambiguous assignment to the business object without searching tables. In multi-tenant systems the tenant identifier is mandatory so events never land in the wrong tenant. More on tenant models in white-label requirements for ISVs.

For the interface, an optimistic but honest treatment of states is advisable. While a user signs in your interface, show the progress you know. If the webhook confirmation is still pending, show “processing” rather than a premature “done”. That prevents users from regarding a document as signed that is not yet released in business terms. For ERP interfaces with embedded signing, silent tech: signing inside ERP surfaces describes more patterns.

For data storage look at retention and privacy. Event data contains times, roles and references, sometimes personal information. Decide how long you keep it and separate what is needed for evidence from what is only needed for operation. The legal basis is in the GDPR. Sign2x runs on the Open Sovereign Cloud (OSC) from T-Systems, which allows a clear location statement in your data processing documentation.

For bulk scenarios, where many transactions run simultaneously, the same model applies, with more attention to throughput and backlog. How to design patterns for large volumes without promising unproven performance figures is described in bulk signature API for enterprises. The key rule stays the same: decouple acceptance and processing.

Typical failure patterns and how to spot them

Practice yields a few recurring failure patterns. The most frequent is double processing: a completion event triggers the same follow-up twice, such as two invoices or two approvals. The cause is almost always missing idempotency or a check outside the transaction. It shows as duplicates in business data despite a single transaction. Remedy: a uniqueness constraint on the event ID and coupling follow-ups to the state change, not to the arrival of a message.

The second is the backward state jump. A late event overwrites a newer state, and a completed transaction appears open again. The cause is a state model without transition checks. Remedy is the state machine with allowed transitions and reconciliation via the API when in doubt. The third is the lost event: your endpoint was unreachable during maintenance and nobody noticed. Remedies are the daily reconciliation, alerts on errors and a dead-letter store someone watches.

The fourth is the timeout loop. Your endpoint processes synchronously, answers too slowly, the sender retries and load grows. Remedy: acknowledge fast, process asynchronously. The fifth is the tenant error: an event lands in the wrong tenant because the reference was missing or imprecise. That is a data protection incident and belongs in every test. Check specifically that an event with an unknown or unassigned reference is rejected and reported.

Finally a word on observability. Measure arrival rate, processing time, retry rate and the size of the dead-letter store. These figures show whether your integration is healthy long before users complain. We deliberately quote no reference values, because they depend on your volume and business systems. What matters is that you know your own baseline and notice deviations. More help is in the help centre, examples under use cases and further articles in the Sign2x blog. The Sign2x quiz offers a first classification of your situation, and for concrete questions reach us via contact.

Test webhooks in the sandbox

Further reading: white-label signature API without context switching and NIS-2 evidence through the signature audit trail. The legal foundations of the signature levels are in the eIDAS Regulation.

Frequently asked questions

Why are webhooks better than polling for signature status?

Webhooks report state changes actively, save load, reduce latency and provide an event history instead of snapshots. A daily reconciliation remains useful as a safety net.

What does idempotency mean for webhook receivers?

Processing the same message several times may yield the same result as once. In practice you store the event ID under a uniqueness constraint and write state and history in one transaction.

How do I handle out-of-order events?

Check every transition against a state machine, use the source's event time and reconcile the current state via the API when in doubt.

How fast should my endpoint respond?

As fast as possible. Verify the message, queue it and acknowledge immediately. Processing runs asynchronously so timeouts do not trigger retries.

What role does Sign2x play for QES?

Sign2x is the API layer and not a QTSP. For QES the qualification runs through a partner QTSP such as Sign8. Your state models should map the intermediate steps.

Finden Sie heraus, wie wir Ihr Unternehmen unterstützen können

Thank you. Your request has been received.
Something went wrong. Please try again or email info@sign2x.com.