SignEnvoy docs
Sign in Start in the sandbox

Events

Webhook events

Register an endpoint with POST /v1/webhooks (an https:// URL and an optional list of event types; an empty list subscribes to everything). Each delivery is a POST with a JSON body and the headers below.

Event types

TypeWhen
document.approvedAn approver approved the document. An approval is not a signature.
document.bouncedA signing email could not be delivered to a recipient.
document.completedEvery recipient has signed. Sealing starts.
document.createdAn envelope was created (draft or finalized).
document.expiredThe envelope's expiry passed before every recipient signed.
document.openedA recipient opened their signing link for the first time. One event per recipient.
document.rejectedA recipient declined, which closes the envelope.
document.sealedThe sealed PDF, with its Certificate of Completion, is ready to download.
document.sentThe envelope was initially sent and signing links were issued. Reminders and re-sends do not emit this event.
document.signedA signer completed all of their fields and signed.
document.viewedA viewer marked the document as viewed. A view is not a signature or an approval.

Payload

{
  "id": "evt_outbox_1234",
  "type": "document.signed",
  "created_at": "2026-08-22T12:00:00+00:00",
  "document": "doc_...",
  "mode": "live",
  "data": {
    "seq": 4,
    "engine_event_type": "recipient_completed",
    "actor": {
      "type": "recipient",
      "id": "3f1c…",
      "email": "ada@example.com"
    }
  }
}
idUnique per event, stable across redeliveries. Use it to deduplicate.
typeOne of the types above.
created_atWhen the event happened, ISO 8601 UTC.
documentThe envelope id, as returned by the API.
modelive or test. Endpoints are workspace-level and receive both; a handler that must ignore test traffic checks this member.
dataThe audit-trail event behind this type: its sequence number in the envelope's chain, the engine event name, and the actor.

document.signed, document.approved and document.viewed share this shape and the engine event recipient_completed; the type says which act it was. A recipient with the approver role approves, and an approval is not a signature, so it never produces document.signed. A recipient with the viewer role marks the document as viewed, which is neither, so it produces document.viewed. An endpoint that lists event types needs document.approved and document.viewed in its list to hear approvals and views. document.opened still means a link was opened, by anyone.

{
  "id": "evt_outbox_1235",
  "type": "document.approved",
  "created_at": "2026-08-22T12:05:00+00:00",
  "document": "doc_...",
  "mode": "live",
  "data": {
    "seq": 7,
    "engine_event_type": "recipient_completed",
    "actor": {
      "type": "recipient",
      "id": "8a2d…",
      "email": "grace@example.com"
    }
  }
}

Test pings

POST /v1/webhooks/{id}/ping (or "Send a test ping" in the dashboard) queues one delivery of type ping to that endpoint. It is signed and retried like every other delivery, so it is the way to check a handler end to end before any envelope exists. ping is not an event type: it cannot be subscribed to, and an endpoint's event filter does not apply to it. The body has no document or data member.

{
  "id": "evt_ping_3f9a1c2b7d4e8f01",
  "type": "ping",
  "created_at": "2026-08-23T12:00:00+00:00",
  "mode": "live"
}

Headers

X-SignEnvoy-EventThe event type, repeated from the body (ping for a test ping).
X-SignEnvoy-SignatureHMAC signature of the body; see verifying signatures.
Content-Typeapplication/json
User-AgentSignEnvoy-Webhooks/1.0

Delivery and retries

A delivery succeeds on any 2xx response within 10 seconds. Anything else is retried 7 times, after 30 s, 5 min, 30 min, 2 h, 5 h, 10 h, 10 h: about 28 hours from the first attempt to the last. After 8 attempts the delivery is marked dead. Every attempt, retries and replays included, is signed at the moment it is sent with a fresh t, so your handler can enforce a timestamp tolerance; the payload and its id do not change. Deliveries are not guaranteed to arrive in order; use created_at and data.seq to order events for one envelope. The worker sends at most 150 deliveries a minute to any one endpoint, so a backlog arrives at that pace rather than all at once.

Every delivery is listed under GET /v1/webhooks/{id}/deliveries (?status=dead is the dead-letter view), and GET /v1/webhooks/{id}/deliveries/{delivery_id} returns one with the payload as posted and a record of every attempt: when it was sent, how long it took, the t it was signed with, the status your endpoint returned and up to 4 KiB of its response body. The dashboard's delivery page shows the same. Delivered and dead deliveries, with their attempts, are kept for 30 days after creation (a replay inside that window keeps them another 30); queued deliveries are never removed.

A dead or delivered delivery can be queued again with POST /v1/webhooks/{id}/deliveries/{delivery_id}/redeliver. To replay many at once, POST /v1/webhooks/{id}/deliveries/replay with {"since": "2026-10-10T00:00:00Z", "status": "dead"} (until is optional; "status": "all" includes delivered ones) re-queues up to 1000 deliveries created in the window, oldest first. A replay carries the same id and a fresh signature, so a handler that deduplicates on id is safe to point at it.

Disabled endpoints

A delivery to a disabled endpoint is not attempted and does not count against the schedule: it waits, is looked at again every 30 minutes, and goes out when the endpoint is re-enabled (PATCH /v1/webhooks/{id} with {"active": true}, or "Re-enable" in the dashboard). A delivery that has waited 7 days is marked dead, and can be replayed like any other. No new deliveries are queued for a disabled endpoint.

If every delivery to an endpoint has failed for 3 days, or if fewer than 5% of at least 50 attempts over the last 3 days succeeded, SignEnvoy disables it, records the reason, and emails each workspace owner once. The endpoint's listing carries failing_since, last_success_at, last_failure_at, disabled_reason (auto) and disabled_at, so an integration can watch its own health. Re-enabling clears the markers and sends the waiting deliveries at once; deliveries that went dead in the meantime can be replayed as above.