Overview
Ceremony Events
Handle signing completion events via JavaScript messages or redirects in embedded ceremonies
When an embedded ceremony reaches a terminal state, such as when the recipient signs the documents, it sends an event to your application.
Your application should listen for these events and respond accordingly. For instance, you can close the iframe in a web app once the ceremony is complete.
The ceremony sends events only when the URL includes embedded=true. Choose how it delivers them with the event_delivery query parameter. See Event delivery.
Event types
There are 4 types of ceremony events:
| Event | Description |
|---|---|
ceremony.completed | The recipient completed the ceremony, for example by signing the documents. |
ceremony.canceled | A signer tapped Cancel. Embedded signers see Cancel instead of Decline. |
ceremony.declined | An approver tapped Reject. This happens even when the ceremony is embedded. |
ceremony.failed | An error happened and the ceremony can’t be completed. |
Standalone ceremonies, which don’t use embedded=true, send no events. Instead, they redirect the recipient to the redirect_url of the ceremony. See Redirect URL.
The ceremony.completed and ceremony.declined events arrive after the result page has been shown for redirect_delay seconds. The default is 3 and the maximum is 20. Set redirect_delay to 0 to receive the event immediately and show your own result screen. See Ceremony object.
Embedded ceremonies ignore redirect_url. Leave it unset.
The payload of an event has only a type property. A ceremony.failed event also includes error_type and error_message.
Error types
The error_type of a ceremony.failed event is one of these values:
| Error type | When it happens |
|---|---|
unauthorized | The link isn’t valid. It is malformed, it expired, or a newer ceremony for the recipient replaced it. |
already_completed | The recipient already finished the ceremony, either by signing or by declining. |
not_available | The ceremony can no longer be used. For example, the envelope was canceled or the recipient was replaced. |
invalid_link | The URL path isn’t a ceremony link. For example, the URL was truncated. |
unexpected_error | Any other error. |
Branch on error_type, and treat an unknown value as a generic failure. New values can appear over time.
The error_message is a fixed English description for your logs. It is never translated. Don’t show it to signers and don’t branch on it. The ceremony already shows the signer a translated message.
Confirm the outcome on your server
A ceremony event is a UI signal, not proof. Before you act on ceremony.completed, confirm the outcome on your server. Read the envelope or the recipient with GET /v1/envelopes/{id}, or use a webhook.
Event delivery
Set the event_delivery query parameter on the ceremony URL to choose how the ceremony sends events:
| Value | Behavior | When to use |
|---|---|---|
none | The default. The ceremony sends no events. | Use webhooks instead. |
message | The ceremony posts a message to the parent window with postMessage. | Web apps that embed the ceremony in an <iframe>, and native apps that forward the message with a document-start script. |
redirect | The ceremony navigates the WebView to a URL with the signatureapi-message:// scheme. | Mobile and desktop apps that show the ceremony as the page of a WebView. |
Javascript messages
The events are delivered to the parent application as a MessageEvent with a payload. For example the payload for a ceremony.completed event is:
{
type: "ceremony.completed"
}
An example for a ceremony.failed event:
{
type: "ceremony.failed",
error_type: "not_available",
error_message: "The ceremony is no longer available."
}
The ceremony posts the message with a target origin of "*". The payload carries no secrets. Accept a message only when both of these are true:
event.originequalshttps://sign.signatureapi.com.event.sourceequals thecontentWindowof your iframe.
When the ceremony is the top-level page, such as in a native app’s WebView, the message arrives on the page’s own window. In that case the source check is event.source === window.
See Listening to events for a complete example.
Redirects
The ceremony navigates the WebView to a URL with the special scheme signatureapi-message://. This is a client-side navigation, not an HTTP redirect: no request reaches the network. Intercept it in your WebView’s navigation handler (webView(_:decidePolicyFor:decisionHandler:) on iOS, shouldOverrideUrlLoading on Android), cancel the navigation, and read the event from the URL. HTTP-layer interception, such as URLProtocol, shouldInterceptRequest, or a proxy, never sees these URLs.
The event type is included as the host part of the URL, and any other data is included as form-encoded query parameters, where + is a space. For example the URL for a ceremony.completed event is:
The URL for a ceremony.failed event: