Skip to main content

Events

A webhook can be added to subscribe to events that occur. When an event occurs, a trigger is sent to a predefined URL.

Event webhooks​

Supported event types:

Event typeDescription
dossier.invite.createdAn invite has been created.
dossier.invite.expiredAn invite has expired.
dossier.invite.undeliveredAn invite cannot be delivered.
dossier.invite.viewedThe invite has been viewed by the invitee.
dossier.invitee.state.updatedThe invitee state is updated. For example, to approved or declined.
dossier.preparedThe prepare step has been completed: fields are added to the dossier and invites should be sent.
dossier.state.updatedThe state of the dossier is updated. For example, from pending to completed.
dossier.invitee.reassignRequest.state.updatedThe state of the reassign request is updated. For example, from pending to approved.

By default, the dossier.state.updated, dossier.prepared and dossier.invite.undelivered events are sent.

Subscribe to event(s)​

Webhooks can be configured via the API using the webhooks endpoint. When adding a webhook URL, it must start with https:// for security reasons. For more details, see the API reference.

Request
POST https://api.cm.com/sign/v1/clients/{kid}/webhooks

Replace {kid} with the client Key ID

Request headers
Content-Type: application/json
Authorization: Bearer GENERATED_TOKEN_HERE
Request body
{
"url": "https://example.com",
"events": [
"dossier.state.updated",
"dossier.prepared",
"dossier.invite.undelivered"
]
}

Custom headers

Custom headers can optionally be provided in the headers field:

Request body
{
"url": "https://example.com",
"headers": {
"My-Custom-Header": "Example"
}
}
Response body
{
"id": "77e79832-1708-4a49-9528-3536ba4057d7",
"url": "https://example.com",
"events": [
"dossier.state.updated",
"dossier.prepared"
],
"headers": null,
"disabled": false,
"updatedAt": "2026-01-01T00:00:00+00:00",
"createdAt": "2026-01-01T00:00:00+00:00"
}

Retrieve status updates​

Status updates are sent to the configured URL. Below are examples of responses that are sent for each event type.

Request headers
Content-Type: application/json
dossier.state.updated
{
"id": "b041a287-bc92-4469-801e-ae1a39c08f6e",
"type": "dossier.state.updated",
"created": "2026-01-01T00:00:00+00:00",
"dossier": {
"id": "b659c273-954e-43cf-893a-0f74a7f87153",
"state": "completed"
}
}
dossier.prepared
{
"id": "c36f5fc9-b412-4aeb-9cbd-bdb6cdca581f",
"type": "dossier.prepared",
"created": "2026-01-01T00:00:00+00:00",
"dossier": {
"id": "b659c273-954e-43cf-893a-0f74a7f87153",
"state": "draft"
}
}
dossier.invite.created
{
"id": "523075b3-dae7-4f2e-89ba-b194d2b56c2f",
"type": "dossier.invite.created",
"created": "2026-01-01T00:00:00+00:00",
"dossier": {
"id": "b659c273-954e-43cf-893a-0f74a7f87153",
"state": "draft"
},
"invite": {
"id": "87aa2c40-7ad1-4493-8ede-640eab6d2f4e"
}
}
dossier.invite.expired
{
"id": "115c17e0-e714-465c-a3a4-f33700a69d7b",
"type": "dossier.invite.expired",
"created": "2026-01-01T00:00:00+00:00",
"dossier": {
"id": "b659c273-954e-43cf-893a-0f74a7f87153",
"state": "pending"
},
"invite": {
"id": "87aa2c40-7ad1-4493-8ede-640eab6d2f4e"
}
}
dossier.invite.undelivered
{
"id": "e5210e6e-058b-4898-9f71-16f18eb6c141",
"type": "dossier.invite.undelivered",
"created": "2026-01-01T00:00:00+00:00",
"dossier": {
"id": "b659c273-954e-43cf-893a-0f74a7f87153",
"state": "pending"
},
"invite": {
"id": "87aa2c40-7ad1-4493-8ede-640eab6d2f4e"
}
}
dossier.invite.viewed
{
"id": "e20d315d-9b37-4407-a036-22f4fdafb226",
"type": "dossier.invite.viewed",
"created": "2026-01-01T00:00:00+00:00",
"dossier": {
"id": "b659c273-954e-43cf-893a-0f74a7f87153",
"state": "pending"
},
"invite": {
"id": "87aa2c40-7ad1-4493-8ede-640eab6d2f4e"
},
"invitee": {
"id": "f6b72c37-9255-4272-8b21-f2f6ba9537ba"
}
}
dossier.invitee.state.updated
{
"id": "12a1eded-01ca-4e56-9e6c-125842dca977",
"type": "dossier.invitee.state.updated",
"created": "2026-01-01T00:00:00+00:00",
"dossier": {
"id": "b659c273-954e-43cf-893a-0f74a7f87153",
"state": "pending"
},
"invitee": {
"id": "f6b72c37-9255-4272-8b21-f2f6ba9537ba",
"state": "approved"
}
}
dossier.invitee.reassignRequest.state.updated
{
"id": "f5b8eb0b-e976-4dc4-88c9-069f377dd1c9",
"type": "dossier.invitee.reassignRequest.state.updated",
"created": "2026-01-01T00:00:00+00:00",
"dossier": {
"id": "b659c273-954e-43cf-893a-0f74a7f87153",
"state": "pending"
},
"reassignRequest": {
"id": "44971ae0-88fc-43e7-9868-ceaacf6d3ee4",
"state": "pending",
"originalInvitee": {
"id": "f6b72c37-9255-4272-8b21-f2f6ba9537ba",
"state": "reassigned"
}
}
}

Response

The status code should be in the 2xx range (between 200 and 300), the response body doesn't matter as it's ignored. In case of status code 5xx, the webhook will be retried several times with an exponentially increasing delay up to a maximum of 1 day between attempts. After 4 failed delivery attempts, the webhook event will be dropped.

Automatic Webhook Disabling​

If a webhook fails too many times over a week, a warning email will be sent to admins. If the webhook still isn't working a week after that warning, the webhook will be automatically disabled to prevent continued failed attempts.

To re-enable a disabled webhook, use the update webhook endpoint with "disabled": false in the request body. Check the API reference for more details.