Embedded signing on your own site
Iframe an Inkpacket signing token on a host page you already operate: /embed/sign/TOKEN, frame-ancestors, EMBED_ALLOWED_ORIGINS, and postMessage events for viewed, signed, and completed.
The signing link does not have to live in an email. If you already operate a portal, an onboarding page, or an account screen, you can iframe the same tokenized signer on that host. The signer still does not create an Inkpacket account. Your page keeps the chrome; Inkpacket keeps the PDF, the fields, and the audit trail.
Embedded signing is that iframe plus three postMessage events. Desk help has the snippet at Docs. Features describes the allowlist at embedded signing. This guide is the public walkthrough: which URL to frame, how origins are allowed, what the parent hears, and what still applies inside the frame.
Which URL to iframe
After you send an envelope, the desk copies two URLs: the invite URL at /sign/TOKEN and a compact-chrome URL at /embed/sign/TOKEN. Use the embed path when the host page already has a header and you do not want a second one. Use the invite path when you want the same page the email would have opened. Both are the same signer and the same envelope.
The public API returns both on send as signingUrl and embedUrl. See public API and signed webhooks and POST /api/v1/packets/:id/send.
Who is allowed to frame the signer
Signing surfaces send a Content-Security-Policy frame-ancestors list for 'self', https://inkpacket.com, https://www.inkpacket.com, and any extra origins in EMBED_ALLOWED_ORIGINS (comma-separated). Inkpacket omits X-Frame-Options on /sign and /embed so more than one host can frame them. Other routes are not meant to be framed.
If your host is not on that list, the browser will refuse the iframe. Add the origin to the environment, redeploy the app that serves signing, and try again. The FAQ answer matches this paragraph.
The snippet
Desk help prints a minimal iframe and a message listener. The important parts: width 100%, a height that can show the PDF, border none, and allow="clipboard-write" so the signer can copy if the page offers it. The script listens on window and ignores messages whose source is not inkpacket.
The iframe posts { source: "inkpacket", type, token } to the parent on viewed, signed, and completed. Use those events to advance your own UI — hide a “waiting for signature” banner, unlock the next onboarding step, or write a row in your system. Do not treat a postMessage as the legal record. The audit trail on the envelope is the record. A workspace or per-packet webhook is how your backend should hear the same lifecycle; the iframe event is for the page the signer is looking at.
Access codes still apply
If you set an access code at send, the iframe shows the lock screen first. Share the PIN separately from the host page if that page is reachable without a login. Access codes for sensitive envelopes explains hash-at-rest and the 15-minute lockout after five wrong guesses.
What the signer can do in the frame
- The parent loads the iframe with the token.
- The signer enters an access code if you set one.
- They view the PDF. The iframe posts viewed.
- They complete required fields and submit. The iframe posts signed, then completed.
- Or they decline with a reason. Signing stops. The parent will not get completed.
If you void the envelope, every signing and embed link stops. If the envelope expires, they cannot complete it. If you correct the recipient and the email changes, the old token is retired — an iframe still pointing at the old URL will fail. Envelope admin and reminders and expiry cover those closes.
What embedded signing is not
- It is not a hosted customer portal Inkpacket operates for you. You already have the host page.
- An in-envelope payment can be requested on the envelope. Checkout is not open — Payments not live / not configured — and does not charge.
- It is not a way to skip the allowlist. Unknown origins will not frame.
- It is not a substitute for webhooks. postMessage is for the parent tab; signed POSTs are for your server.
Host pages that actually work
The useful hosts are pages you already authenticate. An onboarding step after a candidate accepts an offer. An account screen where a customer confirms an order form. An internal ops page where a vendor finishes an envelope without leaving your tool. In each case the iframe is one step in a flow you own. Inkpacket does not replace that flow.
Do not drop the iframe on a public marketing page and hope the token stays secret. The token is the capability. Treat the embed URL like a signed session: generate it when the right person is on the page, then discard the draft if they never arrive. If you create envelopes from your stack, mint the draft, send, and only then render embedUrl for that session. Templates keep the field layout stable so your host page does not have to know coordinates.
When the frame stays blank
- Confirm the host origin is in EMBED_ALLOWED_ORIGINS, including scheme and port if you use them.
- Confirm you framed /embed/sign/TOKEN or /sign/TOKEN — not /desk or /pricing.
- Confirm the envelope is still sent. A voided, declined, or expired token will not complete.
- Confirm the parent listener checks source === "inkpacket" so other windows do not look like signing events.
Send an envelope first — the five-minute send or create and send from the API — then copy the embed URL onto a page you already operate. Add your origin to EMBED_ALLOWED_ORIGINS when that host is not inkpacket.com. Listen for viewed, signed, and completed. File the stamped PDF from the envelope when the audit says completed.
Open a workspace on Free
Billing is published, not charging. Send an envelope from the desk without a card.
Open a workspace