What Breaks When You Embed eSignature in Your App
Verdocs Team
Embedding a signing component takes an afternoon. What takes the rest of the sprint is every path where the signer does something other than sign: failing an identity check, never receiving the invite, declining, delegating to a colleague, or closing the tab and coming back on Tuesday.
Those are not edge cases. On any real volume they are a daily occurrence, and whether your product handles them decides whether your support queue fills up.
What happens when the signer fails authentication?
If you set a signing document above the lowest assurance rung, some signers will fail it. Knowledge-based authentication in particular has a real failure rate among people who have moved house recently or have a thin credit file.
Verdocs emits recipient_auth_fail as a webhook event, and kba_event separately for knowledge-based checks. The reason to care at design time rather than after launch is that a failed check leaves a real person stuck in your product with no path forward unless you built one.
The workable pattern is to catch the event, mark the document as blocked in your own record, and route the signer to a fallback rung, usually an in-person link or a lower-assurance path approved for that document type. What you should not do is let the failure be silent, because the signer's next move is to call whoever sold them your product.
What happens when the invite never arrives?
Email fails constantly. Corporate filters quarantine mail from unfamiliar senders, and signing invitations look exactly like the phishing pattern those filters are trained on.
recipient_invite_failed tells you the delivery did not happen, which is the difference between a document that is waiting on a person and a document that is waiting on nothing. Without that event, an envelope sitting untouched for four days is indistinguishable from a signer who is just taking their time, and the two need different responses.
This is also the strongest argument for signing inside your own product rather than through an emailed link. If the signer is already logged into your application, the invitation is a row in your UI rather than a message that has to survive a mail gateway. recipient_reminded and recipient_opened cover the cases where email is still in the loop.
What if the signer declines, or just leaves?
These are different states and they want different handling.
recipient_declined is an explicit refusal, and it is information. Somebody read the agreement and said no, which usually needs to reach a human on your side quickly rather than sitting in a status column.
Abandonment is the quieter one. There is no event for a signer who closes the tab, so what you get is recipient_opened with no recipient_submitted following it. Deciding how long that gap is allowed to run, and what happens at the end of it, is your product's decision rather than the vendor's. envelope_expired fires when the envelope's own clock runs out, and envelope_canceled when someone on your side pulls it.
Who gets the document when the signer forwards it?
Real signing routes get redirected by the people in them. An adjuster sends a release to a claimant who forwards it to their lawyer. A borrower hands a disclosure to their accountant.
recipient_delegated exists because delegation is a first-class outcome rather than a workaround, and it matters for your records: the person who signed is not the person you invited, and your audit trail needs to show that rather than quietly recording the original name. Verdocs records each party's authentication in the same event history as the signature, so the delegation and the assurance the delegate actually cleared both survive in the evidence package.
What does your endpoint do when it is down?
Your webhook endpoint will be unavailable at some point, during a deploy if nothing else.
Verdocs calls your endpoint once per event over HTTPS POST, and every payload carries the same base shape: the event name, the profile and organization it happened in, an ISO-format event date, and an event-specific data object. Endpoints are configured per organization in Developer Settings.
Two things worth building rather than assuming. Make the handler idempotent, keyed on the event and the envelope, because the safe assumption for any webhook system is that you may see a delivery more than once. And treat the webhook as an accelerator rather than the source of truth: the API can always tell you an envelope's current state, so a missed event should degrade into a slightly stale record that self-corrects, not a document your system has lost track of.
There are 23 events in total, covering the envelope, template, and recipient lifecycle, plus entitlement_used if you are metering signing to your own customers.
Does the signer need an account with your vendor?
They should not, and this is worth checking early because it is invisible in a demo.
On Verdocs, signers sign from a link or inside your product, on any device, without creating anything. A vendor that requires account creation has inserted a signup flow into the middle of your conversion funnel, and the signer will read that account as a relationship with a company they have never heard of. The embedded eSign overview covers where that boundary sits between standalone, integrated, and embedded signing.
What does the embed need from your CSP?
Less than you would expect, and this is where the component approach earns its keep operationally.
Verdocs ships 75+ web components that render in your own light DOM, with no shadow DOM, so your stylesheets reach every element and there is no cross-origin frame to negotiate with. Your content security policy treats them as what they are, your own scripts.
There is an iframe path for environments where custom elements are impractical, and our documentation is blunt about the tradeoff: with iframes you have no styling or customization options. If you take that path, expect the usual frame concerns, including a completion redirect that will be blocked if your return endpoint sends X-Frame-Options.
What to build before you ship
- A handler for
recipient_auth_fail, and a fallback rung for the signer who hits it. - A handler for
recipient_invite_failed, so an undelivered invite is not read as a slow signer. - An abandonment rule. How long an opened, unsubmitted document waits, and what happens then.
- Idempotent webhook processing, keyed on event and envelope.
- A reconciliation path that reads current state from the API, so a missed event self-corrects.
- A record of who actually signed, not who you invited, for anything that can be delegated.
Where this leaves you
The signing component is the part every vendor demos and the part you will spend the least time on. The integration is the state machine around it, and almost all of that work is deciding what your product does when a person does something reasonable that is not signing.
Worth doing this against a free sandbox before you commit a sprint: send one envelope, then deliberately fail the authentication, bounce the invite, and decline it, and watch what arrives at your endpoint. API-first eSignature covers how to judge a vendor in the first place, and Embed in React walks through the component wiring with real package names.
