Embedded signing
Embedded signing keeps the signer inside your product — the Permissio signing
ceremony renders in an <iframe> on your page instead of redirecting away. The
permissio-embed SDK handles the iframe, auto-resizing, and a typed event
stream so you can react when the signer finishes.
1. Allow your origin
For security, Permissio only lets the signing page be framed by origins you've
registered. In the dashboard go to Settings → Security → Embedded signing
origins and add each origin that will embed the signer, e.g.
https://app.example.com. Without this the browser blocks the iframe
(frame-ancestors). The redirect flow is unaffected.
2. Get a signing token
Each embed is scoped to a single signer. Request the signer's signing URL from
your backend — the token is the last path segment of the returned url:
curl https://api.permissio.us/v1/envelopes/$ENV_ID/recipients/$RCP_ID/signing-url \
-H "Authorization: Bearer $PERMISSIO_KEY"
# → { "url": "https://app.permissio.us/sign/<token>", ... }
Pass that <token> to the SDK on the client. Signing URLs are single-use and
expire, so mint one per signing session.
3. Mount the signer
npm install permissio-embed
import { mountPermissioSigner } from "permissio-embed";
const handle = mountPermissioSigner({
container: document.getElementById("signer")!,
token, // from step 2
baseUrl: "https://app.permissio.us", // the Permissio app origin
autoResize: true,
onReady: ({ envelopeId }) => console.log("loaded", envelopeId),
onCompleted: ({ envelopeId, recipientId }) => {
// signer finished — advance your own flow
},
onDeclined: () => {/* signer declined */},
onError: ({ message }) => {/* token invalid / load failed */},
});
// Later, to tear down:
handle.destroy();
The SDK validates that events come from the Permissio origin, so you never have
to wire up the postMessage protocol yourself.
Script tag (no bundler)
<script src="https://unpkg.com/permissio-embed/dist/embed-sdk.umd.js"></script>
<script>
const handle = window.Permissio.mountSigner({
container: document.getElementById("signer"),
token: "…",
baseUrl: "https://app.permissio.us",
onCompleted: ({ envelopeId }) => { /* … */ },
});
</script>
Events
| Event (host callback) | When |
|---|---|
onReady | The signing session loaded |
onResize | The signing surface changed height (handled automatically when autoResize) |
onCompleted | The signer completed all required fields |
onDeclined | The signer declined |
onError | The token was invalid or the session couldn't load |
Alternative: raw iframe
If you can't add the SDK, load the embed URL directly — you're then responsible
for the permissio:* postMessage protocol and resizing:
<iframe
src="https://app.permissio.us/embed/sign?token=<token>"
style="width:100%;height:720px;border:0"
allow="clipboard-write"
></iframe>
The same origin allowlist (step 1) applies.