Webhooks allow apps to receive HTTP callbacks in real-time when events happen in Hootsuite rather than having to periodically poll the REST API.
Registering
The webhooks URL you use has several restrictions placed on it. It must:
- Resolve to a public IP address not owned by Hootsuite (for example, it must not be in the internal network ranges defined in RFC 1918/RFC 4193 or the link-local ranges defined in RFC 3927/RFC 4291)
- Accept traffic on either port
80
or8080
forhttp
or443
or8443
forhttps
. - Return a response no larger than
32KB
.
Ad-hoc webhooks URL can be provided when scheduling a message through the publishing API via the webhookUrls
parameter.
A webhooks URL for Organization Apps can be configured through My Apps. These apps will then be notified in real-time when events occur related to organizations that install the app.
Receiving Data
Hootsuite will make a HTTP POST
request to the configured webhooks URL. Event data will be aggregated and sent in a batch at most once every 5
seconds, or when the number of events exceeds 100
. We expect your webhooks URLs to quickly respond (in less than 10
seconds) with a successful HTTP response (anything in the 200-299
range). You should return an empty body with your response.
Error Handling
See Error Handling for details on how Hootsuite handles failed webhook requests.
Payload Format
The webhook POST
request body will have a Content Type of application/json
and contain a JSON Array
of Event
objects.
The Event
object has the following fields:
Field | Description | Type |
---|---|---|
| String representation of a 64-bit sequence number that will be different for each event. This can be used to deduplicate events that may occur as a result of retries. |
|
| A string that indicates the type of event. This will determine what the format of the data field is. |
|
| The actual event data. The contents of this depend on the type of event. |
|
[
{
"seq_no": "123",
"type": "some.type.here",
"data": {
// data specific to the event type
}
},
// ... up to 100 of these
]
Payload Verification
Webhook POST
requests may also include the following headers that can be used to verify the integrity of the request:
X-Hootsuite-Timestamp
(All webhooks) - Unix timestamp in milliseconds of when the request was sentX-Hootsuite-Signature
(Organization Apps only) - Digital signature that can be used to verify that the contents of the request have not been tampered with.
The X-Hootsuite-Signature
header value is calculated as follows:
- Concatenate the value of the
X-Hootsuite-Timestamp
header and thePOST
body. - Calculate a
SHA-512 HMAC
hex digest on the bytes of that value (as a UTF-8 encoded string) using the Organization App's shared secret as the key. These shared secrets can be configured through My Apps.
For more information on the HMAC algorithm, see RFC 2104
You can perform the same calculation and compare the value against the contents of the X-Hootsuite-Signature
define('APP_SECRET', 'this_is_my_secret');
function verify_webhook_signature($sig, $timestamp, $body)
{
$calculated = bin2hex(hash_hmac('sha512', $timestamp.$data, APP_SECRET, true));
return ($sig == $calculated);
}
$signature = $_SERVER['HTTP_X_HOOTSUITE_SIGNATURE'];
$timestamp = $_SERVER['HTTP_X_HOOTSUITE_TIMESTAMP'];
$data = file_get_contents('php://input');
$verified = verify_signature($signature, $timestamp, $data);
package verification
import (
"crypto/hmac"
"crypto/sha512"
"encoding/hex"
)
const (
appSecret = "secret"
)
func VerifyWebhookSignature(signature string, timestamp string, body []byte) bool {
h := hmac.New(sha512.New, []byte(appSecret))
h.Write([]byte(timestamp))
h.Write(body)
return hex.EncodeToString(h.Sum(nil)) == signature
}
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
object Verifier {
private val secret = new SecretKeySpec("secret".getBytes, "HmacSHA512")
def verifyWebhookSignature(signature: String, timestamp: String, body: Array[Byte]): Boolean = {
val mac = Mac.getInstance("HmacSHA512")
mac.init(secret)
mac.update(timestamp.getBytes)
mac.doFinal(body).map(b => "%02X".format(b)).mkString.toLowerCase == signature
}
}
Whitelisting Hootsuite Server IPs
All Hootsuite webhook requests originate from a static set of IP addresses. If your server handing webhook requests is behind a firewall, you will need to whitelist
the following set of IP addresses to ensure that requests succeed:
52.200.215.209
52.200.216.126
52.200.216.124
Event Types
See Event Reference for a list of events produced by Hootsuite
Updated about a year ago