From medusa-commerce
Creates custom Medusa v2 API routes using file-based routing, HTTP method exports, Zod validators, middleware, and auth scopes. Use when adding REST endpoints.
npx claudepluginhub orcaqubits/agentic-commerce-skills-plugins --plugin medusa-commerceThis skill is limited to using the following tools:
**Fetch live docs**:
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Fetch live docs:
https://docs.medusajs.com/learn/fundamentals/api-routes for API route overviewsite:docs.medusajs.com custom API route file convention for file-based routingsite:docs.medusajs.com API route middleware for middleware configurationsite:docs.medusajs.com API route validation zod for request validationsite:docs.medusajs.com additional data API routes for the additional-data patternMedusa v2 uses a file-system router under src/api/:
| File Path | Resulting Endpoint |
|---|---|
src/api/store/custom/route.ts | GET/POST /store/custom |
src/api/admin/custom/route.ts | GET/POST /admin/custom |
src/api/store/custom/[id]/route.ts | GET/POST /store/custom/:id |
src/api/custom/route.ts | GET/POST /custom (no auth prefix) |
route.ts (not index.ts)[param] folder syntaxstore/ prefix applies storefront authentication scopeadmin/ prefix applies admin authentication scopeEach route.ts exports named functions matching HTTP methods:
| Export Name | HTTP Method |
|---|---|
GET | GET |
POST | POST |
PUT | PUT |
PATCH | PATCH |
DELETE | DELETE |
// src/api/store/custom/route.ts
// Fetch live docs for MedusaRequest/MedusaResponse types
import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http"
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
const service = req.scope.resolve("my-module")
res.json({ items: await service.listMyEntities() })
}
// src/api/store/custom/[id]/route.ts
// Fetch live docs for path parameter access
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
const item = await req.scope.resolve("my-module").retrieveMyEntity(req.params.id)
res.json({ item })
}
Medusa v2 uses Zod schemas for request body and query parameter validation:
| Validation Target | File |
|---|---|
| POST/PUT/PATCH body | validators.ts in same directory as route.ts |
| Query parameters | Same validators.ts file |
// src/api/store/custom/validators.ts
// Fetch live docs for Zod schema integration
import { z } from "zod"
export const PostStoreCustom = z.object({
name: z.string(),
description: z.string().optional(),
})
Validators are linked to routes via middleware configuration.
All middleware is configured in src/api/middlewares.ts:
// src/api/middlewares.ts — Fetch live docs for defineMiddlewares API
import { defineMiddlewares, validateAndTransformBody } from "@medusajs/framework/http"
import { PostStoreCustom } from "./store/custom/validators"
export default defineMiddlewares({
routes: [{ matcher: "/store/custom", method: "POST",
middlewares: [validateAndTransformBody(PostStoreCustom)] }],
})
| Utility | Purpose |
|---|---|
validateAndTransformBody(schema) | Validate request body with Zod |
validateAndTransformQuery(schema) | Validate query parameters |
authenticate("customer", ["session", "bearer"]) | Require customer auth |
authenticate("user", ["session", "bearer"]) | Require admin auth |
| Route Prefix | Default Auth | Custom Auth Override |
|---|---|---|
/admin/* | Admin user required | Can be loosened per route |
/store/* | Optional customer auth | Can require auth per route |
/custom/* | None | Must add explicitly |
// In middlewares.ts routes array
// Fetch live docs for authenticate() options
{
matcher: "/store/custom/me",
middlewares: [authenticate("customer", ["session", "bearer"])],
}
Medusa v2 supports passing extra data through built-in API routes to workflow hooks:
additional_dataadditionalDataValidator in middlewareadditional_dataThis allows extending core commerce flows (e.g., adding custom fields to product creation) without overriding API routes.
| Error Type | Recommended Approach |
|---|---|
| Validation error | Handled automatically by Zod middleware (400) |
| Not found | Throw MedusaError with NOT_FOUND type |
| Unauthorized | Handled by auth middleware (401) |
| Business logic | Throw MedusaError with appropriate type |
| Unexpected | Let Medusa error handler return 500 |
validateAndTransformBodyreq.scope -- never import services directlyadditional_data pattern to extend core routes instead of overriding themauthenticate() middleware explicitly for routes requiring auth outside default scopes{ item } for single, { items, count, offset, limit } for listsFetch the Medusa API route documentation for exact file conventions, middleware utilities, and Zod integration patterns before implementing.