Webhooks are a way of transmitting events via HTTPS from the source system (RaiseNow) to the back-end of a target web application (e.g. a customer's web server).
The great advantage of webhooks is that they make it possible for remote systems to be actively notified when something happens, instead of having to poll for changes. For instance, a system tracking successful payments can choose to receive a webhook every time the event
payments.payment.succeeded is fired in RaiseNow.
Webhooks are sent as POST requests over HTTPS. The body is a JSON object structured as an envelope, with details on the event itself, and a
data field that contains the full serialised object.
id: UUID of the event itself
name: Full name of the event, like
timestamp: UNIX timestamp in milliseconds
object: Name of the object involved, like
organisation_uuid: UUID of the organisation to which the object belongs, when applicable
account_uuid: UUID of the organisation to which the object belongs, when applicable
securityContext: Internal details about the user or API client that triggered the event
data: The serialised object to which the event refers
View the available events on the RaiseNow Events page.
Subscribing to an event via a webhook
Subscribing to events via webhooks in RaiseNow involves two steps:
- Specifying the endpoint on your system that will receive the webhooks.
- Creating an event subscription to specify which kind of events will be sent to the endpoint.
When registering event subscriptions through Event Subscriptions you currently need to supply the event names in a slightly adjusted form:
A single endpoint can be bound to different event types by having multiple event subscriptions.
The endpoint response body is irrelevant, but it should be smaller than 1 kB.
It is recommended that endpoints respond as quickly as possible. If slow operations are involved, webhooks should be stored locally and processed in a second time.
Failures and retry mechanism
If the endpoint returns a status code in the 2xx range, the webhook is considered to have been delivered successfully. Redirect responses (3xx) will not be followed, so the webhook may be lost. 4xx-5xx status codes, network errors and timeouts will result in the retry mechanism kicking in.
Retries are attempted up to 20 times with increasing delays, from 1 minute to 12 hours. The strategy may change without notification.
The retry mechanism can be disabled by adding the header
x-rnw-no-retry: true to the response of an endpoint.
Checking message authenticity
In order to ensure that the webhooks are really coming from RaiseNow, it is possible to enable Hash-based message authentication code (HMAC) on the endpoints.
If the field
hmac_key is set on an endpoint, the system will use it to compute the SHA-512 HMAC of the JSON-serialised body and write it in the
X-Hmac header of every webhook. When receiving the webhook, the endpoint handler can use the same key to compute the HMAC of the received body, and compare it to the value in the header. If they match, the webhook came from RaiseNow and has not been tampered with.
Choosing between HTTP Basic authentication and HMAC
Trust between RaiseNow and the receiving system can be established by using HTTP Basic authentication over HTTPS, HMAC or both.
HTTP Basic authentication can often be handled by the endpoint's webserver itself or as an out-of-the-box feature of most web application frameworks, so it should be easy to set up, robust and lightweight. Since the data transfer is done via HTTPS, it is not normally possible to intercept the credentials. However, if the endpoint lies behind reverse proxies where the HTTPS connection terminates, it may be possible for an attacker to gain access to the credentials.
Implementing HMAC checks on the endpoint can be more complex, consume more system resources and, if custom code is used, it can be subject to bugs. On the other hand, since the key never leaves the two systems it is more difficult to steal it, and in some cases it is not possible to add HTTP Basic authentication.
In any case, secrets (HMAC key, HTTP credentials) must be hard to guess and stored securely.