Frappe Errors API
Impertio-Studio/Frappe_Claude_Skill_Package
A skill your agent uses when debugging or handling API errors in Frappe/ERPNext v14/v15/v16.
Adds HTTP endpoints in convex/http.ts: webhook receivers with signature checks, REST style routes, CORS, auth headers, streaming responses, and file uploads over HTTP.
$ npx skills add waynesutton/builder-skills --skill convex-http-actions -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install waynesutton/builder-skills convex-http-actions --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/waynesutton/builder-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/convex-http-actions .claude/skills/convex-http-actions && 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 "convex-http-actions" agent skill from https://github.com/waynesutton/builder-skills/tree/main/skills/convex-http-actions into .claude/skills/convex-http-actions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "convex-http-actions", 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/waynesutton/builder-skills/tree/main/skills/convex-http-actionsType 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 waynesutton/builder-skills --skill convex-http-actions -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install waynesutton/builder-skills convex-http-actions --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/waynesutton/builder-skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/convex-http-actions .agents/skills/convex-http-actions && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "convex-http-actions" agent skill from https://github.com/waynesutton/builder-skills/tree/main/skills/convex-http-actions into .agents/skills/convex-http-actions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "convex-http-actions", 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 waynesutton/builder-skills --skill convex-http-actions -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install waynesutton/builder-skills convex-http-actions --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/waynesutton/builder-skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/convex-http-actions .cursor/skills/convex-http-actions && 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 "convex-http-actions" agent skill from https://github.com/waynesutton/builder-skills/tree/main/skills/convex-http-actions into .cursor/skills/convex-http-actions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "convex-http-actions", 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/waynesutton/builder-skills.git --path skills/convex-http-actions--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 waynesutton/builder-skills --skill convex-http-actions -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install waynesutton/builder-skills convex-http-actions --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/waynesutton/builder-skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/convex-http-actions .gemini/skills/convex-http-actions && 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 "convex-http-actions" agent skill from https://github.com/waynesutton/builder-skills/tree/main/skills/convex-http-actions into .gemini/skills/convex-http-actions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "convex-http-actions", 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 waynesutton/builder-skills convex-http-actionsInstalls 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 waynesutton/builder-skills --skill convex-http-actions -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/waynesutton/builder-skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/convex-http-actions .github/skills/convex-http-actions && 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 "convex-http-actions" agent skill from https://github.com/waynesutton/builder-skills/tree/main/skills/convex-http-actions into .github/skills/convex-http-actions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "convex-http-actions", 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 waynesutton/builder-skills --skill convex-http-actions -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install waynesutton/builder-skills convex-http-actions --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/waynesutton/builder-skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/convex-http-actions .opencode/skills/convex-http-actions && 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 "convex-http-actions" agent skill from https://github.com/waynesutton/builder-skills/tree/main/skills/convex-http-actions into .opencode/skills/convex-http-actions/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "convex-http-actions", 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.
convex-http-actionsAdds HTTP endpoints in convex/http.ts: webhook receivers with signature checks, REST style routes, CORS, auth headers, streaming responses, and file uploads over HTTP.
Convex HTTP Actions is an agent skill from waynesutton/builder-skills. Adds HTTP endpoints in convex/http.ts: webhook receivers with signature checks, REST style routes, CORS, auth headers, streaming responses, and file uploads over HTTP. Use when integrating Stripe, Clerk, Resend, or any service that calls back into the app, or when a client needs a plain HTTP API.
Its SKILL.md is about 2.6k tokens, which your agent loads only when the skill is triggered. The skill folder holds 8 other files, including reference files and assets (for example `agents/openai.yaml`, `references/rest-and-cors.md` and `references/webhooks.md`).
It sits in Backend & APIs, covering Webhooks, REST APIs and File uploads and storage. It works with Stripe. The repository describes itself as: Builder skills for Convex apps. Convex patterns plus a PRD, task.md, changelog, and files.md workflow for Claude Code, Codex, Cursor, and OpenCode. The licence is Apache-2.0.
Read from SKILL.md and the folder at commit 82d1ce2. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript).
From the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
docs.convex.devFrom URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
PROVIDER_WEBHOOK_SECRETFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Convex HTTP Actions loads about 2.6k tokens when it runs, and up to ~7.6k if it reads all its reference files. Until then it costs about 79 tokens; SKILL.md has 797 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 waynesutton/builder-skills at commit 82d1ce2, republished under its Apache-2.0 licence (© waynesutton). 797 words, ~2,564 tokens.
.claude/skills/convex-http-actions/SKILL.md (or your agent's skills folder). This skill also uses 5 other files; get the full folder from GitHub.Defines public HTTP endpoints served from the deployment's .convex.site domain. The one rule: an httpAction handler treats every byte of the request as untrusted, verifies it, then calls internal.* functions with ctx.runQuery or ctx.runMutation. It never reads or writes ctx.db directly.
useQuery| Caller | Use |
|---|---|
Your own React or Next.js app using convex/react | query and mutation. Skip HTTP actions. |
| External service sending webhooks | httpAction |
| Client that cannot use the Convex SDK | httpAction |
| Scheduled or internal work | internalMutation or internalAction |
HTTP actions get no argument validators and no automatic auth. They run in the default Convex runtime, so Web APIs (fetch, crypto.subtle, Response, ReadableStream) work without "use node". Request and response bodies are capped at 20MB.
The router must live at convex/http.ts and be the default export. A router in any other file is ignored.
// convex/http.ts
import { httpRouter } from "convex/server";
import { httpAction } from "./_generated/server";
import { internal } from "./_generated/api";
const http = httpRouter();
http.route({
path: "/api/items",
method: "POST",
handler: httpAction(async (ctx, request) => {
let body: { name?: unknown };
try {
body = await request.json();
} catch {
return json({ error: "Invalid JSON body" }, 400);
}
if (typeof body.name !== "string") {
return json({ error: "name is required" }, 400);
}
const id = await ctx.runMutation(internal.items.create, { name: body.name });
return json({ id }, 201);
}),
});
export default http;
// JSON response helper shared by every route in this file
function json(data: unknown, status = 200): Response {
return new Response(JSON.stringify(data), {
status,
headers: { "Content-Type": "application/json" },
});
}The endpoint is reachable at https://<deployment>.convex.site/api/items. Note .convex.site, not .convex.cloud. path matches exactly; use pathPrefix: "/api/items/" for dynamic segments and read the tail from new URL(request.url).pathname.
ctx.runQuery, ctx.runMutation, ctx.runAction, ctx.storage, ctx.scheduler, and ctx.auth are all available inside httpAction. Point them at internal.* functions so database logic is not also exposed as a public Convex function. Arguments still pass through the target's validators, so a bad shape fails there with a clear error.
// convex/items.ts
import { internalMutation } from "./_generated/server";
import { v } from "convex/values";
export const create = internalMutation({
args: { name: v.string() },
returns: v.id("items"),
handler: async (ctx, args) => {
return await ctx.db.insert("items", { name: args.name });
},
});For slow work (sending email, calling an LLM), respond 200 right away and hand off with ctx.scheduler.runAfter(0, internal.jobs.process, args). Providers time out and retry if the handler stalls.
Read the raw body once with request.text(). Parsing first changes the bytes and breaks the signature. This generic HMAC SHA-256 pattern covers most providers; Stripe, Clerk, and Resend specifics are in the reference below.
// convex/http.ts (add to the router above)
http.route({
path: "/webhooks/provider",
method: "POST",
handler: httpAction(async (ctx, request) => {
const signature = request.headers.get("x-signature");
if (!signature) return new Response("Missing signature", { status: 400 });
const raw = await request.text();
const secret = process.env.PROVIDER_WEBHOOK_SECRET;
if (!secret) return new Response("Webhook secret not configured", { status: 500 });
if (!(await verifyHmac(raw, signature, secret))) {
return new Response("Invalid signature", { status: 401 });
}
const event = JSON.parse(raw) as { id: string; type: string; data: unknown };
// The mutation returns early if this event id was already processed.
await ctx.runMutation(internal.webhooks.record, {
source: "provider",
eventId: event.id,
type: event.type,
payload: event.data,
});
return new Response(null, { status: 200 });
}),
});
async function verifyHmac(payload: string, signature: string, secret: string): Promise<boolean> {
const enc = new TextEncoder();
const key = await crypto.subtle.importKey(
"raw",
enc.encode(secret),
{ name: "HMAC", hash: "SHA-256" },
false,
["sign"],
);
const mac = await crypto.subtle.sign("HMAC", key, enc.encode(payload));
const expected = Array.from(new Uint8Array(mac))
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
return safeEqual(expected, signature);
}
// Constant time compare so response timing does not leak the signature
function safeEqual(a: string, b: string): boolean {
if (a.length !== b.length) return false;
let diff = 0;
for (let i = 0; i < a.length; i++) diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
return diff === 0;
}Providers retry on any non 2xx and sometimes on network flakes, so the same event arrives more than once. Deduplicate by event id inside the mutation, which is a transaction:
// convex/webhooks.ts
import { internalMutation } from "./_generated/server";
import { v } from "convex/values";
export const record = internalMutation({
args: { source: v.string(), eventId: v.string(), type: v.string(), payload: v.any() },
returns: v.null(),
handler: async (ctx, args) => {
const seen = await ctx.db
.query("webhookEvents")
.withIndex("by_source_and_event_id", (q) =>
q.eq("source", args.source).eq("eventId", args.eventId),
)
.unique();
if (seen) return null;
await ctx.db.insert("webhookEvents", args);
// Apply the event's side effects here, in the same transaction.
return null;
},
});Schema: webhookEvents: defineTable({ source: v.string(), eventId: v.string(), type: v.string(), payload: v.any() }).index("by_source_and_event_id", ["source", "eventId"]).
Open references/webhooks.md for Stripe (constructEvent in a Node action), Clerk and Resend (svix headers), replay protection with timestamps, and a fuller idempotency table with status tracking.
Browsers send an OPTIONS preflight before cross origin POSTs, so each browser facing path needs an OPTIONS route returning the same Access-Control-* headers as the real route. Bearer tokens from your configured auth provider are read with await ctx.auth.getUserIdentity(), the same call used in queries. Streaming works by returning new Response(readableStream), and files are served with ctx.storage.get(storageId) or accepted with request.blob() then ctx.storage.store(blob).
Open references/rest-and-cors.md when building a REST style API: path parameters and id validation, the CORS preflight pair, JSON error conventions, bearer and API key auth, streaming responses, and file upload and download routes.
| Mistake | Why it breaks | Do instead |
|---|---|---|
Router in convex/api.ts or convex/routes.ts | Only convex/http.ts is loaded as the router | Keep one http.ts with export default http |
Calling https://<deployment>.convex.cloud/webhooks/... | HTTP actions live on .convex.site | Use the .convex.site URL in the provider dashboard |
await request.json() before verifying the signature | The reserialized body no longer matches the signed bytes | request.text() once, verify, then JSON.parse |
| Trusting the body because "it came from Stripe" | Anyone can POST to a public URL | Verify the signature on every request |
Using api.* targets from runMutation | Exposes the same logic twice, once unauthenticated | Target internal.* functions |
No OPTIONS route for a browser called endpoint | Preflight fails, the real request never sends | Add an OPTIONS route per path with CORS headers |
| Doing minutes of work inside the handler | Provider times out and retries, duplicating work | Return 200 fast, schedule with ctx.scheduler.runAfter |
| Processing the same event twice | Providers retry on any non 2xx | Dedupe by event id in the mutation |
Missing Content-Type: application/json on responses | Clients get text they cannot parse | Use a json() helper for every JSON response |
convex/http.ts and exported as defaulttry/catch and returns 400 on bad inputinternal.* functions, never ctx.dbrequest.text() once and verify the signature before parsingprocess.env and are set in the deployment, not hardcodedOPTIONS route.convex.site URLContent-Type: application/json© waynesutton, Apache-2.0. 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 5 other files (references, assets) in skills/convex-http-actions of waynesutton/builder-skills.
Open the folder on GitHubat commit 82d1ce2
Convex HTTP Actions 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 |
|---|---|---|---|---|---|---|
| Convex HTTP Actions this skillwaynesutton/builder-skills | 404 | — | ~2.6k | Automated safety check: Pass | Apache-2.0 | |
| Frappe Errors APIImpertio-Studio/Frappe_Claude_Skill_Package | 187 | 1 repos | ~4k | Automated safety check: Pass | MIT | |
| Neon Functionsneondatabase/agent-skills | 100 | — | ~12k | Automated safety check: Notes | Apache-2.0 | |
| Stripe Projectsfossasia/eventyay | 1.7k | 5 repos | ~2k | Automated safety check: Notes | Apache-2.0 | |
| Stripe Appsfossasia/eventyay | 1.7k | 2 repos | ~3.6k | Automated safety check: Pass | Apache-2.0 | |
| Stripe Best Practiceskanchengw/cnllm | 175 | 3 repos | ~925 | Automated safety check: Pass | Apache-2.0 |
Impertio-Studio/Frappe_Claude_Skill_Package
A skill your agent uses when debugging or handling API errors in Frappe/ERPNext v14/v15/v16.
neondatabase/agent-skills
Long-running, serverless Node.js HTTP functions deployed onto your Neon branch, with DATABASEURL injected automatically and compute that runs next to your data.
fossasia/eventyay
A skill your agent uses when the user wants to provision infrastructure or third-party services using Stripe Projects.
fossasia/eventyay
A skill your agent uses when building, modifying, or reviewing a Stripe App — or when the user describes something that implies one (e.g.
kanchengw/cnllm
Guides Stripe integration decisions — API selection (Checkout Sessions vs PaymentIntents), Connect platform setup (Accounts v2, controller properties), billing/subscriptions, Treasury financial…
luadotsh/lua
Handles Laravel Cashier Stripe integration including subscriptions, webhooks, Stripe Checkout, invoices, charges, refunds, trials, coupons, metered billing, and payment failure handling.
waynesutton/builder-skills
Builds AI agents on the Convex agent component: threads, messages, tools that call queries and mutations, streaming, RAG with vector search, and workflows for multi step jobs.
waynesutton/builder-skills
Production patterns for Convex apps and the rules the @convex-dev/eslint-plugin enforces: validators, indexes, idempotent mutations, avoiding OCC conflicts, thin function wrappers, error handling.
waynesutton/builder-skills
Creates reusable Convex components with defineComponent, a clean client wrapper, their own schema, and an npm publish setup.
waynesutton/builder-skills
Schedules work in Convex: cron jobs in convex/crons.ts, one off scheduled functions with runAfter and runAt, batching large jobs, and cancelling or inspecting the queue.
waynesutton/builder-skills
Changes a live Convex schema without downtime: make a field optional, backfill in batches, flip the validator, then clean up.
waynesutton/builder-skills
Deep security review of a Convex app: authorization model, data access paths per table, HTTP action exposure, rate limiting, file storage access, scheduled function trust, and a written findings…
Works with
Categories
Adds HTTP endpoints in convex/http.ts: webhook receivers with signature checks, REST style routes, CORS, auth headers, streaming responses, and file uploads over HTTP. Convex HTTP Actions is an agent skill from waynesutton/builder-skills.ts: webhook receivers with signature checks, REST style routes, CORS, auth headers, streaming responses, and file uploads over HTTP.
Convex HTTP Actions fits situations like: integrating Stripe; any service that calls back into the app; A client needs a plain HTTP API.
Run `npx skills add waynesutton/builder-skills --skill convex-http-actions -a claude-code`. Or copy the skill folder (skills/convex-http-actions in waynesutton/builder-skills) into .claude/skills/convex-http-actions in your project. Claude Code loads it when a task matches its description.
Run `npx skills add waynesutton/builder-skills --skill convex-http-actions -a codex`. Or copy the skill folder (skills/convex-http-actions in waynesutton/builder-skills) into .agents/skills/convex-http-actions 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 waynesutton/builder-skills --skill convex-http-actions -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/convex-http-actions, .gemini/skills/convex-http-actions, .github/skills/convex-http-actions and .opencode/skills/convex-http-actions in your project.
Going by SKILL.md and its folder, Convex HTTP Actions needs credentials named PROVIDER_WEBHOOK_SECRET. Our summary lists: A credential in PROVIDER_WEBHOOK_SECRET.
SKILL.md names 1 domain. As links in the text: docs.convex.dev. 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.
Convex HTTP Actions is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 2.6k tokens (SKILL.md is roughly 10k 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 5.1k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Convex HTTP Actions: Frappe Errors API (Impertio-Studio/Frappe_Claude_Skill_Package, 187 stars), Neon Functions (neondatabase/agent-skills, 100 stars), Stripe Projects (fossasia/eventyay, 1.7k stars) and Stripe Apps (fossasia/eventyay, 1.7k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
waynesutton (a GitHub user) maintains it in waynesutton/builder-skills, which has 404 GitHub stars. The repository holds 17 skills in this directory. The repository was last updated on September 28, 2026.
Source: waynesutton/builder-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.