Skip to main content
In this recipe, you build an Express app where a signed-in user signs an agreement without leaving your site. The server creates and sends the document and returns the party’s signing token. The page shows the signing page with @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 allowlist. For more information, see Embedded signing.
  • Node.js 18 or later, and Express: npm install express.
  • An API key in the SAJN_API_KEY environment variable. To create one, go to workspace settings in the sajn app, then Utvecklare (Developer) > API-nycklar (API keys).
  • A template for the agreement. Store its ID in SAJN_TEMPLATE_ID.

Build the app

1

Prepare the document on the server

Save the following file as server.js. The /api/signing-session route creates the document with the user as a party whose deliveryMethod is NONE, sends it, and returns the document ID and the token from the party’s signingUrl:
The create request returns the whole document, so the party’s id is in parties. GET /api/v1/documents/:id/parties/:partyId returns the party’s signingUrl, which carries the token in its token query parameter. The token lets anyone sign as the party, so return it only to that user’s session. 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 asks the server for a session and mounts the signing page:
3

Confirm the signature on the server

onSignerCompleted 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 with node server.js behind a public HTTPS domain that’s in the allowlist, such as a tunnel to port 3000, and 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 or a document-error event: the domain isn’t in the allowlist or isn’t served over HTTPS, or the token is wrong.
  • An error from /api/signing-session: the server logs the API code and requestId, and the page shows the error’s userMessage, which is safe to show users. For what each code means, see Errors.