Clerk Webhooks
vvedantb/eva
Clerk webhooks for real-time events and data syncing. An agent skill from vvedantb/eva.
Clerk webhooks for real-time events and data syncing. An agent skill from geekskai/blog.
$ npx skills add geekskai/blog --skill clerk-webhooks -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install geekskai/blog clerk-webhooks --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/geekskai/blog.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/clerk-webhooks .claude/skills/clerk-webhooks && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "clerk-webhooks" agent skill from https://github.com/geekskai/blog/tree/main/.agents/skills/clerk-webhooks into .claude/skills/clerk-webhooks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "clerk-webhooks", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/geekskai/blog/tree/main/.agents/skills/clerk-webhooksType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add geekskai/blog --skill clerk-webhooks -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install geekskai/blog clerk-webhooks --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/geekskai/blog.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/clerk-webhooks .agents/skills/clerk-webhooks && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "clerk-webhooks" agent skill from https://github.com/geekskai/blog/tree/main/.agents/skills/clerk-webhooks into .agents/skills/clerk-webhooks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "clerk-webhooks", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add geekskai/blog --skill clerk-webhooks -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install geekskai/blog clerk-webhooks --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/geekskai/blog.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/clerk-webhooks .cursor/skills/clerk-webhooks && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "clerk-webhooks" agent skill from https://github.com/geekskai/blog/tree/main/.agents/skills/clerk-webhooks into .cursor/skills/clerk-webhooks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "clerk-webhooks", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/geekskai/blog.git --path .agents/skills/clerk-webhooks--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add geekskai/blog --skill clerk-webhooks -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install geekskai/blog clerk-webhooks --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/geekskai/blog.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/clerk-webhooks .gemini/skills/clerk-webhooks && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "clerk-webhooks" agent skill from https://github.com/geekskai/blog/tree/main/.agents/skills/clerk-webhooks into .gemini/skills/clerk-webhooks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "clerk-webhooks", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install geekskai/blog clerk-webhooksInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add geekskai/blog --skill clerk-webhooks -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/geekskai/blog.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/clerk-webhooks .github/skills/clerk-webhooks && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "clerk-webhooks" agent skill from https://github.com/geekskai/blog/tree/main/.agents/skills/clerk-webhooks into .github/skills/clerk-webhooks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "clerk-webhooks", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add geekskai/blog --skill clerk-webhooks -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install geekskai/blog clerk-webhooks --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/geekskai/blog.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/clerk-webhooks .opencode/skills/clerk-webhooks && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "clerk-webhooks" agent skill from https://github.com/geekskai/blog/tree/main/.agents/skills/clerk-webhooks into .opencode/skills/clerk-webhooks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "clerk-webhooks", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
clerk-webhooksClerk webhooks for real-time events and data syncing. An agent skill from geekskai/blog.
Clerk Webhooks is an agent skill from geekskai/blog. Clerk webhooks for real-time events and data syncing. Verify with verifyWebhook from the framework-specific package. Handle user, session, organization, billing, and payment events. Build event-driven features like database sync, notifications, and integrations.
Its SKILL.md is about 3.4k tokens, which your agent loads only when the skill is triggered. The skill folder holds 4 other files, including reference files (for example `evals/evals.json` and `references/frameworks.md`). Compatibility notes: Requires CLERKWEBHOOKSIGNINGSECRET (svix signing secret from Clerk dashboard)
It sits in Backend & APIs, covering Webhooks and Event-driven systems. It works with Clerk. The repository describes itself as: 🚀 2026 Most Popular FREE Blog Template! Next.js 14, Zero Code - Just Write & Deploy | 2026最火免费博客模板!支持Markdown,一键部署,极致性能!⚡️ ✨ Write in Markdown, get your professional blog in…. The licence is MIT.
Read from SKILL.md and the folder at commit e5554c5. It shows what the files ask for, not the result of running them.
Pre-approves these tools, so the agent can use them without asking each time:
WebFetchFrom allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript and bash).
From the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
webhooks.clerk.comAlso links to:
clerk.comdocs.svix.comFrom URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
CLERK_WEBHOOK_SIGNING_SECRETRESEND_API_KEYFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Requires CLERK_WEBHOOK_SIGNING_SECRET (svix signing secret from Clerk dashboard)
From compatibility in the SKILL.md frontmatter.
Clerk Webhooks loads about 3.4k tokens when it runs, and up to ~4.9k if it reads all its reference files. Until then it costs about 69 tokens; SKILL.md has 659 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from geekskai/blog at commit e5554c5, republished under its MIT licence (© geekskai). 659 words, ~3,390 tokens.
.claude/skills/clerk-webhooks/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.Output complete, working webhook handlers with verifyWebhook(req) verification in every handler.
Webhooks are asynchronous and eventually consistent. Delivery is fast but not guaranteed to be immediate, and may occasionally fail (Svix retries on a fixed schedule). Use them for:
Do NOT rely on webhook delivery as part of a synchronous flow such as onboarding ("user signs up, then we read X from our DB"). For data the user just created, read it from the Clerk session token or call the Backend API directly. Webhooks fill the gap when you need data about other users or events the session token doesn't carry.
Use verifyWebhook(req) from the framework-specific package (@clerk/nextjs/webhooks, @clerk/express/webhooks, etc.). It reads CLERK_WEBHOOK_SIGNING_SECRET automatically and throws on bad signatures. Skipping verification, even for notification-only handlers, exposes the endpoint to spoofed events.
Webhook routes must be excluded from Clerk middleware protection. Without this, Clerk returns 401.
// proxy.ts (Next.js <=15: middleware.ts)
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'
const isPublicRoute = createRouteMatcher(['/api/webhooks(.*)'])
export default clerkMiddleware(async (auth, req) => {
if (!isPublicRoute(req)) await auth.protect()
})// app/api/webhooks/route.ts
import { verifyWebhook } from '@clerk/nextjs/webhooks'
import { NextRequest } from 'next/server'
import { db } from '@/lib/db'
export async function POST(req: NextRequest) {
// ALWAYS verify - never skip, even for notification-only handlers
let evt
try {
evt = await verifyWebhook(req) // uses CLERK_WEBHOOK_SIGNING_SECRET automatically
} catch (err) {
console.error('Webhook verification failed:', err)
return new Response('Verification failed', { status: 400 })
}
if (evt.type === 'user.created') {
const { id, email_addresses, first_name, last_name } = evt.data
const email = email_addresses[0]?.email_address
const name = `${first_name ?? ''} ${last_name ?? ''}`.trim()
await db.users.create({ data: { clerkId: id, email, name } })
}
if (evt.type === 'user.updated') {
const { id, email_addresses, first_name, last_name } = evt.data
const email = email_addresses[0]?.email_address
await db.users.update({ where: { clerkId: id }, data: { email, first_name, last_name } })
}
if (evt.type === 'user.deleted') {
const { id } = evt.data
await db.users.delete({ where: { clerkId: id } })
}
if (evt.type === 'organizationMembership.created') {
const { organization, public_user_data, role } = evt.data
const orgId = organization.id
const userId = public_user_data.user_id
await db.teamMembers.create({ data: { orgId, userId, role } })
}
if (evt.type === 'organizationMembership.deleted') {
const { organization, public_user_data } = evt.data
const orgId = organization.id
const userId = public_user_data.user_id
await db.teamMembers.delete({ where: { orgId_userId: { orgId, userId } } })
}
return new Response('OK', { status: 200 })
}Notification-only handlers still verify the signature. Same pattern as the database-sync handler:
// app/api/webhooks/route.ts
import { verifyWebhook } from '@clerk/nextjs/webhooks'
import { NextRequest } from 'next/server'
import { Resend } from 'resend'
const resend = new Resend(process.env.RESEND_API_KEY)
export async function POST(req: NextRequest) {
// Step 1: ALWAYS verify the webhook signature - NEVER skip this
let evt
try {
evt = await verifyWebhook(req) // uses CLERK_WEBHOOK_SIGNING_SECRET env var
} catch (err) {
console.error('Webhook verification failed:', err)
return new Response('Verification failed', { status: 400 })
}
// Step 2: Listen for user.created event
if (evt.type === 'user.created') {
// Step 3: Extract user email and name from webhook payload
const { id, email_addresses, first_name, last_name } = evt.data
const email = email_addresses[0]?.email_address
const name = `${first_name ?? ''} ${last_name ?? ''}`.trim()
// Step 4: Call Resend API to send welcome email
await resend.emails.send({
from: 'noreply@yourdomain.com',
to: email,
subject: 'Welcome!',
html: `<p>Hi ${name}, welcome to our app!</p>`,
})
// Step 5: Post notification to Slack channel
await fetch(process.env.SLACK_WEBHOOK_URL!, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: `New user signed up: ${name} (${email})`,
}),
})
}
// Always return 200 to acknowledge receipt
return new Response('OK', { status: 200 })
}Also include proxy.ts (Next.js <=15: middleware.ts) to make the route public:
// proxy.ts (Next.js <=15: middleware.ts)
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'
const isPublicRoute = createRouteMatcher(['/api/webhooks(.*)'])
export default clerkMiddleware(async (auth, req) => {
if (!isPublicRoute(req)) await auth.protect()
})// app/api/webhooks/route.ts
import { verifyWebhook } from '@clerk/nextjs/webhooks'
import { NextRequest } from 'next/server'
import { db } from '@/lib/db' // your database client
export async function POST(req: NextRequest) {
// ALWAYS verify signature - never skip, even for simple handlers
let evt
try {
evt = await verifyWebhook(req) // uses CLERK_WEBHOOK_SIGNING_SECRET env var
} catch (err) {
console.error('Webhook verification failed:', err)
return new Response('Verification failed', { status: 400 })
}
if (evt.type === 'organization.created') {
const { id, name } = evt.data
await db.workspaces.create({
data: { orgId: id, name, createdAt: new Date() },
})
}
if (evt.type === 'organizationMembership.created') {
// Extract organization ID, user ID, and role from payload
const { organization, public_user_data, role } = evt.data
const orgId = organization.id
const userId = public_user_data.user_id
// Add to team_members table
await db.team_members.create({
data: { orgId, userId, role },
})
// Create workspace record for new member
await db.workspaces.create({
data: { orgId, userId, createdAt: new Date() },
})
}
if (evt.type === 'organizationMembership.deleted') {
// Extract organization ID and user ID from payload
const { organization, public_user_data } = evt.data
const orgId = organization.id
const userId = public_user_data.user_id
// Remove from team_members table
await db.team_members.delete({
where: { orgId, userId },
})
// Remove workspace record
await db.workspaces.deleteMany({
where: { orgId, userId },
})
}
// Return 200 status on success
return new Response('OK', { status: 200 })
}For Express, Astro, Fastify, Nuxt, React Router, and TanStack Start, use the framework-specific verifyWebhook adapter. Each Clerk SDK package ships its own (@clerk/express/webhooks, @clerk/astro/webhooks, @clerk/fastify/webhooks, etc.).
See references/frameworks.md for full handler examples per framework.
evt.dataverifyWebhook returns WebhookEvent, a discriminated union of all event types. Narrow with evt.type to get type-safe access to evt.data:
const evt = await verifyWebhook(req)
if (evt.type === 'user.created') {
// evt.data is now UserJSON, autocompletes id, email_addresses, etc.
console.log(evt.data.id)
}For manual typing of nested payloads, import the JSON types from your framework's webhook subpath: DeletedObjectJSON, EmailJSON, OrganizationInvitationJSON, OrganizationJSON, OrganizationMembershipJSON, SessionJSON, SMSMessageJSON, UserJSON.
user.created, user.updated, user.deleted)const {
id, // Clerk user ID
email_addresses, // array; [0].email_address is primary email
first_name,
last_name,
image_url,
public_metadata,
} = evt.dataorganization.created, organization.updated, organization.deleted)const {
id, // org ID
name, // org name
slug,
} = evt.dataorganizationMembership.created, organizationMembership.updated, organizationMembership.deleted)const {
organization, // { id, name, ... }
public_user_data, // { user_id, first_name, last_name, ... }
role, // e.g. 'org:admin', 'org:member'
} = evt.data
// Access: organization.id, public_user_data.user_id, roleUser: user.created user.updated user.deleted
Session: session.created session.ended session.removed session.revoked
Organization: organization.created organization.updated organization.deleted
Organization Membership: organizationMembership.created organizationMembership.updated organizationMembership.deleted
Organization Domain: organizationDomain.created organizationDomain.updated organizationDomain.deleted
Organization Invitation: organizationInvitation.accepted organizationInvitation.created organizationInvitation.revoked
Communication: email.created sms.created
Waitlist: waitlistEntry.created waitlistEntry.updated
Permission: permission.created permission.updated permission.deleted
Role: role.created role.updated role.deleted
Subscription: subscription.created subscription.updated subscription.active subscription.pastDue
Subscription Item: subscriptionItem.created subscriptionItem.active subscriptionItem.updated subscriptionItem.canceled subscriptionItem.upcoming subscriptionItem.ended subscriptionItem.abandoned subscriptionItem.incomplete subscriptionItem.pastDue subscriptionItem.freeTrialEnding
Payment: paymentAttempt.created paymentAttempt.updated
Retries: Svix retries failed webhooks on a set schedule (see Svix Retry Schedule). Return 2xx to succeed, 4xx/5xx to retry. Use the svix-id header as an idempotency key to deduplicate retried events.
Replay: Failed webhooks can be replayed from Dashboard.
| Symptom | Cause | Fix |
|---|---|---|
| Verification fails (Next.js) | Wrong import or usage | Use @clerk/nextjs/webhooks, pass req directly |
| Verification fails (Express) | Using express.json() | Use express.raw({ type: 'application/json' }) for webhook route |
| Route not found (404) | Wrong path | Use /api/webhooks or preserve existing path |
| Not authorized (401) | Route is protected by middleware | Make route public in clerkMiddleware() |
| No data in DB | Async job pending | Wait/check logs |
| Duplicate entries | Only handling user.created | Also handle user.updated |
| Timeouts | Handler too slow | Queue async work, return 200 first |
Local: Use the Clerk CLI's first-party tunnel — no auth or linked project needed:
clerk webhooks listen --token "$(clerk webhooks token)" --forward-to http://localhost:3000/api/webhooksAdd the printed relay URL (https://webhooks.clerk.com/in/c_.../) as a webhook endpoint in the Dashboard — events don't flow until you do. svix-* headers are preserved, so verifyWebhook() works against that endpoint's signing secret as usual. Flags, offline signature checks (clerk webhooks verify), and agent-mode behavior are in the clerk-cli skill. Without the CLI, tunnel localhost:3000 yourself (ngrok, localtunnel, Cloudflare Tunnel) and add the public URL to the Dashboard endpoint.
Production: Update webhook endpoint URL to production domain. Copy CLERK_WEBHOOK_SIGNING_SECRET to production env vars.
| Reference | Description |
|---|---|
references/frameworks.md | Webhook handler examples for Express, Astro, Fastify, Nuxt, React Router, TanStack Start |
clerk-cli - clerk webhooks listen/verify for local webhook testingclerk-setup - Initial Clerk installclerk-orgs - Org membership eventsclerk-billing - Subscription, subscription item, and payment attempt eventsclerk-backend-api - Sync via direct API calls© geekskai, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 2 other files (references) in .agents/skills/clerk-webhooks of geekskai/blog.
Open the folder on GitHubat commit e5554c5
We found 3 copies of this SKILL.md (exact, near-identical or edited) in other folders, from 3 other GitHub owners. This page covers the copy in geekskai/blog, which our catalogue first saw on October 7, 2026.
Clerk Webhooks next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Clerk Webhooks this skillgeekskai/blog | 103 | 3 repos | ~3.4k | Automated safety check: Pass | MIT | |
| Clerk Webhooksvvedantb/eva | 101 | — | ~1.2k | Automated safety check: Pass | MIT | |
| Adobe App Builder Action Scaffolderadobe/skills | 196 | — | ~3.1k | Automated safety check: Pass | Apache-2.0 | |
| Sanity Best Practicessanity-io/agent-toolkit | 188 | — | ~1.3k | Automated safety check: Pass | MIT | |
| Upstash Qstashdavila7/claude-code-templates | 32k | 5 repos | ~597 | Automated safety check: Pass | MIT | |
| Clerk Authdavila7/claude-code-templates | 32k | 5 repos | ~376 | Automated safety check: Pass | MIT |
vvedantb/eva
Clerk webhooks for real-time events and data syncing. An agent skill from vvedantb/eva.
adobe/skills
Scaffolds, implements, deploys and debugs Adobe Runtime actions in App Builder projects, with templates for webhooks, events, database CRUD, sequences and Asset Compute workers.
sanity-io/agent-toolkit
Sanity development best practices for schema design, GROQ queries, TypeGen, Visual Editing, images, Portable Text, Studio structure, localization, migrations, Sanity Functions, webhooks, Blueprints…
davila7/claude-code-templates
Upstash QStash expert for serverless message queues, scheduled jobs, and reliable HTTP-based task delivery without managing infrastructure.
davila7/claude-code-templates
Expert patterns for Clerk auth implementation, middleware, organizations, webhooks, and user sync Use when: adding authentication, clerk auth, user authentication, sign in, sign up.
Tommy-yw/RunbookHermes
Create and manage webhook subscriptions for event-driven agent activation, or for direct push notifications (zero LLM cost).
geekskai/blog
Implement Clerk authentication for native Android apps using Kotlin and Jetpack Compose with clerk-android source-guided patterns.
geekskai/blog
React SPA auth patterns with @clerk/react for Vite/CRA - ClerkProvider setup, useAuth/useUser/useClerk hooks, React Router protected routes, custom sign-in flows.
geekskai/blog
React Router v7/v8 patterns with Clerk — rootAuthLoader, getAuth in loaders, clerkMiddleware, protected routes, SSR user data, org switching.
geekskai/blog
TanStack React Start auth patterns with @clerk/tanstack-react-start - createServerFn, beforeLoad guards, loaders, Vinxi server.
geekskai/blog
Astro patterns with Clerk — middleware, SSR pages, island components, API routes, static vs SSR rendering.
geekskai/blog
Clerk Billing for subscription management - render Clerk's PricingTable and in-app checkout drawer, configure subscription plans, seat-limit plans for B2B, feature entitlements with has(), and…
Works with
Categories
Clerk webhooks for real-time events and data syncing. An agent skill from geekskai/blog. Clerk Webhooks is an agent skill from geekskai/blog. Clerk webhooks for real-time events and data syncing.
Clerk Webhooks fits situations like: tasks that involve Webhooks; tasks that involve Event-driven systems.
Run `npx skills add geekskai/blog --skill clerk-webhooks -a claude-code`. Or copy the skill folder (.agents/skills/clerk-webhooks in geekskai/blog) into .claude/skills/clerk-webhooks in your project. Claude Code loads it when a task matches its description.
Run `npx skills add geekskai/blog --skill clerk-webhooks -a codex`. Or copy the skill folder (.agents/skills/clerk-webhooks in geekskai/blog) into .agents/skills/clerk-webhooks in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add geekskai/blog --skill clerk-webhooks -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/clerk-webhooks, .gemini/skills/clerk-webhooks, .github/skills/clerk-webhooks and .opencode/skills/clerk-webhooks in your project.
Going by SKILL.md and its folder, Clerk Webhooks needs credentials named CLERK_WEBHOOK_SIGNING_SECRET and RESEND_API_KEY. Our summary lists: A credential in CLERK_WEBHOOK_SIGNING_SECRET; A credential in RESEND_API_KEY. Its frontmatter pre-approves these tools: WebFetch. Compatibility (from SKILL.md): Requires CLERK_WEBHOOK_SIGNING_SECRET (svix signing secret from Clerk dashboard).
SKILL.md names 3 domains. In commands or code: webhooks.clerk.com; the agent is likely to contact it when it follows the instructions. As links in the text: clerk.com and docs.svix.com. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Clerk Webhooks is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.4k tokens (SKILL.md is roughly 14k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 1.5k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Clerk Webhooks: Clerk Webhooks (vvedantb/eva, 101 stars), Adobe App Builder Action Scaffolder (adobe/skills, 196 stars), Sanity Best Practices (sanity-io/agent-toolkit, 188 stars) and Upstash Qstash (davila7/claude-code-templates, 32k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
geekskai (a GitHub user) maintains it in geekskai/blog, which has 103 GitHub stars. The repository holds 20 skills in this directory. The repository was last updated on October 7, 2026.
Source: geekskai/blog on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.