# Embedded signing

Embedded signing puts the signing page inside your own app, in an iframe on a site you list. The signer never leaves your page, and the frame tells your page when they finish.

## Before you start

1. List your site in branding: `embed_origins: ["https://app.example.com"]`. See [branding](/docs/branding). Without a listed site, the embedded page refuses to load.
2. Send the document. A signing link only exists for a sent document.

## Get an embed URL

Call `create_signing_link` with the signer's position and `embed: true`.

```
curl https://docuinked.com/v1/documents/DOCUMENT_ID/signing_links \
  -H "Authorization: Bearer $DOCUINKED_API_KEY" \
  -H "Idempotency-Key: embed-2291-1" \
  -H "Content-Type: application/json" \
  -d '{"signer": 1, "embed": true}'
```

The reply holds `embed_url`. Treat it like a password: anyone holding it can open that signer's page. Create it on your server when the signer is in front of you, and hand it straight to the page. Agent keys can't get live signing links.

## Show it in your page

```
<div id="sign"></div>
<script type="module">
  const frame = document.createElement("iframe");
  frame.src = embedUrl;
  frame.title = "Sign the document";
  frame.style.width = "100%";
  frame.style.height = "80vh";
  document.querySelector("#sign").append(frame);
</script>
```

The page sends a Content-Security-Policy that allows framing only by your listed sites. Anywhere else, the browser refuses to show it.

## Listen for what happened

The frame posts a message to your page at each step, only to an origin on your list.

```
window.addEventListener("message", (e) => {
  if (e.origin !== "https://docuinked.com") return;
  const { type, document, signer } = e.data;
  // type is "docuinked:loaded", "docuinked:signed" or "docuinked:declined"
});
```

| Message | Sent when |
|---|---|
| `docuinked:loaded` | The signing page is ready |
| `docuinked:signed` | This signer finished signing |
| `docuinked:declined` | This signer declined or asked for paper |

Each message carries `document` and `signer`. Browser messages are for moving your page along. For anything that matters, such as marking a deal signed, trust the [webhook](/docs/webhooks) on your server, which is signed.

## What the signer sees

The same steps as everywhere else: the consumer disclosure and consent, the document with its fields, and the signature pad. The page wears the account's branding. When the last person signs, the PDF is sealed and every party gets a copy by email.

## Common questions

### Why doesn't the frame load on my local machine?

Embed origins must be https sites you list in branding. A page on `http://localhost` isn't one, so the frame shows a refusal. Test on an https staging site that you add to `embed_origins`.

### Can the signer still use the email link?

Yes. The email link and the embedded page lead to the same signing session. Whichever the signer finishes first counts, and signing can happen only once.

### How long does an embed URL last?

Treat it as short-lived and make a fresh one each time the signer opens your page. Don't store it or put it in a URL that gets logged.
