Webhooks

Learn how to set up webhooks for your application.

How Webhooks Work

cside Webhooks are an easy way to get notifications about important events in your cside account. Webhooks can be used to trigger actions in your application, send messages to your Discord or Slack channels, and more.

When you create a webhook endpoint, we will send a POST request to the URL you have specified. The request will contain a JSON payload with information about the event that triggered the webhook.

The Data Structure

We will always send you a structured JSON payload with the following fields:

Prop

Type

Events

Below is the event IDs and their payloads that will be sent with webhooks.

Event IDs

IDNamedata Object
alert.createdAlert CreatedAlert Object

Event Objects

HMAC Secret (aka x-cside-signature)

We compute an HMAC on the fly, using a SHA256 hash of the payload and your webhook secret that was provided to you when you first created the webhook endpoint. This signature is included in the x-cside-signature header of the request.

WE HIGHLY SUGGEST YOU USE THIS TO VERIFY THE REQUEST IS COMING FROM cside: Not doing so could leave you vulnerable to replay attacks.

Verifying the HMAC secret

If you are using JavaScript, we suggest you use our JavaScript Package to help you verify the signature. We have provided examples on that page that will help you get started with it.

If you are not using JavaScript, you can verify the signature by computing the HMAC SHA256 hash of the request body using your webhook secret, and comparing it to the header (x-cside-signature) that we send with every request.

Here are a few examples in different languages:

async function verifyHmac(body: string, signature: string, secret: string) {	const encoder = new TextEncoder();	const encodedBody = encoder.encode(body);	const key = await crypto.subtle.importKey(		"raw",		encoder.encode(secret),		{ name: "HMAC", hash: "SHA-256" },		false,		["sign"]	);	const signatureBuffer = await crypto.subtle.sign("HMAC", key, encodedBody);	const finalSig = Array.from(new Uint8Array(signatureBuffer))		.map((byte) => byte.toString(16).padStart(2, "0"))		.join("");	return signature.toLowerCase() === finalSig;}
fn verify_hmac(body: &str, signature: &str, secret: &str) -> Result<(), &'static str> {      let mut mac = HmacSha256::new_from_slice(secret.as_bytes()).map_err(|_| "Invalid secret")?;      mac.update(body.as_bytes());      let result = mac.finalize();      let code_bytes = result.into_bytes();      let final_sig = hex::encode(code_bytes);      if signature.to_lowercase() == final_sig {          Ok(())      } else {          Err("Invalid signature")      }  }  // Add to Cargo.toml:  // [dependencies]  // hmac = "0.12"  // sha2 = "0.10"  // hex = "0.4"
package mainimport (  "crypto/hmac"  "crypto/sha256"  "encoding/hex"  "strings")func verifyHmac(body, signature, secret string) bool {	h := hmac.New(sha256.New, []byte(secret))	h.Write([]byte(body))	finalSig := hex.EncodeToString(h.Sum(nil))	return strings.ToLower(signature) == finalSig}
defmodule HmacVerifier do	def verify_hmac(body, signature, secret) do		final_sig =			:crypto.mac(:hmac, :sha256, secret, body)			|> Base.encode16(case: :lower)			String.downcase(signature) == final_sig	endend
import hmacimport hashlibimport secretsdef verify_hmac(body: str, signature: str, secret: str) -> bool:	final_sig = hmac.new(		secret.encode('utf-8'),		body.encode('utf-8'),		hashlib.sha256	).hexdigest()	return signature.lower() == final_sig

How is this doc?

On this page