# Signing inside your product

The person is already in your app. Do not send them to their inbox.

Watch it done: [Embedded signing in your own product](https://signsealer.com/guides/embedded-signing-in-your-own-product) (1:55)

Three ways to put signing in front of somebody, from least work to most:

- **Send them to our page.** The `url` in the send's answer, in a new tab or as a redirect; set `return_url` on the document and the signed page offers the way back.
- **Frame our page** on your own site. This page.
- **Build your own page** on the signing routes (`/v1/sign/{token}`), which take no key and answer a browser on any site. The [Node client](https://signsealer.com/docs/sdk)'s `SignSealerSigning` is that client.

## 1. Send without sending

Give the signer `delivery: "embedded"`. Nothing is emailed or texted to them, and the automatic reminders leave them alone: you are showing them the page yourself. They still need an email address or a mobile number, because the certificate records how they could be reached and the completed copy goes to them.

```
const { links } = await signsealer.send(documentId, [
  { email: "dana@example.signsealer.com", full_name: "Dana Reyes", delivery: "embedded" },
]);
```

## 2. A fresh link when the page is shown

Do not keep the link from the send in your database: it is a bearer credential. Mint one when the person opens the screen that shows it. The link they had stops working, and the trail records that one was shown.

```
const { url, frame_origins } = await signsealer.embedLink(documentId, signerId);
// POST /v1/documents/{id}/signers/{signer}/embed
```

## 3. Put it in a frame, on a site the business has proven

The signing page may be framed only on sites the business has proven are its own, and the browser enforces it (`frame-ancestors`): anywhere else the frame stays empty. A business proves a site in one of three ways, the same three that let a signed page send somebody back to it:

- a **signing domain** it verified (Settings, under *Your own domains*), and every host under it;
- a **company sign-in domain** it proved (Settings → Single sign-on), and every host under it;
- the **site of an app it connected**, such as a WordPress site running our plugin: that one host. Not an AI assistant's: connecting Claude does not make claude.ai one.

`frame_origins` on the embed answer, and on `GET /v1/account`, lists them. Empty means nowhere yet. The business's public forms (`/f/{business}/{form}`) may be framed on the same sites.

With a test key (`mk_test_`), the sandbox's pages may also be framed on `http://localhost` and `http://127.0.0.1`, any port, so you can build the frame before you deploy. The live business's pages never are.

```
<iframe src="{url}" title="Sign your rental agreement"
        style="width:100%;border:0;min-height:640px"
        allow="camera; geolocation"></iframe>
```

`allow="camera"` lets a template that asks for a photograph use it; `geolocation`, one that asks where the signer is.

## 4. Hear what happened

Inside a frame the page posts a message to the page around it:

```
{ source: "signsealer", event, document_id, signer_id, height }
```

| event | When |
| --- | --- |
| ready | Every page, as it loads. |
| resize | The page's height changed: set the frame's height to `height` and there is no inner scrollbar. |
| signed | They have signed. Other signers may still be to come; `signing.completed` on your webhook is when everyone has. |
| declined | They declined. |

```
window.addEventListener("message", (e) => {
  if (e.origin !== new URL(url).origin) return;      // only the signing page
  const m = e.data;
  if (!m || m.source !== "signsealer") return;
  if (m.event === "resize" || m.event === "ready") frame.style.height = m.height + "px";
  if (m.event === "signed") showThanks();
  if (m.event === "declined") showDeclined();
});
```

Treat the message as a hint to update the screen, not as proof: anything that matters — releasing an order, unlocking a booking — waits for the webhook, which is signed, or for `GET /v1/documents/{id}`.

## What the page does and does not do in a frame

- It sets no cookie, so a browser that blocks third-party cookies changes nothing.
- It carries one script in a frame, pinned by its hash in the page's own policy, and none at all when opened in a tab. The message is the only thing it does.
- The way back on the signed page (`return_url`) leaves the frame for the whole window.
- A frame on a site that is not proven shows nothing, and that is the browser refusing on our instruction, not an error to work around.

[This page as Markdown](https://signsealer.com/docs/embedding.md) Ask an AI about it: [ChatGPT](https://chatgpt.com/?q=Please%20read%20https%3A%2F%2Fsignsealer.com%2Fdocs%2Fembedding%20and%20explain%20it%20to%20me%20as%20a%20developer%20adding%20SignSealer%20to%20my%20application%3A%20what%20it%20covers%2C%20the%20calls%20involved%20and%20anything%20to%20watch%20out%20for.%20Use%20https%3A%2F%2Fsignsealer.com%2Fllms.txt%20for%20the%20rest%20of%20the%20docs%2C%20and%20cite%20the%20page%27s%20URL%20in%20your%20answer.) · [Claude](https://claude.ai/new?q=Please%20read%20https%3A%2F%2Fsignsealer.com%2Fdocs%2Fembedding%20and%20explain%20it%20to%20me%20as%20a%20developer%20adding%20SignSealer%20to%20my%20application%3A%20what%20it%20covers%2C%20the%20calls%20involved%20and%20anything%20to%20watch%20out%20for.%20Use%20https%3A%2F%2Fsignsealer.com%2Fllms.txt%20for%20the%20rest%20of%20the%20docs%2C%20and%20cite%20the%20page%27s%20URL%20in%20your%20answer.) · [Perplexity](https://www.perplexity.ai/search?q=Please%20read%20https%3A%2F%2Fsignsealer.com%2Fdocs%2Fembedding%20and%20explain%20it%20to%20me%20as%20a%20developer%20adding%20SignSealer%20to%20my%20application%3A%20what%20it%20covers%2C%20the%20calls%20involved%20and%20anything%20to%20watch%20out%20for.%20Use%20https%3A%2F%2Fsignsealer.com%2Fllms.txt%20for%20the%20rest%20of%20the%20docs%2C%20and%20cite%20the%20page%27s%20URL%20in%20your%20answer.) · [Google AI](https://www.google.com/search?udm=50&q=Please%20read%20https%3A%2F%2Fsignsealer.com%2Fdocs%2Fembedding%20and%20explain%20it%20to%20me%20as%20a%20developer%20adding%20SignSealer%20to%20my%20application%3A%20what%20it%20covers%2C%20the%20calls%20involved%20and%20anything%20to%20watch%20out%20for.%20Use%20https%3A%2F%2Fsignsealer.com%2Fllms.txt%20for%20the%20rest%20of%20the%20docs%2C%20and%20cite%20the%20page%27s%20URL%20in%20your%20answer.) · [Grok](https://grok.com/?q=Please%20read%20https%3A%2F%2Fsignsealer.com%2Fdocs%2Fembedding%20and%20explain%20it%20to%20me%20as%20a%20developer%20adding%20SignSealer%20to%20my%20application%3A%20what%20it%20covers%2C%20the%20calls%20involved%20and%20anything%20to%20watch%20out%20for.%20Use%20https%3A%2F%2Fsignsealer.com%2Fllms.txt%20for%20the%20rest%20of%20the%20docs%2C%20and%20cite%20the%20page%27s%20URL%20in%20your%20answer.)
