What embedded signing is
Embedded signing lets your users sign a SignProof envelope without leaving your product. Your backend creates a short-lived signing session, your frontend renders it in an iframe, and your app reacts to events viapostMessage and
webhooks.
It reuses the exact same signing flow as emailed links — consent, identity
verification, signature capture, audit trail, and sealing are unchanged.
Embedded signing requires the API. The session must be created server-side with
your OAuth2 credentials. The signature generator (
SignProofSignatureMaker)
and the public signature generator are the only
parts that work fully client-side.The flow
- Your backend creates an envelope (PDF + fields + signer) as usual.
- Your backend creates an embedded signing session for one signer.
- SignProof returns a one-time
sessionToken+embedUrl. - Your frontend renders the iframe (use
@signproof/embed-react). - The signer signs inside the iframe.
- The iframe emits
postMessageevents; SignProof fires your webhooks.
1. Create the session (server-side)
The token is returned once and stored only as a hash. Pass
sessionToken to
your frontend.
2. Render it (React)
embedUrl in a
plain <iframe> and listen for window.message yourself.
3. Events
The iframe posts these to yourallowedOrigin (never *):
Each event includes
{ envelopeId, signerId }.
4. Webhooks are the source of truth
postMessage events are for UI reactions only — a browser tab can close
before completed fires. For backend state (fulfilment, status, audit), rely on
the same envelope webhooks as any other signing:
envelope.completed, signer.signed, envelope.declined. See
Webhooks.
5. Security
- Sessions are short-lived, single-signer, single-origin, and stored as a hash.
- The browser enforces
Content-Security-Policy: frame-ancestors <allowedOrigin>on the embed page — only your registered origin can frame it. - Never expose your API key/secret in frontend code.
- Expired, revoked, completed, or wrong-origin sessions are rejected.
Local development
- Create the session with
"allowedOrigin": "http://localhost:3000"— plainhttp://localhostis allowed only in development. - Point the iframe at your local signing UI host (the
/embed/signroute).
Common errors
Coming later: embedded builder
Embedded signing ships first. An embedded builder (place fields in your own app) will reuse the same session + origin + theme model (POST /v1/embedded/builder-sessions, /embed/builder/:token). Not available
yet — build signing first.