---
title: "Announcing API Routes"
description: "This is a new page"
url: https://medusajs.com/blog/announcing-api-routes
last_updated: 2026-08-13T14:25:35Z
---

# Announcing API Routes

_Published 2023-10-19 by Kasper Kristensen in Product_

Today, we are excited to announce API Routes – a massive improvement of the developer experience of a core concept in Medusa’s extensibility toolbox.

We are highly committed to delivering a world-class experience across all our products. With our commerce primitives and tooling, developers can effortlessly build unique digital commerce applications at record speed.

## **API Routes**

API Routes in Medusa is a place for developers to add custom logic that HTTP requests can trigger. The endpoints have direct access to Medusa’s core services like the Product and Cart services and custom services added to your project or in installed plugins.

To create a custom endpoint in Medusa, developers have had to familiarize themselves with application routing and Express more generally. This created friction unrelated to our product, leading to frustration from users, the community, and our support team.

Today, we are introducing API Routes - drastically simplifying creating custom endpoints in Medusa.

Developers can now create custom routes using simple JavaScript without worrying about the intricacies of the Express Router. Routes are registered using the file system, an approach familiar to many from frameworks like Next.js and Svelte.

```typescript
// api/admin/products/route.ts
import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"

export async function GET(req: MedusaRequest, res: MedusaResponse) {
    const productService = req.scope.resolve("productService")

    const products = await productService.list()

    res.json({ products })
}
```

The example above illustrates a few key points of API Routes:

- Endpoint paths are inferred from the file path
- `route.{ts|js}` is a special file that contains the router handlers
- HTTP methods are defined by the route handler name; here `GET`

In the example above, we register a `GET` route at path `/admin/products`.

### **Dynamic Segments**

API Routes support dynamic URL segments and are similarly registered through the file system.

```typescript
// api/admin/products/[id]/route.ts

import { MedusaRequest, MedusaResponse } from "@medusajs/medusa"

export async function POST(req: MedusaRequest, res: MedusaResponse) {
  const { id } = req.params
    const { payload } = req.body

    const productService = req.scope.resolve("productService")

    const product = await productService.update(id, payload)

    res.json({ product })
}
```

In the example above, we register a `POST` route at path `/admin/products/:id`. The brackets in the file path, `api/admin/products/[id]/route.ts`, specify a parameter that can be accessed within the handler.

You can add as many dynamic segments as you’d like. However, if the parameter names clash, an error will be thrown, and your application will terminate.

### **Middlewares**

Adding middleware to routes has also been simplified. With API Routes, we are centralizing all middlewares in a file at `api/middlewares.{ts|js}`. In this file, you can register middleware to all endpoints, a subset of endpoints, or one at a time.

```typescript
// api/middlewares.ts

export const config: MiddlewaresConfig = {
  routes: [
    {
      method: ["GET", "POST"],
      matcher: "/store/*",
      middlewares: [someStoreMiddleware],
    },
  ],
}
```

Per default, middleware is registered globally. The `matcher` option is required to configure the paths the middlewares apply to. The `method` option is used to configure the specific methods the middlewares apply to.

In the example above, we register a middleware, `someStoreMiddleware`, to all paths starting with `/store` that use HTTP methods `GET` and `POST`.

## **What’s next?**

We are excited to hear your thoughts about our new API Routes. If you have any feedback or experience issues, don’t hesitate to post on our GitHub Issues board or GitHub Discussions.

In the future, we plan to extend the `MedusaRequest` and `MedusaResponse` to offer an even better experience with access to types specific to our Request and Response context, such as the Awilix dependency container living at `req.scope`.

Track our progress on [X](https://twitter.com/medusajs) and in our [changelog](https://medusajs.com/changelog/).
