# How to Access Request Parameters and Body in Medusa API Routes

> Learn how to access request parameters and body in Medusa API routes. Effortlessly retrieve URL params, query filters, and validated request body data for your custom endpoints.

- Repository: [Medusa/medusa](https://github.com/medusajs/medusa)
- Tags: how-to-guide
- Published: 2026-05-19

---

**In Medusa API routes, access URL path parameters via `req.params`, query filters via `req.filterableFields`, and request body data via `req.body` (raw) or `req.validatedBody` (type-checked after validation middleware).**

The medusajs/medusa repository provides a robust HTTP layer through the **@medusajs/framework/http** package. Every API route receives a strongly-typed request object that exposes multiple properties for accessing request parameters and body data. Understanding how to properly extract this data ensures type-safe handlers that integrate cleanly with Medusa’s workflow and query systems.

## Understanding MedusaRequest Types

Every route handler in Medusa receives a request object whose type derives from either **AuthenticatedMedusaRequest** (for routes requiring authentication) or the generic **MedusaRequest** (for public routes). These types extend standard Express request objects with Medusa-specific fields.

As defined in [`packages/framework/src/http/types.ts`](https://github.com/medusajs/medusa/blob/main/packages/framework/src/http/types.ts), these interfaces provide the foundation for `req.params`, `req.body`, `req.queryConfig`, and other context-aware properties. When you import types like **RequestWithContext** or **StoreRequestWithContext**, you gain access to additional fields such as `locale`, `pricingContext`, and `queryConfig` that the middleware stack automatically populates.

## Extracting URL Path Parameters with req.params

**Path parameters** captured from route definitions (e.g., `/:id`) are available on `req.params` as plain strings. You can destructure them directly for immediate use in database queries or workflow inputs.

In `packages/medusa/src/api/store/products/[id]/route.ts`, the handler extracts the product ID to perform a targeted lookup:

```typescript
export const GET = async (
  req: AuthenticatedMedusaRequest,
  res: MedusaResponse<HttpTypes.StoreProductResponse>
) => {
  const { id } = req.params

  const product = await query.graph({
    entity: "product",
    filters: { id },
    fields: req.queryConfig.fields,
    pagination: req.queryConfig.pagination,
  })

  res.json({ product })
}

```

The `req.params` object contains string values from the URL segments. When multiple parameters exist (e.g., `/:id/line-items/:line_id`), destructure them together: `const { id, line_id } = req.params`.

## Parsing Query String Filters via req.filterableFields

For list endpoints that accept query-string filters (e.g., `GET /store/products`), Medusa automatically parses filterable fields into **req.filterableFields**. This property contains validated and typed query parameters specific to the entity being listed.

In [`packages/medusa/src/api/store/products/route.ts`](https://github.com/medusajs/medusa/blob/main/packages/medusa/src/api/store/products/route.ts), the handler uses `req.filterableFields` to apply user-provided filters to the product query:

```typescript
export const GET = async (
  req: RequestWithContext<HttpTypes.StoreProductListParams>,
  res: MedusaResponse<HttpTypes.StoreProductListResponse>
) => {
  const filterableFields = req.filterableFields

  const { data: products, metadata } = await query.graph({
    entity: "product",
    filters: filterableFields,
    fields: req.queryConfig.fields,
    pagination: req.queryConfig.pagination,
  })

  res.json({ products, count: metadata!.count })
}

```

The `filterableFields` property returns a type-safe object (in this case `HttpTypes.StoreProductListParams`) that you can pass directly to the query layer without manual parsing.

## Handling Request Body Data

Medusa provides two properties for accessing incoming JSON payloads: `req.body` for raw data and `req.validatedBody` for validated, type-checked data.

### Accessing Raw Body Data with req.body

Use **req.body** when you need the raw JSON payload, such as when forwarding data directly to a workflow. In [`packages/medusa/src/api/store/payment-collections/route.ts`](https://github.com/medusajs/medusa/blob/main/packages/medusa/src/api/store/payment-collections/route.ts), the handler extracts the cart ID to create a payment collection:

```typescript
export const POST = async (
  req: AuthenticatedMedusaRequest<
    HttpTypes.StoreCreatePaymentCollection,
    HttpTypes.SelectParams
  >,
  res: MedusaResponse<HttpTypes.StorePaymentCollectionResponse>
) => {
  const { cart_id } = req.body

  await we.run(createPaymentCollectionForCartWorkflowId, {
    input: req.body,
  })

  res.status(200).json({ payment_collection: paymentCollection })
}

```

### Using Validated Body Data with req.validatedBody

After the built-in body-validation middleware runs (defined in [`packages/core/framework/src/http/utils/validate-body.ts`](https://github.com/medusajs/medusa/blob/main/packages/core/framework/src/http/utils/validate-body.ts)), a type-checked copy of the payload is stored in **req.validatedBody**. Use this property when you need guaranteed type safety after schema validation.

In `packages/medusa/src/api/store/carts/[id]/line-items/[line_id]/route.ts`, the handler accesses the validated quantity update:

```typescript
export const POST = async (
  req: AuthenticatedMedusaRequest<HttpTypes.StoreUpdateLineItem>,
  res: MedusaResponse<HttpTypes.StoreLineItemResponse>
) => {
  const { quantity } = req.validatedBody
  const lineId = req.params.line_id

  // Process the validated update...
}

```

The validated body ensures that `quantity` conforms to the expected schema, reducing runtime errors and eliminating the need for manual type guards.

## Leveraging Typed Request Helpers

Medusa extends base request types with context-aware helpers that expose additional request metadata. The **RequestWithContext** and **StoreRequestWithContext** types provide access to:

- **queryConfig**: Pre-computed fields and pagination settings
- **locale**: Current localization context
- **pricingContext**: Pricing-specific context for the request

These helpers are automatically populated by Medusa’s middleware stack, allowing you to write cleaner route handlers without manually parsing configuration or context data.

## Summary

- Access URL path parameters via **req.params**, which contains plain strings from route definitions like `/:id`.
- Retrieve parsed query filters via **req.filterableFields** in list endpoints, which provides type-safe filter objects.
- Read raw JSON payloads using **req.body** when forwarding data to workflows or services.
- Prefer **req.validatedBody** after validation middleware runs for type-safe, schema-validated data.
- Use **AuthenticatedMedusaRequest** or **MedusaRequest** as base types, and leverage **RequestWithContext** for additional fields like `queryConfig` and `locale`.

## Frequently Asked Questions

### What is the difference between req.body and req.validatedBody in Medusa?

**`req.body`** contains the raw JSON payload sent by the client, while **`req.validatedBody`** contains the same data after it has passed through Medusa's body-validation middleware. According to the implementation in [`packages/core/framework/src/http/utils/validate-body.ts`](https://github.com/medusajs/medusa/blob/main/packages/core/framework/src/http/utils/validate-body.ts), the middleware validates the payload against the route's schema and attaches the result to `req.validatedBody`. Use `req.body` for raw forwarding to workflows, and `req.validatedBody` when you need guaranteed type safety in your handler logic.

### How do I access query parameters in a Medusa API route?

For standard query strings used as filters, access **req.filterableFields**, which Medusa automatically parses and types based on the endpoint's expected parameters. This property is available on routes using types like `RequestWithContext<HttpTypes.StoreProductListParams>`. For custom query parameters that are not part of the filterable schema, you can access them via the standard Express `req.query` object, though Medusa's typed helpers are preferred for consistency.

### What type should I use for authenticated routes in Medusa?

Use **AuthenticatedMedusaRequest** for routes that require authentication. This type extends the base `MedusaRequest` with authentication-specific properties and ensures the route is properly protected. For public store routes, use the generic **MedusaRequest** or **StoreRequestWithContext** when you need access to store-specific context like `locale` or `pricingContext`.

### Where is the request validation middleware defined in Medusa?

The body validation logic that populates `req.validatedBody` is implemented in [`packages/core/framework/src/http/utils/validate-body.ts`](https://github.com/medusajs/medusa/blob/main/packages/core/framework/src/http/utils/validate-body.ts). This utility runs automatically on routes that have validation schemas defined, ensuring incoming payloads match expected types before your handler executes.