trpc-rest

OpenAPI Generator

Generate an OpenAPI 3.1.0 document from a tRPC router.

generateOpenApiDocument scans your tRPC router for procedures with openapi metadata and produces a complete OpenAPI 3.1.0 specification.

Basic usage

import { generateOpenApiDocument } from 'trpc-rest';

const doc = generateOpenApiDocument(appRouter, {
  title: 'My API',
  version: '1.0.0',
  baseUrl: 'https://api.example.com',
});

Options

OptionTypeRequiredDescription
titlestringYesAPI title
versionstringYesAPI version
baseUrlstringYesBase URL for the server
descriptionstringNoAPI description
tagsstring[]NoTag definitions
docsUrlstringNoExternal docs URL
securitySchemesRecord<string, unknown>NoSecurity scheme definitions
filter(opts) => booleanNoFilter which procedures to include
extensions(opts) => Record<string, unknown>NoAdd OpenAPI extensions to operations
errorSchemasErrorSchemaConfigNoError response schema configuration

OpenAPI metadata

Add openapi to any procedure's .meta():

t.procedure.meta({
  openapi: {
    method: 'GET',           // Required: HTTP method
    path: '/users/{id}',     // Required: URL path with {param} placeholders
    tags: ['Users'],         // Optional: OpenAPI tags
    summary: 'Get user',     // Optional: operation summary
    description: '...',      // Optional: operation description
    successDescription: 'OK',// Optional: 200 response description
    errorResponses: {        // Optional: additional error responses
      404: 'User not found',
    },
    protect: false,          // Optional: exclude from security (default: true)
    enabled: false,          // Optional: exclude from spec entirely
    deprecated: true,        // Optional: mark as deprecated
  },
});

Filtering procedures

Use filter to control which procedures appear in the spec:

generateOpenApiDocument(appRouter, {
  // ...
  filter: ({ path, metadata }) => {
    return metadata.includeInDocs === true;
  },
});

Error response schemas

Instead of inline error schemas, you can wire up $ref components:

import { generateOpenApiDocument, createErrorResponseSchema } from 'trpc-rest';

// Register error component schemas
createErrorResponseSchema('ErrorBadRequest', 'BAD_REQUEST', 'Bad request');
createErrorResponseSchema('ErrorUnauthorized', 'UNAUTHORIZED', 'Unauthorized');
createErrorResponseSchema('ErrorNotFound', 'NOT_FOUND', 'Not found');

const doc = generateOpenApiDocument(appRouter, {
  // ...
  errorSchemas: {
    schemas: {
      400: 'ErrorBadRequest',
      401: 'ErrorUnauthorized',
      404: 'ErrorNotFound',
    },
    autoAdd401: true, // Adds 401 to every operation automatically
  },
});

This produces clean $ref links in the spec:

"401": {
  "description": "Unauthorized",
  "content": {
    "application/json": {
      "schema": { "$ref": "#/components/schemas/ErrorUnauthorized" }
    }
  }
}

Schema conversion

The generator uses zod-openapi's createDocument for Zod-to-JSON-Schema conversion. This handles transforms, pipes, $ref deduplication, and .meta() annotations.

Path parameters from the input schema are automatically excluded from request bodies.

On this page