Looking for per-request notifications on asynchronous PDF Services jobs instead?
See Callbacks. The two mechanisms are
configured differently and are not interchangeable.
Overview
Nitro allows applications added to the API service to register a webhook URL to receive notifications of real-time events in the platform.How to register a webhook
Webhooks are managed per API Application in the Nitro Admin Portal. One webhook is permitted per application, though the same endpoint URL can be reused across multiple applications. To register a webhook:1
Open your application
In the Admin Portal, go to your API Application’s details and select Add Webhook.
2
Enter your endpoint URL
Enter your webhook URL. You can select Test Webhook at this point to confirm your endpoint is reachable before continuing.
3
Choose your events
Select Continue, then choose which event types you want to subscribe to. Create is enabled once at least one event is selected.
4
Save your client secret
On creation, Nitro generates a client secret for your webhook.Your client secret is used to verify incoming event signatures. See Security and Verification.
Store your Client Secret in a secure location. Do not save it on personal devices, mobile phones, shared folders, or source code repositories. Instead, use a secrets manager to store it and expose it to your application using that manager’s best practices.
Editing a webhook
From your application’s details, select Edit Webhook. The URL and event fields become editable, and Test and Delete are disabled while you’re editing. Select Save Changes once your URL is valid and at least one event is selected, or cancel to revert without saving.Deleting a webhook
Select Delete Webhook, then confirm in the dialog. This immediately stops all event delivery to that endpoint. You’ll need to add a new webhook to resume receiving events.Deleting a webhook does not affect past deliveries or in-flight retries already queued at the time of deletion.
After Registration
Once your webhook is registered, we recommend the following best practices:- Scope down events Only subscribe to events that your application needs to handle. This helps reduce unnecessary load on both your server and the Nitro system.
-
Test your webhook
Select Test Webhook from your application’s details at any time to confirm your endpoint is responsive.
- A successful test returns: “Test event delivered successfully. Your endpoint is responsive.”
- A failed test (4xx, 5xx, or timeout) returns: “Test event could not be delivered.”
Handling Events
Event Payload
When events occur on your application, Nitro will send a POST request to your webhook URL with a JSON payload containing event details and data. The JSON payload will have the following structure:id: The event’s unique id.type: Enum of the event’s type. Possible values:EnvelopeCreated,EnvelopeDocumentAdded,EnvelopeDocumentDeleted,EnvelopeSentForSignature,EnvelopeCancelled,SignatureRequestReassigned,SignatureRequestDeclined,SignatureRequestSigned,EnvelopeSigningCompleted,EnvelopeSealed,OwnerMessaged.created: UTC timestamp of the creation of the event.data: An object with the minimum relevant data for the event. If your process requires additional data, you have to request it via the API.
Event Types
The JSON payload of the event will have the following object structure, with thedata field varying depending on the event type.
EnvelopeCreated
EnvelopeCreated
The envelope has been created.
EnvelopeDocumentAdded
EnvelopeDocumentAdded
A document has been uploaded and attached to the envelope.
EnvelopeDocumentDeleted
EnvelopeDocumentDeleted
A document has been deleted from an envelope.
EnvelopeSentForSignature
EnvelopeSentForSignature
An envelope has been sent for signature.
EnvelopeCancelled
EnvelopeCancelled
The envelope has been cancelled by the owner.
SignatureRequestReassigned
SignatureRequestReassigned
A signature request has been forwarded to another participant.
SignatureRequestDeclined
SignatureRequestDeclined
A signature request has been declined.
SignatureRequestSigned
SignatureRequestSigned
A participant has signed the envelope.
EnvelopeSigningCompleted
EnvelopeSigningCompleted
All participants have signed and sealing will start.
EnvelopeSealed
EnvelopeSealed
The envelope is sealed and digitally signed. No further changes can be made.
OwnerMessaged
OwnerMessaged
The owner received a message from one of the signers.
Webhook’s Response
When delivering events, our system interprets your webhook’s response code as follows:- 2xx responses: Any response in the 200–299 range is treated as a success. No further delivery attempts are made.
- 4xx responses: Any response in the 400–499 range indicates the request reached your server. These are treated as acknowledged, and no further delivery attempts are made.
- 5xx responses or network errors: Responses in the 500–599 range, or network failures, are considered temporary errors. Nitro will retry event delivery.
Backwards Compatibility
Events are implemented with backward compatibility, similar to the Nitro API. This means there is no versioning for Events. Once your event handlers are implemented, you can expect them to continue working reliably. Any data added to support new features will be included as optional fields, which can be ignored if your application does not require them.Event Ordering
The delivery order of events is not guaranteed to match the real-world order of occurrence. In most cases, events will arrive in the same sequence as the actions that triggered them. However, network conditions, retries, and asynchronous processes may result in out-of-order delivery. For example, when the last participant signs an envelope, you might receive events in this order:EnvelopeSigningCompleteSignatureRequestSigned
SignatureRequestSigned event represents the last signer completing their signature, which logically happens before the EnvelopeSigningComplete event. Because these actions occur almost simultaneously, the events are sometimes delivered in the reverse order.
We recommend that your application does not rely on strict event ordering:
- Use unique event IDs to de-duplicate and track processing.
- Derive the current status from the event payload (timestamps, resource state), not from the event order.
- Design handlers to be idempotent and resilient to out-of-order messages.
- Store events as data points and replay them in your system if needed.
Fault tolerance
We will make a best effort to deliver webhook events reliably. In cases where delivery to your endpoint does not succeed, our system will retry sending the event. Retries apply only to5xx responses and network errors. 2xx and 4xx responses are final and are never retried.
Each event gets up to 5 delivery attempts in total — the initial attempt plus 4 retries — with an exponentially increasing delay between them:
If the 5th attempt also fails, the event is marked as failed and is not retried again. Because retries can span roughly 15 minutes, a recovering endpoint may receive an event well after the action that triggered it.
Event handler recommendations
- Idempotency In general we recommend that the endpoint implementation is idempotent and resilient to temporary delivery delays.
- Response time: Your server should respond within 15 seconds. Requests that exceed this time will be treated as failed.
-
Asynchronous Processing:
Your endpoint should return a
2xxresponse as quickly as possible to acknowledge receipt of the event. Avoid performing heavy or time-consuming operations (e.g., database writes, external API calls) before sending this acknowledgement. If additional work is required, enqueue it for asynchronous processing after the acknowledgement has been sent.
Security and Verification
SSL Certificates
Your webhook’s server requires a valid SSL certificate in order to receive events from Nitro.Signature Headers
Nitro signs webhook events using cryptographic signatures to guarantee their authenticity and integrity, following the RFC 9421 standard. To validate an event, generate a cryptographic signature using the event headers together with your client secret key and then compare this signature with the one included in the event headers. Matching signatures confirm that the event originated from Nitro and that its contents have not been altered. Follow these steps to implement signature validation:1
Extract data from headers
The event will include these three headers:Where:
- Content-Digest: A SHA-256 hash of the request body, base64-encoded.
- Signature-Input: Signature parameters and metadata of signing method.
- Signature: The cryptographic signature you will later compare.
2
Construct a canonical representation
Using the header data, build a canonical representation of the signed components as a single continuous string, making sure to follow the exact order defined in the Signature-Input header.At the end, append a line for signature parameters (created, keyid, alg) as per RFC 9421.The final result should look like this::When writing the string in code, represent line breaks with \n. For example:
3
Apply Canonicalization rules (format the string)
The string must be formatted according to strict rules below. Any deviation will produce a different signature. Once formatted, the result is called the
signature_base_string, which will be the dynamic portion of the cryptographic signature.- Convert all header names to lowercase.
- Remove leading/trailing whitespace from values.
- Normalize internal whitespace.
- If a header has multiple values, join them with commas.
- Maintain the exact order specified in Signature-Input.
4
Generate signature
With the
signature_base_string ready, apply the following formula in your code to generate the expected signature:expected_signature = base64encode(hmac_sha256(your_secret_key, signature_base_string))5
Compare signature values
Compare the signature you generated with the value in the Signature header. A match confirms that the event is authentic and that its contents have not been altered.