@sajn/embed-js and moves on when the user has signed.
Before you begin
- Embedded signing turned on for your organization, with your domain in the embed domains. For more information, see Add your embed domains.
- Node.js 18 or later, and Express:
npm install express. - An API key in the
SAJN_API_KEYenvironment variable. To create one, go to Inställningar > Utvecklare > API-nycklar (Settings > Developer > API keys) in the sajn app. - A template for the agreement. Store its ID in
SAJN_TEMPLATE_ID. - The public HTTPS origin your app runs on, such as
https://signing.example.com, inAPP_ORIGIN.
Build the app
1
Prepare the document and the session on the server
Save the following file as The SDK calls
server.js. The /api/embed-session route creates and sends the document the first time the user asks, then creates an embed session for the user’s party and returns its clientSecret:/api/embed-session again each time a session ends, so the route creates a new session on every call but sends the document only once. The client secret lets the frame sign as the party, so return it only to that user’s session, and never log it. If the template has signature boxes placed on a PDF, leave out parties and update the template’s party instead. See Create documents from templates.2
Show the signing page
Save the following file as
public/index.html. It mounts the signing page and gets a client secret from the server:3
Confirm the signature on the server
onSigned runs in the browser, so use it to move the user on, not as proof. To confirm the signature, subscribe a webhook to document.party.signed or document.completed, and match the document by data.object.externalId. For a complete handler, see Send a contract from your CRM.Run it
Start the server withAPP_ORIGIN=https://signing.example.com node server.js behind a public HTTPS domain that’s in the embed domains, such as a tunnel to port 3000. Open the domain in a browser. The signing page loads in the frame, and after signing, the browser opens /done.html.
Handle errors
- A blank frame and a
bootstrap_timeouterror:APP_ORIGINdoesn’t match the page’s origin exactly, the domain isn’t in the embed domains, or the page isn’t served over HTTPS. For every cause, see Fix a blank frame. - A
client_secret_failederror:/api/embed-sessionfailed. The server logs the APIcodeandrequestId, and the page shows the error’suserMessage, which is safe to show users. For what each code means, see Errors.

