Content Creation
#writing
convex-functions
Writing queries, mutations, actions, and HTTP actions with proper argument validation, error handling, internal functions, and runtime considerations
DeepseekModel
Curated skill
Quality Excellent · 78
v1.0.0
Get
https://deepseekmodel.com/api/download.php?id=waynesutton-convexskills-skills-convex-functions-skill-md&format=skill
Download .skill
Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
name convex-functions displayName Convex Functions description Writing queries, mutations, actions, and HTTP actions with proper argument validation, error handling, internal functions, and runtime considerations version 1.0.0 author Convex tags ["convex","functions","queries","mutations","actions","http"] Convex Functions Master Convex functions including queries, mutations, actions, and HTTP endpoints with proper validation, error handling, and runtime considerations. Code Quality All examples in this skill comply with @convex-dev/eslint-plugin rules: Object syntax with handler property Argument validators on all functions Explicit table names in database operations See the Code Quality section in convex-best-practices for linting setup. Documentation Sources Before implementing, do not assume; fetch the latest documentation: Primary: https://docs.convex.dev/functions Query Functions: https://docs.convex.dev/functions/query-functions Mutation Functions: https://docs.convex.dev/functions/mutation-functions Actions: https://docs.convex.dev/functions/actions HTTP Actions: https://docs.convex.dev/functions/http-actions For broader context: https://docs.convex.dev/llms.txt Instructions Function Types Overview Type Database Access External APIs Caching Use Case Query Read-only No Yes, reactive Fetching data Mutation Read/Write No No Modifying data Action Via runQuery/runMutation Yes No External integrations HTTP Action Via runQuery/runMutation Yes No Webhooks, APIs Queries Queries are reactive, cached, and read-only: import { query } from "./_generated/server" ; import { v } from "convex/values" ; export const getUser = query ({ args : { userId : v. id ( "users" ) }, returns : v. union ( v. object ({ _id : v. id ( "users" ), _creationTime : v. number (), name : v. string (), email : v. string (), }), v. null (), ), handler : async (ctx, args) => { return await ctx. db . get ( "users" , args. userId ); }, }); // Query with index export const listUserTasks = query ({ args : { userId : v. id ( "users" ) }, returns : v. array ( v. object ({ _id : v. id ( "tasks" ), _creationTime : v. number (), title : v. string (), completed : v. boolean (), }), ), handler : async (ctx, args) => { return await ctx. db . query ( "tasks" ) . withIndex ( "by_user" , ( q ) => q. eq ( "userId" , args. userId )) . order ( "desc" ) . collect (); }, }); Mutations Mutations modify the database and are transactional: import { mutation } from "./_generated/server" ; import { v } from "convex/values" ; import { ConvexError } from "convex/values" ; export const createTask = mutation ({ args : { title : v. string (), userId : v. id ( "users" ), }, returns : v. id ( "tasks" ), handler : async (ctx, args) => { // Validate user exists const user = await ctx. db . get ( "users" , args. userId ); if (!user) { throw new ConvexError ( "User not found" ); } return await ctx. db . insert ( "tasks" , { title : args. title , userId : args. userId , completed : false , createdAt : Date . now (), }); }, }); export const deleteTask = mutation ({ args : { taskId : v. id ( "tasks" ) }, returns : v. null (), handler : async (ctx, args) => { await ctx. db . delete ( "tasks" , args. taskId ); return null ; }, }); Actions Actions can call external APIs but have no direct database access: "use node" ; import { action } from "./_generated/server" ; import { v } from "convex/values" ; import { api, internal } from "./_generated/api" ; export const sendEmail = action ({ args : { to : v. string (), subject : v. string (), body : v. string (), }, returns : v. object ({ success : v. boolean () }), handler : async (ctx, args) => { // Call external API const response = await fetch ( "https://api.email.com/send" , { method : "POST" , headers : { "Content-Type" : "application/json" }, body : JSON . stringify (args), }); return { success : response. ok }; }, }); // Action calling queries and mutations export const processOrder = action ({ args : { orderId : v. id ( "orders" ) }, returns : v. null (), handler : async (ctx, args) => { // Read data via query const order = await ctx. runQuery (api. orders . get , { orderId : args. orderId }); if (!order) { throw new Error ( "Order not found" ); } // Call external payment API const paymentResult = await processPayment (order); // Update database via mutation await ctx. runMutation (internal. orders . updateStatus , { orderId : args. orderId , status : paymentResult. success ? "paid" : "failed" , }); return null ; }, }); HTTP Actions HTTP actions handle webhooks and external requests: // convex/http.ts import { httpRouter } from "convex/server" ; import { httpAction } from "./_generated/server" ; import { api, internal } from "./_generated/api" ; const http = httpRouter (); // Webhook endpoint http. route ({ path : "/webhooks/stripe" , method : "POST" , handler : httpAction ( async (ctx, request) => { const signature = request. headers . get ( "stripe-signature" ); const body = await request. text (); // Verify webhook signature if (! verifyStripeSignature (body, signature)) { return new Response ( "Invalid signature" , { status : 401 }); } const event = JSON . parse (body); // Process webhook await ctx. runMutation (internal. payments . handleWebhook , { eventType : event. type , data : event. data , }); return new Response ( "OK" , { status : 200 }); }), }); // API endpoint http. route ({ path : "/api/users/:userId" , method : "GET" , handler : httpAction ( async (ctx, request) => { const url = new URL (request. url ); const userId = url. pathname . split ( "/" ). pop (); const user = await ctx. runQuery (api. users . get , { userId : userId as Id < "users" >, }); if (!user) { return new Response ( "Not found" , { status : 404 }); } return Response . json (user); }), }); export default http; Internal Functions Use internal functions for sensitive operations: import { internalMutation, internalQuery, internalAction, } from "./_generated/server" ; import { v } from "convex/values" ; // Only callable from other Convex functions export const _updateUserCredits = internalMutation ({ args : { userId : v. id ( "users" ), amount : v. number (), }, returns : v. null (), handler : async (ctx, args) => { const user = await ctx. db . get ( "users" , args. userId ); if (!user) return null ; await ctx. db . patch ( "users" , args. userId , { credits : (user. credits || 0 ) + args. amount , }); return null ; }, }); // Call internal function from action export const purchaseCredits = action ({ args : { userId : v. id ( "users" ), amount : v. number () }, returns : v. null (), handler : async (ctx, args) => { // Process payment externally await processPayment (args. amount ); // Update credits via internal mutation await ctx. runMutation (internal. users . _updateUserCredits , { userId : args. userId , amount : args. amount , }); return null ; }, }); Scheduling Functions Schedule functions to run later: import { mutation, internalMutation } from "./_generated/server" ; import { v } from "convex/values" ; import { internal } from "./_generated/api" ; export const scheduleReminder = mutation ({ args : { userId : v. id ( "users" ), message : v. string (), delayMs : v. number (), }, returns : v. id ( "_scheduled_functions" ), handler : async (ctx, args) => { return await ctx. scheduler . runAfter ( args. delayMs , internal. notifications . sendReminder , { userId : args. userId , message : args. message }, ); }, }); export const sendReminder = internalMutation ({ args : { userId : v. id ( "users" ), message : v. string (), }, returns : v. null (), handler : async (ctx, args) => { await ctx. db . insert ( "notifications" , { userId : args. userId , message : args. message , sentAt : Date . now (), }); return null ; }, }); Examples Complete Function File // convex/messages.ts import { query, mutation, internalMutation } from "./_generated/server" ; import { v } from "convex/values" ; import { ConvexError } from "convex/values" ; import { internal } from "./_generated/api" ; const messageValidator = v. object ({ _id : v. id ( "messages" ), _creationTime : v. number (), channelId : v. id ( "channels" ), authorId : v. id ( "users" ), content : v. string (), editedAt : v. optional (v. number ()), }); // Public query export const list = query ({ args : { channelId : v. id ( "channels" ), limit : v. optional (v. number ()), }, returns : v. array (messageValidator), handler : async (ctx, args) => { const limit = args. limit ?? 50 ; return await ctx. db . query ( "messages" ) . withIndex ( "by_channel" , ( q ) => q. eq ( "channelId" , args. channelId )) . order ( "desc" ) . take (limit); }, }); // Public mutation export const send = mutation ({ args : { channelId : v. id ( "channels" ), authorId : v. id ( "users" ), content : v. string (), }, returns : v. id ( "messages" ), handler : async (ctx, args) => { if (args. content . trim (). length === 0 ) { throw new ConvexError ( "Message cannot be empty" ); } const messageId = await ctx. db . insert ( "messages" , { channelId : args. channelId , authorId : args. authorId , content : args. content . trim (), }); // Schedule notification await ctx. scheduler . runAfter ( 0 , internal. messages . notifySubscribers , { channelId : args. channelId , messageId, }); return messageId; }, }); // Internal mutation
Keywords that activate this skill. Click one to copy it.
This skill does not provide trigger words.
The downloaded .skill package contains the following fields.
| Field | Description |
|---|---|
| format | Format tag (skill/v1) |
| skill_id | Unique skill ID |
| name | Skill name |
| version | Version |
| description | Description |
| category | Categories (array) |
| trigger_words | Trigger words |
| tags | Tags |
| source | Source |
| source_url | Source URL (this page) |
| exported_at | Exported at (set per download) |
| system_prompt | System prompt body |
| model_config | Model config: provider / model / temperature / max_tokens / top_p |
| examples | Examples |
| install_guide | Import guide for Coze / Dify / Claude / custom frameworks |
The same skill can be exported in different platform formats.