Agent skill

Convex HTTP Actions

by waynesutton in 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.

Apache-2.0Auto-check passedBackend & APIs

Install Convex HTTP Actions

skills CLI
$ npx skills add waynesutton/builder-skills --skill convex-http-actions -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install waynesutton/builder-skills convex-http-actions --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ 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-src

Use ~/.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/

Facts

Skill name
convex-http-actions
GitHub stars
404
Token cost
~2.6k tokens
SKILL.md length
797 words
Files
6 (incl. references, assets)
Skills in repo
17
Repo updated
First seen
Licence
Apache-2.0

At a glance

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.

  • Integrating Stripe
  • SKILL.md covers When to reach for this, httpAction or mutation, Router skeleton and Calling queries and mutations…, plus 5 more sections
  • Needs PROVIDER_WEBHOOK_SECRET
  • Any service that calls back into the app

What it does

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.

When your agent uses it

  • Integrating Stripe
  • Any service that calls back into the app
  • A client needs a plain HTTP API

Example prompts

  • “/convex-http-actions”

Requirements

  • A credential in PROVIDER_WEBHOOK_SECRET

What it can do on your machine

Read from SKILL.md and the folder at commit 82d1ce2. It shows what the files ask for, not the result of running them.

  • Tool permissions

    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.

  • Runs code

    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.

  • Network

    Links to these hosts (documentation or services it may open):

    • docs.convex.dev

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • PROVIDER_WEBHOOK_SECRET

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

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.

Always · name and description, kept in context so the agent knows when to use it
~79
When it runs · the whole SKILL.md, loaded when a task matches
~2.6k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~7.6k

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.

Safety

Auto-check passed

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.

SKILL.md

The full file from waynesutton/builder-skills at commit 82d1ce2, republished under its Apache-2.0 licence (© waynesutton). 797 words, ~2,564 tokens.

Download SKILL.mdSave it as .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.
name
convex-http-actions
description
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.

Convex HTTP actions

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.

When to reach for this

  • A third party (Stripe, Clerk, Resend, GitHub) needs a URL to POST events to
  • A client without the Convex SDK (mobile app, CLI, another backend) needs a plain HTTP API
  • A browser needs to download or stream bytes without going through useQuery
  • A script or form needs to upload bytes over HTTP instead of an upload URL

httpAction or mutation

CallerUse
Your own React or Next.js app using convex/reactquery and mutation. Skip HTTP actions.
External service sending webhookshttpAction
Client that cannot use the Convex SDKhttpAction
Scheduled or internal workinternalMutation 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.

Router skeleton

The router must live at convex/http.ts and be the default export. A router in any other file is ignored.

typescript
// 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.

Calling queries and mutations from the handler

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.

typescript
// 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.

Webhook with signature verification

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.

typescript
// 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:

typescript
// 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.

CORS, path params, auth headers, streaming, files

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.

Show full SKILL.md (277 more words)Show less

Common mistakes

MistakeWhy it breaksDo instead
Router in convex/api.ts or convex/routes.tsOnly convex/http.ts is loaded as the routerKeep one http.ts with export default http
Calling https://<deployment>.convex.cloud/webhooks/...HTTP actions live on .convex.siteUse the .convex.site URL in the provider dashboard
await request.json() before verifying the signatureThe reserialized body no longer matches the signed bytesrequest.text() once, verify, then JSON.parse
Trusting the body because "it came from Stripe"Anyone can POST to a public URLVerify the signature on every request
Using api.* targets from runMutationExposes the same logic twice, once unauthenticatedTarget internal.* functions
No OPTIONS route for a browser called endpointPreflight fails, the real request never sendsAdd an OPTIONS route per path with CORS headers
Doing minutes of work inside the handlerProvider times out and retries, duplicating workReturn 200 fast, schedule with ctx.scheduler.runAfter
Processing the same event twiceProviders retry on any non 2xxDedupe by event id in the mutation
Missing Content-Type: application/json on responsesClients get text they cannot parseUse a json() helper for every JSON response

Checklist

  • Router is at convex/http.ts and exported as default
  • Every route parses the body inside try/catch and returns 400 on bad input
  • Handlers call internal.* functions, never ctx.db
  • Webhook routes read request.text() once and verify the signature before parsing
  • Webhook secrets come from process.env and are set in the deployment, not hardcoded
  • Events are deduplicated by provider event id inside a mutation
  • Slow work is scheduled, and the handler returns 2xx quickly
  • Browser called routes have a matching OPTIONS route
  • The provider dashboard points at the .convex.site URL
  • JSON responses set Content-Type: application/json

Docs

© 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

Files

