Documentation

Getting Started

Install the module, define your first endpoint, and call it with types.

In a few minutes you will have a Nuxt route that validates its input at runtime, a client call with fully inferred types, and an OpenAPI document — all from one endpoint definition.

Compatibility

Nuxt Endpoints currently supports Nuxt 4.5+ with Nitro 2 and H3 1. It brings the route-contract direction being developed for the Nuxt 5 generation to Nuxt 4 today, while implementing the missing lower-level pieces inside the module.

$endpoint and useEndpoint are stable application-facing concepts owned by Nuxt Endpoints. As H3, Nitro, and Nuxt expose suitable upstream primitives, the module will adopt them behind that UX and retain only the missing integration. Upstream APIs are evolving, so necessary changes remain possible, but preserving application code is an explicit design goal.

The experimental implementation is developed in public. See Nuxt 5 integration progress for the Nuxt Endpoints branch and its matching H3, Nitro, and fetchdts forks.

This section is the single source for the supported platform line; other pages link here instead of restating it.

Install

Add Nuxt Endpoints through the Nuxt CLI:

npx nuxt module add nuxt-endpoints

Then install the schema library you want to use in endpoint definitions — Zod, Valibot, and Effect are optional peer dependencies:

npm install zod

Install with Valibot:

npm install valibot

Install with Effect Schema:

npm install effect

Your first endpoint

Create an explicit, file-based Nuxt server route and default-export a defineEndpoint() call. The route remains an HTTP endpoint; Nuxt Endpoints adds the contract-aware handler API inside it.

// server/api/users/[id].get.ts
import { z } from 'zod'
export default defineEndpoint({
  summary: 'Get a user',
  request: {
    params: z.object({ id: z.coerce.number() }),
  },
  responses: { 200: z.object({ id: z.number(), name: z.string() }) },
  handler: (event) => {
    return { id: event.validated.params.id, name: 'Tom' } // params.id is a number — validated and coerced
  },
})

Call it from any component. Request options and the response type are inferred — there is no codegen step to run and no types to import:

<script setup lang="ts">
const result = await $endpoint('/api/users/:id', {
  method: 'get',
  params: { id: '1' },
})

if (result.status === 200) result.body.name.toUpperCase()
</script>

Requests that do not match the contract are rejected before your handler runs — try /api/users/abc and the z.coerce.number() param fails validation.

While the dev server is running, the generated OpenAPI 3.1 document for this route is served at /_endpoints/schema.

From here:

  • Define Endpoints covers the full contract surface: validated request parts, multiple response statuses, and response validation.
  • Generated Client covers everything $endpoint and useEndpoint can do.

Configure Nuxt

The Nuxt CLI adds nuxt-endpoints to modules. The generated OpenAPI route and optional client helpers can be configured through endpoints.

export default defineNuxtConfig({
  modules: ['nuxt-endpoints'],
  endpoints: {
    openApi: {
      path: '/_endpoints/schema',
      title: 'Example API',
      version: '1.0.0',
    },
    client: { raw: true },
  },
})

openApi can also be set to false to disable the generated schema route. By default, the schema route is only served in development; set openApi: true or openApi.enabled: true to also serve it in production. client.raw controls whether .raw() is generated on $endpoint calls.

Shared application responses use the conventional server/routes.config.ts file. Set endpoints.serverRouteConfig.path only when that file lives elsewhere; see Responses.

Nuxt Endpoints exposes typed adapters from #endpoints/colada for standard Pinia Colada query, mutation, and infinite-query options. For cache, SSR, and hydration support, install Colada and its official Nuxt modules:

vp add @pinia/colada @pinia/colada-nuxt pinia @pinia/nuxt

Add @pinia/nuxt and @pinia/colada-nuxt to modules; Nuxt Endpoints does not install a second cache plugin. See Pinia Colada for queryOptions(), mutationOptions(), and cursor pagination.

What gets generated

  • $endpoint: a generated path/method client available in Nuxt app code.
  • #endpoints: helper types for paths, methods, calls, status-aware typed results, and raw Web Responses.
  • /_endpoints/schema: the default OpenAPI 3.1 document route when OpenAPI generation is enabled.

Adding the module changes nothing by itself: only routes whose default export is a direct defineEndpoint({...}) call are affected. Existing routes keep working unchanged — see Incremental Adoption.