Skip to main content
Embedding v2 is in beta. Embed sessions and SDK 1.0 can change in ways that break your integration before the first stable release, estimated for November 2026. Embedding v1, described in Embedded signing, is stable.
In this guide, you embed the sajn signing page in a web page with the @sajn/embed-js package. The package has createSigningEmbed, createViewingEmbed for a read-only viewing session, and two Web Components. It works with any framework or none.

Before you begin

  • Turn on embedding for your organization and add your domain to the embed domains. For more information, see Add your embed domains.
  • Create and send the document, and note the party’s id. For the steps, see Embed the signing page.

Install the package

With a package manager:
Without a build step, load the UMD bundle from a CDN. It exposes the sajn global:
Always pin the version in a CDN URL. A URL without a version, such as https://unpkg.com/@sajn/embed-js, loads the newest major version the day it’s published, and a major version has breaking changes.
To make sure that the browser runs only the file you tested, add an integrity attribute with the file’s hash and crossorigin="anonymous" to the <script> tag.

Create a session on your server

Your page never calls the sajn API. Add an endpoint to your server that creates an embed session and returns its clientSecret:
The SDK calls this endpoint again each time a session ends, so create a new session on every call. For every field of the request, see Create session request.

Show the signing page

Call createSigningEmbed with a container and a fetchClientSecret function:
The SDK creates the iframe inside the container right away and calls fetchClientSecret once. To remove the frame, call embed.destroy().

Options

The callbacks are onReady, onSigned, onRejected, onFieldsSubmitted, onVerified, onStateChange, onResize, onSessionExpired, and onError. For when each one runs and its data, see Events.

Change the frame after it loads

createSigningEmbed returns an object with three methods: For example, to follow your page’s dark mode:
Features can’t change from the browser. To change them, create a new session.

Use the CDN bundle

The following page uses the UMD bundle:

Use the Web Components

@sajn/embed-js defines two elements when it loads: <sajn-signing-embed> and <sajn-viewing-embed>. Give the element a client-secret-url. The element sends a POST to that URL and expects { "clientSecret": "..." } back:
The element takes the attributes client-secret-url, host, locale, appearance (JSON), fallback-height, and frame-title. Changing appearance or locale updates the frame in place; any other attribute starts a new session. To fetch the secret yourself, set the fetchClientSecret property instead of the attribute. The element fires the callbacks as DOM events, with the callback’s argument in event.detail: ready, signed, rejected, fields-submitted, verified, state-change, resize, session-expired, and embed-error.

TypeScript types

The package exports its types:
EmbedIds is { documentId: string; partyId: string; externalId: string | null }, the data of most events.

Troubleshooting

  • onError gets bootstrap_timeout, and the frame is blank: the browser most likely refused the frame. Check the session’s origins against the page’s exact origin, and your page’s own frame-src policy. For every cause, see Fix a blank frame.
  • onError gets client_secret_failed: your fetchClientSecret threw an error, or returned something other than the clientSecret string. Check your endpoint’s response.
  • The frame is 600px high and doesn’t fill the container: the container has no height. Give it one, or set appearance.mode to inline.
For the other error codes, see Error codes.

Next steps

Embedded signing

See the session request, the appearance, the events, and the error codes.

Embed signing in your app

Run the whole flow from server to frame.