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
- 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:3000is allowed. Nothing else (no path, no plainhttp) is. - Send with embedded seats. On your server add
embedded: ["signer_1"]to the send request. Nobody is emailed for those seats. - Ask for a session. On your server call
POST /api/v1/documents/{id}/embed-sessionwith{ "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. - Show it. Give the
urlto 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-ancestorsheader naming exactly those, and only for a link made for an embedded seat. An ordinary emailed link is never frameable, even withembed=1added. - 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
completedas a prompt, not proof: confirm withGET /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.
On your server (never in a browser), with a key that has the
embedded:writescope:POST /api/v1/embedded/builder-session { "origin": "https://app.example.com", "name": "Services agreement" }The answer is a
urlthat works for one hour. The website must already be on your allowed list (Settings → Embedding); anything else gets a 409.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>Listen for
ready,saved({ templateId, name, fields }) anderror. Use thetemplateIdto 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.