Agent skill

Webex Webhooks Skill

Receive and verify Webex webhooks (formerly Cisco Spark). Use when setting up Webex webhook handlers, debugging X-Spark-Signature verification, or handling events like messages.created, memberships.created, rooms.updated, meetings.started, or attachmentActions.created.

Install this skill

npx skills add hookdeck/webhook-skills --skill webex-webhooks


When to Use This Skill

  • How do I receive Webex webhooks?
  • How do I verify the Webex X-Spark-Signature header?
  • How do I handle messages.created, memberships.created, or meetings.started events?
  • Why is my Webex webhook signature verification failing?
  • Why does the Webex messages webhook have no message text?

Verification (core)

When you create a Webex webhook with the optional secret field, every delivery carries an X-Spark-Signature header: the hex HMAC-SHA1 of the raw request body, keyed with the secret string as-is. There is no timestamp and nothing is prefixed to the body. Compare timing-safe and always hash the raw body — parsing and re-serializing the JSON changes the bytes and breaks the signature.

const crypto = require('crypto');

// Verify the X-Spark-Signature header (hex HMAC-SHA1 of the raw body)
function verifyWebexWebhook(rawBody, signature, secret) {
  if (!signature || !secret) return false;
  const expected = crypto.createHmac('sha1', secret).update(rawBody).digest('hex');
  try {
    return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
  } catch {
    return false; // Length mismatch = invalid
  }
}

Python:

import hmac, hashlib

def verify_webex_webhook(raw_body: bytes, signature: str, secret: str) -> bool:
    if not signature or not secret:
        return False
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha1).hexdigest()
    return hmac.compare_digest(signature, expected)

Webex has no SDK helper for webhook verification, so all three examples verify manually. Some webhook types also send X-Webex-Signature (HMAC-SHA256/SHA512); X-Spark-Signature is sent whenever a secret is set, so this skill verifies that one. See references/verification.md.

For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.

Common Event Types

Webex events are a resource + event pair in the payload. This skill names them resource.event.

EventTriggered When
messages.createdA message is posted in a room you're in (payload has the id only, no text)
messages.deletedA message is deleted from a room you're in
memberships.createdSomeone joins a room, or you're added to one
memberships.deletedSomeone leaves or is removed from a group room
rooms.createdA room is created by you or one of your integrations
rooms.updatedA room is updated (e.g. locked or unlocked)
meetings.startedA meeting starts
meetings.endedA meeting ends
attachmentActions.createdA user submits one of your Adaptive Cards

For the full resource and event list, see Webex Webhooks.

Important Headers and Payload Fields

NameDescription
X-Spark-SignatureHex HMAC-SHA1 of the raw body, present when the webhook has a secret
X-Webex-SignatureHMAC-SHA256/SHA512 on some webhook types only (not used by this skill)
resource / eventBody fields identifying the event, e.g. messages / created
idThe webhook ID, not a unique event ID — don't deduplicate on it alone
dataThe resource object; for messages it omits text, so GET /v1/messages/{id} to fetch it

Environment Variables

WEBEX_WEBHOOK_SECRET=your_webhook_secret   # The `secret` you passed to POST /v1/webhooks

Local Development

# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 webex --path /webhooks/webex

Reference Materials


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 2, 2026

View on GitHub →