Lucidchart webhooks events
'Webhooks Events for Lucidchart.From its SKILL.md
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill lucidchart-webhooks-eventsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its file declares
Copied from the file, not written here
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
5.4 KB, ~1.3k tokens by cl100k_base, as published. Nobody here has run it
Lucidchart Webhooks & Events
Overview
Lucidchart delivers real-time webhook notifications when documents, shapes, and collaboration states change across your organization's diagramming workspace. These events power integrations such as auto-archiving diagrams to Confluence when finalized, notifying Slack channels when collaborators join a shared document, triggering CI pipelines when architecture diagrams are updated, and maintaining audit logs of all document access. Payloads are signed JSON delivered over HTTPS using a webhook signing secret.
Prerequisites
- A Lucid developer account with an OAuth2 app registered at
developer.lucid.co - Webhook endpoint URL accessible over HTTPS (TLS 1.2+)
- Webhook signing secret from the Lucid app settings (
LUCID_WEBHOOK_SECRET) - Express.js with raw body parsing for signature verification
Webhook Registration
import axios from "axios";
const res = await axios.post(
"https://api.lucid.co/v1/webhooks",
{
callbackUrl: "https://your-app.com/webhooks/lucidchart",
events: ["document.created", "document.updated", "document.shared",
"shape.added", "collaborator.joined"],
scope: "account",
},
{ headers: { Authorization: `Bearer ${process.env.LUCID_ACCESS_TOKEN}`,
"Lucid-Api-Version": "1" } }
);
console.log("Webhook ID:", res.data.webhookId);
Signature Verification
import crypto from "crypto";
import { Request, Response, NextFunction } from "express";
function verifyLucidSignature(req: Request, res: Response, next: NextFunction) {
const signature = req.headers["x-lucid-signature"] as string;
const requestId = req.headers["x-lucid-request-id"] as string;
if (!signature || !requestId) return res.status(401).send("Missing signature");
const expected = crypto
.createHmac("sha256", process.env.LUCID_WEBHOOK_SECRET!)
.update((req as any).rawBody)
.digest("base64");
if (!crypto.timingSafeEqual(Buffer.from(signature, "base64"), Buffer.from(expected, "base64"))) {
return res.status(403).send("Invalid signature");
}
next();
}
Event Handler
app.post("/webhooks/lucidchart", verifyLucidSignature, (req, res) => {
const { eventType, data, timestamp } = req.body;
switch (eventType) {
case "document.created":
console.log(`New doc: "${data.title}" by ${data.creatorId} in ${data.folderId}`);
break;
case "document.updated":
console.log(`Doc updated: ${data.documentId}, pages: ${data.pageCount}`);
break;
case "document.shared":
console.log(`Doc shared: ${data.documentId} → ${data.recipientEmail} (${data.permission})`);
break;
case "shape.added":
console.log(`Shape: ${data.shapeType} on page ${data.pageId} of doc ${data.documentId}`);
break;
case "collaborator.joined":
console.log(`${data.userId} joined doc ${data.documentId} as ${data.role}`);
break;
default:
console.warn(`Unhandled event: ${eventType}`);
}
res.status(200).json({ ok: true });
});
Event Types
| Event | Payload Fields | Use Case |
|---|---|---|
document.created | documentId, title, creatorId, folderId, templateId | Index new diagrams in search or notify team channels |
document.updated | documentId, pageCount, lastEditedBy, editSummary | Trigger CI when architecture diagrams change |
document.shared | documentId, recipientEmail, permission, sharedBy | Audit external sharing for compliance |
shape.added | documentId, pageId, shapeType, shapeId, position | Track diagram complexity metrics |
collaborator.joined | documentId, userId, role, joinedAt | Post Slack notifications for live collaboration |
document.deleted | documentId, deletedBy, deletedAt | Remove stale references from linked systems |
Retry & Idempotency
const seen = new Set<string>();
function ensureIdempotent(req: Request, res: Response, next: NextFunction) {
const requestId = req.headers["x-lucid-request-id"] as string;
if (seen.has(requestId)) {
return res.status(200).json({ duplicate: true });
}
seen.add(requestId);
next();
}
// Lucid retries failed deliveries 3 times with exponential backoff (1 min, 5 min, 30 min).
// After 3 consecutive failures the webhook is marked inactive and must be re-enabled via API.
Error Handling
| Issue | Cause | Fix |
|---|---|---|
| 403 on signature check | Signing secret regenerated in Lucid dashboard | Update LUCID_WEBHOOK_SECRET and redeploy |
| Events arrive for wrong account | Webhook scope set to user instead of account | Re-register with "scope": "account" |
shape.added floods endpoint | Busy diagram with many rapid edits | Debounce by documentId with a 5-second window |
| Webhook marked inactive | Endpoint returned errors for 3 retries | Fix endpoint, then PATCH webhook status to active |
Missing Lucid-Api-Version header | API version not pinned | Always include "Lucid-Api-Version": "1" in registration |
Resources
Next Steps
See lucidchart-security-basics.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.