SKILL.md and 5 other files (references, assets) in skills/convex-http-actions of waynesutton/builder-skills.

  • SKILL.md
  • agents/openai.yaml
  • assets/large-logo.png
  • assets/small-logo.svg
  • references/rest-and-cors.md
  • references/webhooks.md

Open the folder on GitHubat commit 82d1ce2

Compare with similar skills

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.

Convex HTTP Actions compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Convex HTTP Actions this skillwaynesutton/builder-skills404—~2.6kAutomated safety check: PassApache-2.0
Frappe Errors APIImpertio-Studio/Frappe_Claude_Skill_Package1871 repos~4kAutomated safety check: PassMIT
Neon Functionsneondatabase/agent-skills100—~12kAutomated safety check: NotesApache-2.0
Stripe Projectsfossasia/eventyay1.7k5 repos~2kAutomated safety check: NotesApache-2.0
Stripe Appsfossasia/eventyay1.7k2 repos~3.6kAutomated safety check: PassApache-2.0
Stripe Best Practiceskanchengw/cnllm1753 repos~925Automated safety check: PassApache-2.0

Similar skills

  • 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.

    187 GitHub starsUsed in 1 repo~4k tokens
    Backend & APIsAuto-check passed
  • Neon Functions

    neondatabase/agent-skills

    Official

    Long-running, serverless Node.js HTTP functions deployed onto your Neon branch, with DATABASEURL injected automatically and compute that runs next to your data.

    100 GitHub stars~12k tokensUpdated yesterday
    Backend & APIsAuto-check: notes
  • Stripe Projects

    fossasia/eventyay

    A skill your agent uses when the user wants to provision infrastructure or third-party services using Stripe Projects.

    1.7k GitHub starsUsed in 5 repos~2k tokens
    Backend & APIsAuto-check: notes
  • Stripe Apps

    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.

    1.7k GitHub starsUsed in 2 repos~3.6k tokens
    Backend & APIsAuto-check passed
  • Stripe Best Practices

    kanchengw/cnllm

    Guides Stripe integration decisions — API selection (Checkout Sessions vs PaymentIntents), Connect platform setup (Accounts v2, controller properties), billing/subscriptions, Treasury financial…

    175 GitHub starsUsed in 3 repos~925 tokens
    Backend & APIsAuto-check passed
  • Handles Laravel Cashier Stripe integration including subscriptions, webhooks, Stripe Checkout, invoices, charges, refunds, trials, coupons, metered billing, and payment failure handling.

    343 GitHub starsUsed in 1 repo~1.2k tokens
    Backend & APIsAuto-check passed

More from waynesutton/builder-skills

All 17 skills in this repo
  • Convex Agents

    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.

    404 GitHub stars~2.2k tokensUpdated 10 days ago
    Auto-check passed
  • Convex Best Practices

    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.

    404 GitHub stars~2.6k tokensUpdated 10 days ago
    Auto-check passed
  • Convex Component Authoring

    waynesutton/builder-skills

    Creates reusable Convex components with defineComponent, a clean client wrapper, their own schema, and an npm publish setup.

    404 GitHub stars~2.6k tokensUpdated 10 days ago
    Auto-check passed
  • Convex Cron Jobs

    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.

    404 GitHub stars~2k tokensUpdated 10 days ago
    Auto-check passed
  • Convex Migrations

    waynesutton/builder-skills

    Changes a live Convex schema without downtime: make a field optional, backfill in batches, flip the validator, then clean up.

    404 GitHub stars~2.1k tokensUpdated 10 days ago
    Auto-check passed
  • Convex Security Audit

    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…

    404 GitHub stars~2.6k tokensUpdated 10 days ago
    Auto-check passed

Works with

Categories

Questions about Convex HTTP Actions

What does Convex HTTP Actions do?

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.

When should I use Convex HTTP Actions?

Convex HTTP Actions fits situations like: integrating Stripe; any service that calls back into the app; A client needs a plain HTTP API.

How do I install Convex HTTP Actions in Claude Code?

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.

How do I install Convex HTTP Actions in Codex?

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.

Can I use Convex HTTP Actions in Cursor, Gemini CLI or GitHub Copilot?

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.

What does Convex HTTP Actions need to run?

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.

Does Convex HTTP Actions access the network?

SKILL.md names 1 domain. As links in the text: docs.convex.dev. This is read from the text; nothing was executed.

Is Convex HTTP Actions safe to install?

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.

What licence does Convex HTTP Actions use?

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.

How many tokens does Convex HTTP Actions use?

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.

What are the alternatives to Convex HTTP Actions?

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.

Who maintains Convex HTTP Actions?

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.