Agent skill

MICEtribe Webhooks Skill

Receive and verify MICEtribe webhooks (micetribe.com event registration, badge printing and check-in). Use when setting up a MICEtribe webhook handler, debugging X-Signature verification failures, or handling registration.created, registration.updated, registration.deleted, registration.attended and registration.printed events.

Install this skill

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


When to Use This Skill

  • How do I receive MICEtribe webhooks?
  • How do I verify the MICEtribe X-Signature header?
  • Why is my MICEtribe webhook signature verification failing?
  • How do I handle registration.created or registration.attended events?
  • How do I dedupe MICEtribe webhook deliveries?

Setup note

MICEtribe signs webhooks only when the webhook has a signing secret. Set one on the webhook and paste it here.

Without a signing secret, deliveries carry no X-Signature header and there is nothing to verify.

Verification (core)

X-Signature is the bare lowercase hex HMAC-SHA256 (no prefix) of X-Timestamp + "." + the exact raw request body, keyed with the webhook's signing secret as UTF-8 bytes. Build the signed message as bytes (the X-Timestamp string as latin1, a literal ., the body bytes untouched), validate the signature is exactly 64 hex characters, then compare in constant time. Missing/empty headers, a malformed value or a mismatch is a 401.

const crypto = require('crypto');

function verify(rawBody, signature, timestamp, secret) { // rawBody: Buffer
  if (!signature || !timestamp || !/^[0-9a-fA-F]{64}$/.test(signature)) return false;
  const signed = Buffer.concat([Buffer.from(timestamp, 'latin1'), Buffer.from('.'), rawBody]);
  const expected = crypto.createHmac('sha256', Buffer.from(secret, 'utf8')).update(signed).digest();
  const received = Buffer.from(signature.toLowerCase(), 'hex');
  return received.length === expected.length && crypto.timingSafeEqual(received, expected);
}
import hmac, hashlib, re

def verify(raw_body: bytes, signature: str, timestamp: str, secret: str) -> bool:
    if not signature or not timestamp or not re.fullmatch(r"[0-9a-fA-F]{64}", signature):
        return False
    signed = b"".join([timestamp.encode("latin-1"), b".", raw_body])
    expected = hmac.new(secret.encode("utf-8"), signed, hashlib.sha256).digest()
    return hmac.compare_digest(bytes.fromhex(signature), expected)

Timestamp window (opt-in): X-Timestamp is Unix seconds. MICEtribe lists rejecting old timestamps as optional. The examples do not reject old timestamps by default, because Hookdeck retries and replays resend the original headers and timestamp, and Hookdeck itself applies no tolerance. Set MICETRIBE_WEBHOOK_TOLERANCE_SECONDS (unset or 0 = off) to opt in.

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

MICEtribe has no webhook verification SDK, so verification is manual. Read the body as raw bytes (express.raw({ type: '*/*' }), await request.arrayBuffer(), await request.body()) and parse JSON only after the check. See references/verification.md.

Common Event Types

Dispatch on the body's meta.trigger field.

meta.triggerDescription
registration.createdA new registration is created
registration.updatedAn existing registration is updated
registration.deletedA registration is deleted
registration.attendedAttendance is recorded
registration.printedA badge/registration is printed

For the full reference, see MICEtribe's webhook documentation.

Important Headers

HeaderDescription
X-SignatureHex HMAC-SHA256 of X-Timestamp + . + raw body (only sent when a signing secret is set)
X-TimestampUnix timestamp in seconds used when signing
X-Request-IdUnique UUID for this delivery attempt

Delivery and Idempotency

The request is a POST with a JSON body. A 2xx response is success; 3xx and above, network errors and timeouts (10 seconds) fail. MICEtribe retries up to 5 times, 15 min, 30 min, 3 h, 6 h and 12 h apart (a dispatcher runs every 15 minutes). Process idempotently on registration_id + meta.trigger + X-Request-Id.

Environment Variables

MICETRIBE_WEBHOOK_SECRET=your_webhook_signing_secret   # The signing secret set on the webhook (used as UTF-8)
MICETRIBE_WEBHOOK_TOLERANCE_SECONDS=0                  # Optional; a positive value turns on the X-Timestamp check

Local Development

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

Reference Materials


Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 10, 2026

View on GitHub →