
Building With Medusa
Implement Medusa v2 custom store and admin API routes with Zod body validation, auth, workflows, and consistent error handling.
Overview
Building with Medusa is an agent skill for the Build phase that guides custom Medusa store and admin API routes with validation, auth, and workflows.
Install
npx skills add https://github.com/medusajs/medusa-agent-skills --skill building-with-medusaWhat is this skill?
- Documents /store and /admin path prefixes with SDK auth expectations
- Requires validateAndTransformBody with Zod schemas for request bodies
- Shows correct pattern for stacking authenticate and validation middleware in arrays
- Covers list endpoints with request query config and protected route patterns
- Guides invoking Medusa workflows from API route handlers with structured errors
- Separate path prefixes for /store and /admin custom routes
Adoption & trust: 2.3k installs on skills.sh; 185 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your agent keeps generating Medusa API routes that skip Zod validation, mix up store vs admin paths, or nest middleware the framework rejects.
Who is it for?
Solo builders extending Medusa 2.x with custom storefront or admin endpoints who want agent output aligned to Medusa’s route and middleware rules.
Skip if: Greenfield teams not using Medusa, frontend-only styling work, or deployments that need infrastructure runbooks instead of API route authoring.
When should I use this skill?
User is implementing or reviewing Medusa custom API routes, middleware validation, authentication, or workflow-backed handlers.
What do I get? / Deliverables
You ship Medusa endpoints that follow official path, validation, auth, and workflow patterns suitable for storefront and admin clients.
- Medusa store or admin route modules with Zod schemas and middleware
- Workflow-invoking handlers with documented error handling
Recommended Skills
Journey fit
Custom Medusa endpoints are core backend work while you are assembling the commerce product itself. Route design, middleware, and workflows map directly to backend API construction in Medusa’s modular commerce stack.
How it compares
Medusa-specific backend route skill—not a generic Express/Fastify API generator or a storefront theme skill.
Common Questions / FAQ
Who is building-with-medusa for?
Indie developers and small teams building on Medusa commerce who need agents to scaffold admin and store API routes with correct validation and authentication.
When should I use building-with-medusa?
Use it during Build backend work when adding custom Medusa endpoints, wiring workflows into routes, or fixing middleware and Zod validation mistakes.
Is building-with-medusa safe to install?
Check the Security Audits panel on this page; the skill is procedural documentation and does not by itself execute shell or network actions.
SKILL.md
READMESKILL.md - Building With Medusa
# Custom API Routes API routes (also called "endpoints") are the primary way to expose custom functionality to storefronts and admin dashboards. ## Contents - [Path Conventions](#path-conventions) - [Middleware Validation](#middleware-validation) - [Query Parameter Validation](#query-parameter-validation) - [Request Query Config for List Endpoints](#request-query-config-for-list-endpoints) - [API Route Structure](#api-route-structure) - [Error Handling](#error-handling) - [Protected Routes](#protected-routes) - [Using Workflows in API Routes](#using-workflows-in-api-routes) ## Path Conventions ### Store API Routes (Storefront) - **Path prefix**: `/store/<rest-of-path>` - **Examples**: `/store/newsletter-signup`, `/store/custom-search` - **Authentication**: SDK automatically includes publishable API key ### Admin API Routes (Dashboard) - **Path prefix**: `/admin/<rest-of-path>` - **Examples**: `/admin/custom-reports`, `/admin/bulk-operations` - **Authentication**: SDK automatically includes auth headers (bearer/session) **Detailed authentication patterns**: See [authentication.md](authentication.md) ## Middleware Validation **⚠️ CRITICAL**: Always validate request bodies using Zod schemas and the `validateAndTransformBody` middleware. ### Combining Multiple Middlewares When you need both authentication AND validation, pass them as an array. **NEVER nest validation inside authenticate:** ```typescript // ✅ CORRECT - Multiple middlewares in array export default defineMiddlewares({ routes: [ { matcher: "/store/products/:id/reviews", method: "POST", middlewares: [ authenticate("customer", ["session", "bearer"]), validateAndTransformBody(CreateReviewSchema) ], }, ], }) // ❌ WRONG - Don't nest validator inside authenticate export default defineMiddlewares({ routes: [ { matcher: "/store/products/:id/reviews", method: "POST", middlewares: [authenticate("customer", ["session", "bearer"], { validator: CreateReviewSchema // This doesn't work! })], }, ], }) ``` **Middleware order matters:** Put `authenticate` before `validateAndTransformBody` so authentication happens first. ### Step 1: Create Middleware File ```typescript // api/store/[feature]/middlewares.ts import { MiddlewareRoute, validateAndTransformBody } from "@medusajs/framework" import { z } from "zod" export const CreateMySchema = z.object({ email: z.string().email(), name: z.string().min(2), // other fields }) // Export the inferred type for use in route handlers export type CreateMySchema = z.infer<typeof CreateMySchema> export const myMiddlewares: MiddlewareRoute[] = [ { matcher: "/store/my-route", method: "POST", middlewares: [validateAndTransformBody(CreateMySchema)], }, ] ``` ### Step 2: Register in api/middlewares.ts ```typescript // api/middlewares.ts import { defineMiddlewares } from "@medusajs/framework/http" import { myMiddlewares } from "./store/[feature]/middlewares" export default defineMiddlewares({ routes: [...myMiddlewares], }) ``` **⚠️ CRITICAL - Middleware Export Pattern:** Middlewares are exported as **named arrays**, NOT default exports with config objects: ```typescript // ✅ CORRECT - Named export of MiddlewareRoute array // api/store/reviews/middlewares.ts export const reviewMiddlewares: MiddlewareRoute[] = [ { matcher: "/store/reviews", method: "POST", middlewares: [validateAndTransformBody(CreateReviewSchema)], }, ] // ✅ CORRECT - Import and spread the named array // api/middlewares.ts import { reviewMiddlewares } from "./store/reviews/middlewares" export default defineMiddlewares({ routes: [...reviewMiddlewares], }) ``` ```typescript // ❌ WRONG - Don't use default export with .config // api/store/reviews/middlewares.ts export default { config: { routes: [...], // This is NOT the middleware pattern! }, } // ❌ WRONG - Don't access .config.routes // api/middlewares.ts import reviewMid