A webhook is a lightweight, event-driven communication that automatically sends data between applications via HTTP. Triggered by specific events, webhooks automate communication between application programming interfaces (APIs) and can be used to activate workflows, such as in GitOps environments.
For the purposes of this document, the terms "webhook" and "postback" are used interchangeably.
The Signhost postback service is meant to provide realtime updates on your transactions.
If you cannot implement receiving postback in your application, or if you have any questions about how to implement receiving postbacks, please contact Support.
Your postback endpoint must always return a 2xx HTTP status code (such as 200 OK), even if validation fails or errors occur. Failing to do so will cause Signhost to queue all subsequent postbacks, which can lead to significant delays in receiving transaction updates. See the Recommended Postback Flow section for details.
Signhost will send a postback with the most up-to-date data known at the moment when:
Failed (email bounce) and SignedDocumentSent are used for receivers.There are two ways of creating postbacks that will be used to deliver postback messages to:
You can register a posback URL on the Postbacks page of the Signhost portal. Global Postback URLs will be used for every transaction.
This method supports both digest security and security headers.
The Postbacks page allows you to easily manage postbacks, check for any queued requests, and use security features such as the Authorization header and Checksum calculation. For more information, see the Security section.
When you create a postback URL, we automatically test if your endpoint is available by sending an empty POST request.
You can dynamically specify a postback URL for a specific transaction by providing one in the PostbackUrl property of the transaction object when creating a transaction.
This functionality is meant for separating the postbacks into different 'buckets' that would make sense for your implementation, for example to differentiate between different environments (staging, production, etc.) or different departments (sales, HR, etc.).
This functionality is not meant to separate postbacks per transaction as this circumvents the postback queueing system. Your business logic should be able to differentiate between postbacks based on the transaction ID. Signhost reserves the right to block postback URLs if this feature is repeatedly abused.
Dynamic Postback URLs do NOT support digest security or security headers.
If you configure both a Global Postback URL and a Dynamic Postback URL for a transaction, postbacks will be delivered to both endpoints. Each postback URL acts as a subscriber at different scopes:
This allows you to receive postbacks at multiple endpoints simultaneously if needed for your integration architecture.
Signhost recommends the following flow once a postback arrives at your server:
Your endpoint must always return an HTTP 2xx status code (typically 200 OK), regardless of whether validation succeeds or fails. This is a critical security precaution that prevents information about your validation process from being returned to a potentially malicious sender.
Any response other than 2xx will cause Signhost to queue all subsequent postbacks, leading to delays in receiving transaction updates. See Error Handling for more details.
This is one of the most common issues encountered by API users. Even if your validation fails, return 200 OK and handle the invalid postback internally (e.g., log it, discard it, or alert your team).
If your postback URL returns a non 2xx HTTP status code, Signhost will queue any new postbacks.
Sighost will retry to deliver the first failed postback with an increasing interval (the first retry is within a few minutes).
After 5 successive failed attempts, Signhost will send you an email which will include an attachment with the received response (if any).
When Signhost receives a 2xx HTTP status code, the postback URL will be marked as available and resume sending the queued postbacks.
To guarantee performance and uptime, and make sure there is no data loss, it's possible that that may you receive the same postback twice. This can happen because our system consists of multiple instances and there is no deduplication. By checking if the postback from instance one is already sent from instance two, we would re-introduce a single point of failure. Furthermore, it is possible to receive postbacks containing statuses or activities after a signer signed, or after the entire transaction is marked as signed. Your system will have to handle these scenarios.
A postback is sent out when either the Transaction Status changes or a Signer Activity occurs. A postback contains only one transaction status however a signer object will contain the full list of all signer activities which have taken place. This can help you track all of the activities which have taken place for each individual signers in a transaction.
A transaction has an overall status. This is the status of the entire transaction such as signed or rejected.
A full list of all Transaction Statuses can be found at the Status & Activities page.
A few scenarios around transaction status postbacks:
A transaction is created, and two documents are attached.
The transaction will still be in status 5 (waiting for document).
You need to start the transaction so Signhost knows you have finished uploading files.
A transaction with two signers is signed by the first signer.
The transaction status is still 10 (waiting for signer) because Signer 2 still needs to sign!
After end statuses such as 30 (signed), 40 (rejected), 50 (expired), 60 (cancelled), 70 (failed) you can still receive postbacks with signer activities as people might click the invite link again or download signed documents.
Transaction status postbacks can be identified via a combination of the Transaction ID, Status code and Checksum.
Multiple postbacks with the same combination of these variables might arrive because you will receive multiple signer activities falling under the same transaction status.
In addition to the overall transaction status, for each signer that is involved in a transaction, there is a list of activities that the user has performed. This details what an individual person has done in their signing session.
A full list of all the Signer Activities can be found at the Status & Activities page.
A Signer Activity details what interactions a specific person had with the transaction and the documents within. These activities give real-time insight in the full audit trail of what a signer has done to come to a signed document and can be used in your business logic and dashboarding to provide extra information to your users.
A signer who checked a document five times but still hasn't signed, might trigger a signal for you to give them a call.
A few scenarios around signer activity postbacks:
In a transaction with two signers, Signer 1 and Signer 2. Signer 1 has signed the document. Signer 2 still has yet to sign the document.
Your system receives a postback with signer activity status 203 (signed) for Signer 1.
After signing, the Signer 1 goes back to their email, and clicks the invite link again.
You will receive a subsequent posback with status 103 (opened) for Signer 1 but that still means Signer 1 has already signed the document.
Due to the queuing processes in both Signhost and your application, you might receive the signer activity postback for 'signed' (203) and 'document opened' (105) at the same time. That still means that Signer 1 has signed the document.
Signer activities can be identified via a combination of Activity ID, Status code and CreatedDateTime.
Your business logic can use signer activities to trigger subsequent actions. For example, if you are using the Direct Flow for delivering transactions, and you want to invite Signer 2 after Signer 1 signed, you can rely on the signer activity 203 (signed) for Signer 1 to trigger sending the transaction to Signer 2. Make sure that subsequent signer activities or duplicate postbacks after the first 203 (signed) do not overwrite or retrigger any invitations.
Note that the signer activity 203 (signed) only indicates that the signer completed the sign flow with the intent of signing the document.
The fully signed document is only available once Signhost completes the processing of the document and the transaction reaches status 30 (signed).
Signhost offers two methods to secure postbacks:
This can be any string that you enter while registering the postback URL.
Postbacks sent from Signhost will include this string in the Authorization header of the HTTP POST message. This ensures that the request came from Signhost.
This involves calculating a checksum using the transaction ID, transaction status, and a shared secret. You will receive the shared secret only once when registering your Postback URL.
Postbacks sent from Signhost will include the checksum in the Checksum header of the HTTP POST message. This ensures that the contents of the message have not been altered or tampered with.
IP whitelisting and certificate pinning should not be used as security measures because they are not always reliable. All security measures can be found and configured on the Postbacks page in the Signhost portal.
The checksum is calculated using the following formula:
Checksum = SHA1(transaction id + || + status + | + sharedsecret)
There is a double "pipe" sign between the transaction id and the status. If you are still using our legacy API - you are seeing a File object in your postback and get responses - you'll have to include the file id at this location. eg
Checksum = SHA1(transaction id + | + file id + | + status + | + sharedsecret)
The "pipe" sign ( | ) is used as the delimiter between values. You may need to put the delimiters between single quotes (') or double quotes (") depending on the programming language that you will be using. The value returned by the SHA1 function is a string of 40 characters representing a hexadecimal value. How to use the SHA1 algorithm depends on your development platform. Most languages and frameworks (such as PHP, ASP.NET, Python, Java, JavaScript) have built-in implementations of the SHA1 algorithm. For other languages, such as classic ASP, Open Source implementations of the SHA1 algorithm are available online.
Signhost strongly urges you to protect your account by only returning an HTTP 2xx response code, even if an expected security header or checksum does not match. Failing to do so could potentially allow attackers to probe your security measures or cause the formation of queues that could impact the performance of your system.
If the webhook URL doesn't return a 2xx HTTP response code, that POST request will be re-attempted with a random increasing interval.
All following postbacks will be put in a postback queue, and will wait there untill the first postback in the queue gets a 2xx HTTP response code.
If a particular POST request is unsuccessful and is being retried, no other POSTs will be attempted until the first one succeeds or is marked as failed. Requests are marked failed and removed from the queue after 48-72 hours of unsuccessful retry attempts. Subsequent postbacks are deferred until the first completes. Once the first postback request completes the deferred requests will be processed sequentially.