Skip to the content

Documentation

Embedded signing

Show a Docustay signing form inside your own website or app, with a web component and React, Vue and Angular wrappers.

Show the signing form inside your own page, so the signer never leaves your app.

How it fits together

  1. List your website. In Developers → Embedding add each website that will show the form, one per line, for example https://app.example.com. While developing, http://localhost:3000 is allowed. Nothing else (no path, no plain http) is.
  2. Send with embedded seats. On your server add embedded: ["signer_1"] to the send request. Nobody is emailed for those seats.
  3. Ask for a session. On your server call POST /api/v1/documents/{id}/embed-session with { "seat": "signer_1", "origin": "https://app.example.com" }. The answer is { url, expiresAt }. The link works for one hour; ask again each time the page loads.
  4. Show it. Give the url to the element.

The API key stays on your server. The url is the only thing the browser sees.

The element

<script type="module" src="https://docustay.app/embed/index.js"></script>
<docustay-sign url="https://…/sign/pdf?t=…&embed=1&parent=https%3A%2F%2Fapp.example.com" height="720"></docustay-sign>

Attributes: url, height (pixels or any CSS length), auto-height (follow the form's own height), title. Events, each with detail.documentId:

Event When
ready the form has loaded
waiting it is not this person's turn yet
completed the signer finished
declined the signer declined
error the link was refused (expired, wrong, or the website is not on the list)
resize the form's height changed (detail.height)

The docustay event carries all of them as { type, … }. Events do not bubble.

React, Vue, Angular

import { DocustaySign } from "@docustay/react";
<DocustaySign url={session.url} onCompleted={({ documentId }) => confirmOnServer(documentId)} />
<DocustaySign :url="session.url" @completed="done" />
<docustay-sign-form [url]="session.url" (completed)="done($event)"></docustay-sign-form>

What keeps it safe

  • The form can be framed only by the websites you listed. Docustay sends a frame-ancestors header naming exactly those, and only for a link made for an embedded seat. An ordinary emailed link is never frameable, even with embed=1 added.
  • The form sends its events to one parent origin, the one in the link, and only if it is on your list. The element accepts a message only from its own frame and the form's own origin.
  • Treat completed as a prompt, not proof: confirm with GET /api/v1/documents/{id} on your server (state: executed).

Let your people build templates inside your own page

The builder is the same editor Docustay uses, in a frame on your website. Your server asks for a session; your page shows it.

  1. On your server (never in a browser), with a key that has the embedded:write scope:

    POST /api/v1/embedded/builder-session
    { "origin": "https://app.example.com", "name": "Services agreement" }

    The answer is a url that works for one hour. The website must already be on your allowed list (Settings → Embedding); anything else gets a 409.

  2. In your page, show it:

    <script type="module" src="https://docustay.app/embed/index.js"></script>
    <docustay-builder url="…the url…" height="760"></docustay-builder>
  3. Listen for ready, saved ({ templateId, name, fields }) and error. Use the templateId to send documents from your server as usual.

What keeps it safe: the key inside the link is created for this session only, lives in the #fragment (so no server log sees it), expires in an hour, and can read and write templates and nothing else — it cannot send a document. The link names the one website that may frame it and is signed; change the website and it will not frame anywhere.

CtrlI