Skip to main content

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
onReadyThe signing session loaded
onResizeThe signing surface changed height (handled automatically when autoResize)
onCompletedThe signer completed all required fields
onDeclinedThe signer declined
onErrorThe 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.