To embed the signing interface in your web app, first get a ceremony URL.

The ceremony URL

Add two query parameters to the ceremony URL:

  • embedded=true -> Configures the UI for embedding and specifies allowed sources for the frame-ancestors directive of the .
  • event_delivery=message -> Sends ceremony events (like ceremony completion) as Javascript messages.

Example URL with both query parameters:

https://sign.signatureapi.com/en/start?token=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MjI4OTE3NDYsImV4cCI6MTcyMzQ5NjU0NiwiY2VyZW1vbnlf&embedded=true&event_delivery=message

The <iframe> tag

Embed the signing interface using an iframe tag with the Ceremony URL as the src attribute.

Ensure you use the URL with the embedded=true and event_delivery=message query parameters appended.
<iframe
  id="signatureapi-ceremony"
  title="SignatureAPI Signing Ceremony"
  width="800"
  height="600"
  src="https://sign.signatureapi.com/en/start?token=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MjI4OTE3NDYsImV4cCI6MTcyMzQ5NjU0NiwiY2VyZW1vbnlf&embedded=true&event_delivery=message">
</iframe>

Listening to events

The embedded ceremony sends JavaScript MessageEvents for events happening inside the ceremony.

Your app can listen to these events and take actions, such as closing the iframe when the ceremony is completed. Here’s an example of how to listen to these events:

// Function to handle the ceremony completed event
function handleCeremonyCompleted(event) {
    console.log("Ceremony completed successfully.");
}

// Function to handle the ceremony canceled event
function handleCeremonyCanceled(event) {
    console.log("Ceremony was canceled by the user.");
}

// Function to handle the ceremony failed event
function handleCeremonyFailed(event) {
    const { error_type, error_message } = event.data;
    console.error(`Ceremony failed with error: ${error_type} - ${error_message}`);
}

// Function to handle incoming message events
function handleMessage(event) {
    const { type } = event.data;

    switch (type) {
        case 'ceremony.completed':
            handleCeremonyCompleted(event);
            break;
        case 'ceremony.canceled':
            handleCeremonyCanceled(event);
            break;
        case 'ceremony.failed':
            handleCeremonyFailed(event);
            break;
        default:
            console.warn(`Unknown event type: ${type}`);
    }
}

// Add event listener to window for message events
window.addEventListener('message', handleMessage, false);

Advanced options

Cancel Button

By default, a cancel button is included inside the embedded app. To handle cancellation yourself, such as placing a close button outside the embedded app, hide the cancel button with the query parameter allow_cancel=false.

Troubleshooting

If the browser refuses to load the iframe content and you see an error like this in the console log:

Refused to frame … because an ancestor violates the following Content Security Policy directive: “frame-ancestors none”.

Make sure:

  1. You added the &embedded=true query parameter to the ceremony URL.
  2. Your app’s domain is included in the embeddable_in array when creating the ceremony.

To troubleshoot problems, you can try adding a wildcard to the embeddable_in array, for example:

POST https://api.signatureapi.com/v1/recipients/re_5m393QvSqy9SasSmSIG5xS/ceremony HTTP/1.1
Content-Type: application/json
X-API-Key: key_test_...

{
  "authentication": {
    //...
  },
  "embeddable_in": [
    "*"
  ]
}
We don’t recommend using the asterisk * wildcard in production, as it can create security vulnerabilities.