with one click
cursor-webhooks
Receive and verify Cursor Cloud Agent webhooks. Use when setting up Cursor webhook handlers, debugging signature verification, or handling Cloud Agent status change events (ERROR, FINISHED).
Menu
Receive and verify Cursor Cloud Agent webhooks. Use when setting up Cursor webhook handlers, debugging signature verification, or handling Cloud Agent status change events (ERROR, FINISHED).
Audit the developer experience of any platform that sends outbound webhooks or event destinations to its customers, and produce a structured YAML audit file with scored findings and prioritized recommendations. Use whenever the task is to review, assess, grade, or critique a company's webhook/event- delivery DX: their signup and onboarding, signing and verification, retry and delivery semantics, event catalog and payloads, setup surfaces (UI/API/CLI/IaC/SDK), consumer-facing observability, local dev, and local-to-production transition. Trigger this for a 'webhook DX review', 'event destinations audit', or an 'outbound webhook assessment', even if the user names a specific company (e.g. 'review Acme's webhooks') rather than the word audit. The output is a YAML audit file conforming to `schema/audit.schema.yaml`; whoever consumes it downstream renders their own presentation.
Receive and verify Knock outbound webhooks. Use when setting up Knock webhook handlers, debugging x-knock-signature verification, or handling notification events like message.sent, message.delivered, message.bounced, message.read, workflow.committed, or message.link_clicked.
Receive and verify Scrapfly webhooks. Use when setting up Scrapfly webhook handlers for async scrape, extraction, screenshot, or crawler jobs, debugging X-Scrapfly-Webhook-Signature verification, or routing on X-Scrapfly-Webhook-Resource-Type.
Receive and verify Orb webhooks. Use when setting up Orb webhook handlers, debugging Orb signature verification, or handling usage-based billing events like invoice.issued, subscription.created, or customer.credit_balance_dropped.
Receive and verify Twilio webhooks. Use when setting up Twilio webhook handlers, debugging X-Twilio-Signature verification, or handling communications events like incoming SMS, voice calls, message status callbacks (delivered, failed), or recording status callbacks.
Receive and verify Slack Events API webhooks. Use when setting up Slack webhook handlers, debugging Slack signature verification, handling the url_verification challenge, or processing events like app_mention, message, reaction_added, team_join, or app_home_opened.
| name | cursor-webhooks |
| description | Receive and verify Cursor Cloud Agent webhooks. Use when setting up Cursor webhook handlers, debugging signature verification, or handling Cloud Agent status change events (ERROR, FINISHED). |
| license | MIT |
| metadata | {"author":"hookdeck","version":"0.1.0","repository":"https://github.com/hookdeck/webhook-skills"} |
const crypto = require('crypto');
function verifyCursorWebhook(rawBody, signatureHeader, secret) {
if (!signatureHeader || !secret) return false;
// Cursor sends: sha256=xxxx
const [algorithm, signature] = signatureHeader.split('=');
if (algorithm !== 'sha256') return false;
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
try {
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
} catch {
return false;
}
}
const express = require('express');
const app = express();
// CRITICAL: Use express.raw() - Cursor requires raw body for signature verification
app.post('/webhooks/cursor',
express.raw({ type: 'application/json' }),
(req, res) => {
const signature = req.headers['x-webhook-signature'];
const webhookId = req.headers['x-webhook-id'];
const event = req.headers['x-webhook-event'];
// Verify signature
if (!verifyCursorWebhook(req.body, signature, process.env.CURSOR_WEBHOOK_SECRET)) {
console.error('Cursor signature verification failed');
return res.status(401).send('Invalid signature');
}
// Parse payload after verification
const payload = JSON.parse(req.body.toString());
console.log(`Received ${event} (id: ${webhookId})`);
// Handle status changes
if (event === 'statusChange') {
console.log(`Agent ${payload.id} status: ${payload.status}`);
if (payload.status === 'FINISHED') {
console.log(`Summary: ${payload.summary}`);
} else if (payload.status === 'ERROR') {
console.error(`Agent error for ${payload.id}`);
}
}
res.json({ received: true });
}
);
import hmac
import hashlib
from fastapi import Request, HTTPException
def verify_cursor_webhook(body: bytes, signature_header: str, secret: str) -> bool:
if not signature_header or not secret:
return False
# Cursor sends: sha256=xxxx
parts = signature_header.split('=')
if len(parts) != 2 or parts[0] != 'sha256':
return False
signature = parts[1]
expected = hmac.new(
secret.encode(),
body,
hashlib.sha256
).hexdigest()
# Timing-safe comparison
return hmac.compare_digest(signature, expected)
| Event Type | Description | Common Use Cases |
|---|---|---|
statusChange | Agent status changed | Monitor agent completion, handle errors |
{
"event": "statusChange",
"timestamp": "2024-01-01T12:00:00.000Z",
"id": "agent_123456",
"status": "FINISHED", // or "ERROR"
"source": {
"repository": "https://github.com/user/repo",
"ref": "main"
},
"target": {
"url": "https://github.com/user/repo/pull/123",
"branchName": "feature-branch",
"prUrl": "https://github.com/user/repo/pull/123"
},
"summary": "Updated 3 files and fixed linting errors"
}
# Your Cursor webhook signing secret
CURSOR_WEBHOOK_SECRET=your_webhook_secret_here
For local webhook testing, install Hookdeck CLI:
Then start the tunnel:
npx hookdeck-cli listen 3000 cursor --path /webhooks/cursor
No account required. Provides local tunnel + web UI for inspecting requests.
overview.md - What Cursor webhooks are, event typessetup.md - Configure webhooks in Cursor dashboardverification.md - Signature verification details and gotchasexamples/ - Runnable examples per frameworkFor production-ready webhook handling, also use the webhook-handler-patterns skill: