Guides
Embedded signing
Let recipients sign inside your own website or app with signing sessions and an iframe.
With embedded signing your customer signs inside your own website or app. You create a short-lived signing session for one recipient and open its URL in an iframe (or a new window). The page is the same signing experience as the email link, without the access-code step — you have already identified the signer.
1. Allow your site to embed Macaaw#
Browsers only show the signing page in an iframe on sites you allow. Add your site's origin (for example https://app.example.com) under Account → Developer → Settings → Allowed embed origins. With no origins, sessions still open as a normal page or popup but cannot be framed.
2. Send the document silently#
Create the document as usual and send it with "silent": true. Silent documents send no emails at all — not to recipients, and not the sender's own signed, declined or completed notices — and get no automatic reminders. Use webhooks to follow them.
curl https://macaaw.com/public/v1/documents/$DOCUMENT_ID/send \
-H "Authorization: API-Key $MACAAW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"silent": true}'3. Create a session#
| Field | Description |
|---|---|
recipient | Email address of the recipient who will sign. Required. |
lifetime | Seconds until the session expires: 900 to 86400, default 3600. |
curl https://macaaw.com/public/v1/documents/$DOCUMENT_ID/session \
-H "Authorization: API-Key $MACAAW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"recipient": "client@example.com", "lifetime": 900}'{
"id": "ss_gfT8iyVuwiuA3qZwReb8SnQPwcPmobpUO_4zJdLbQHE",
"expires_at": "2026-10-30T11:50:00.000000Z",
"url": "https://macaaw.com/s/ss_gfT8iyVuwiuA3qZwReb8SnQPwcPmobpUO_4zJdLbQHE"
}The document must be document.sent (silently or not) and the recipient must be a signer; otherwise the call answers 409 or 400. Create sessions on your server — never expose your API key to the browser.
4. Open it in an iframe#
<iframe
src="https://macaaw.com/s/ss_gfT8iyVu…"
title="Sign the agreement"
style="width: 100%; height: 760px; border: 0"
allow="clipboard-write"
></iframe>The page adapts to narrow frames (down to 360 px), works in 24 languages (the recipient's locale, or add a prefix such as /de/s/…) and loads no ads, analytics or cookie banners.
5. Listen for the result#
When the signer finishes or declines, the page posts a message to the parent window — only to an origin on your allowed list:
{
"type": "macaaw.signing",
"event": "completed",
"session_id": "ss_gfT8iyVu…"
}window.addEventListener('message', (e) => {
if (e.origin !== 'https://macaaw.com') return;
if (e.data?.type !== 'macaaw.signing') return;
if (e.data.event === 'completed') showThanks();
if (e.data.event === 'declined') showDeclined();
});recipient_completed or document_state_changed webhook, or GET /documents/{id}/details.Session rules#
- A session is for one recipient of one document and expires after its lifetime. Create a new one each time the user opens the signing step.
- Session ids are long random values stored as hashes; treat the URL like a password.
- Signing order still applies: a recipient whose turn has not come sees a “not yet” page.