Embedding the signing page

Let your own site show the signing ceremony in an iframe, on the hostnames you declare.

A signing link opens a full page at https://foliosign.com/sign/<token>. You can also show that page inside your own product in an iframe, so the person signing never leaves your app.

Framing is refused by default, and opens only to the origins a workspace has declared. That default is deliberate: the ceremony is where a signature is produced, and a page that can frame it can cover it with its own buttons and collect a signature on a document the signer never read.

Declare your origins

The allow-list belongs to the workspace that sends the document — so in a multi-tenant integration, each of your customers declares their own hostname on their own workspace, and one customer's setting can never widen framing for another.

PUT/api/v1/workspaces/{id}/embed-origins

Replace the list of origins allowed to frame this workspace's signing pages.

GET/api/v1/workspaces/{id}/embed-origins

Read the list back.

curl
curl -X PUT https://foliosign.com/api/v1/workspaces/$WORKSPACE_ID/embed-origins \
  -H "Authorization: Bearer dctr_live_..." \
  -H "Content-Type: application/json" \
  -d '{"allowedOrigins": ["https://planetvan.ca", "https://planetvan.gympillar.com"]}'

Reading needs the workspaces:read scope, writing needs workspaces:write — the same scopes that create the workspace, so a provisioning call can declare the origin in the same breath. Owners and admins can also set it from Settings.

Rules

  • An origin is scheme + host + optional port — https://app.example.com, never a path. A bare hostname is read as https.
  • https only, except http://localhost for local development.
  • No wildcards. *.example.com is refused: it would re-open the exact attack the default prevents. List each hostname, on the workspace that sends to it.
  • The list is replaced wholesale — send the full set every time, and send [] to close it again.
  • Up to 20 origins per workspace.
Changes apply to links already sent

The list is read when the page is served, not when the link is minted, so removing an origin revokes it for signing links that are already out in the world. Allow up to a minute for the change to take effect.

The iframe

html
<iframe
  src="https://foliosign.com/sign/TOKEN"
  referrerpolicy="no-referrer"
  allow="clipboard-write"
  style="width:100%;height:900px;border:0"
></iframe>

The ceremony needs no cookies from your page — the signing token in the URL is the credential — so it works in a third-party frame with storage partitioning on. Give it real height: it is a document, and a short frame means a lot of scrolling.

Always keep a plain link to the same URL next to the frame. Some people open documents in a browser that blocks third-party frames outright, and a fallback link is the difference between a slow signature and a support ticket.

If the frame stays blank

Open your browser console. A refusal names the policy that blocked it:

Framing 'https://foliosign.com/' violates the following Content
Security Policy directive: "frame-ancestors 'self'".
  • frame-ancestors 'self' alone — that workspace has declared no origins. Check you set them on the workspace that sent the document, not on your platform's own workspace.
  • Your origin missing from a longer list — the spelling doesn't match. It is compared exactly: scheme, host and port, so https://www.example.com and https://example.com are two different origins.
  • A refusal from a page served over http — only https origins can be allow-listed.