Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.vertz.dev/llms.txt

Use this file to discover all available pages before exploring further.

@vertz/openapi generates a fully typed TypeScript SDK from any OpenAPI 3.x spec. It produces typed resource methods, TypeScript interfaces, and optional Zod schemas — powered by @vertz/fetch under the hood.
This page covers generating SDKs from external OpenAPI specs (third-party APIs, FastAPI backends, etc.). For the SDK generated from your own Vertz entity definitions, see SDK & Fetch Client.

Install

vtz add -d @vertz/openapi

Quick start

npx @vertz/openapi generate --from ./openapi.json --output ./src/generated
This generates:
src/generated/
  client.ts          # createClient() factory + HttpClient interface
  types/             # TypeScript interfaces per resource
  resources/         # Typed resource methods per resource
  schemas/           # Zod schemas (opt-in with --schemas)
  README.md          # Usage documentation

Configuration

Create an openapi.config.ts in your project root:
import { defineConfig } from '@vertz/openapi';

export default defineConfig({
  source: './openapi.json',
  output: './src/generated',
  baseURL: 'https://api.example.com',
  groupBy: 'tag',
  schemas: true,
});
CLI flags override config file values.

CLI options

FlagDescriptionDefault
--from <path-or-url>Path to OpenAPI spec file or URLRequired (or use config)
--output <dir>Output directory./src/generated
--base-url <url>Default base URL for API calls''
--group-by <mode>Grouping: tag, path, nonetag
--schemasGenerate Zod validation schemasfalse
--exclude-tags <t>Comma-separated tags to excludenone
--dry-runPreview without writing filesfalse

Using the generated SDK

Install @vertz/fetch in the project that consumes the SDK:
vtz add @vertz/fetch
import { createClient } from './generated/client';
import { isOk } from '@vertz/fetch';

const api = createClient({ baseURL: 'https://api.example.com' });

const result = await api.tasks.list();
if (isOk(result)) {
  console.log(result.data); // typed as Task[]
}
Every method returns Result<T, FetchError> — never throws for HTTP errors.

Operation ID normalization

Many backend frameworks generate verbose operationIds that include the full URL path. The generator provides three levels of control to produce clean, idiomatic method names.

Auto-cleaning (default)

Without any configuration, the generator automatically:
  • Strips controller prefixes (e.g., TasksController_findAllfindAll)
  • Removes trailing HTTP method words (listTasksGetlistTasks)
  • Detects CRUD patterns from the HTTP method and path shape

Framework adapters

Built-in adapters handle operationId quirks for common backend frameworks. Import from @vertz/openapi/adapters.

FastAPI

FastAPI generates operationIds by concatenating the function name, route path, and HTTP verb:
list_tasks_tasks_get
get_user_v1_users__id__get
get_bot_activities_web_organizations__organization_id__b__brand_id__sites_agent_traffic_bot_activities_get
The fastapi() adapter strips the route+verb suffix, leaving just the meaningful function name:
import { defineConfig } from '@vertz/openapi';
import { fastapi } from '@vertz/openapi/adapters';

export default defineConfig({
  source: './openapi.json',
  output: './src/generated',
  operationIds: fastapi(),
});
FastAPI operationIdPathResult
list_tasks_tasks_get/taskslist_tasks
get_user_v1_users__id__get/v1/users/{id}get_user_v1
create_task_v2_tasks_post/v2/taskscreate_task_v2
delete_task_tasks__id__delete/tasks/{id}delete_task
get_bot_activities_web_...bot_activities_get/web/organizations/{id}/...get_bot_activities
The adapter also handles API version prefixes — if your path starts with /v1/, /v2/, etc., the version is preserved in the method name.

NestJS

NestJS (@nestjs/swagger) generates operationIds like TasksController_findAll. The adapter strips the Controller prefix:
import { defineConfig } from '@vertz/openapi';
import { nestjs } from '@vertz/openapi/adapters';

export default defineConfig({
  source: './openapi.json',
  output: './src/generated',
  operationIds: nestjs(),
});
NestJS operationIdResult
TasksController_findAllfindAll
UsersController.getByIdgetById

Custom transform

For full control, provide a transform function that receives the auto-cleaned name and a full OperationContext:
export default defineConfig({
  source: './openapi.json',
  operationIds: {
    transform: (cleaned, ctx) => {
      // ctx.operationId  — raw operationId from the spec
      // ctx.method       — GET, POST, PUT, DELETE, PATCH
      // ctx.path         — /v1/tasks/{id}
      // ctx.tags         — ['tasks']
      // ctx.hasBody      — whether the operation has a request body
      return cleaned;
    },
  },
});

Static overrides

For one-off renames, use overrides — a map from raw operationId to desired method name:
export default defineConfig({
  source: './openapi.json',
  operationIds: {
    overrides: {
      listTasks: 'fetchAll',
      getTask: 'findById',
    },
  },
});
Overrides take the highest priority — they’re applied before any transform or auto-cleaning.

Writing a custom adapter

An adapter is a function that returns { transform }. You can write one for any backend framework:
function myFramework() {
  return {
    transform: (cleaned, ctx) => {
      // Your logic using ctx.operationId, ctx.method, ctx.path, etc.
      return cleaned;
    },
  };
}

export default defineConfig({
  operationIds: myFramework(),
});

Excluding tags

Skip internal or deprecated tags:
export default defineConfig({
  source: './openapi.json',
  excludeTags: ['internal', 'deprecated'],
});
Operations where any tag matches the exclude list are skipped entirely.

Programmatic API

import { generateFromOpenAPI } from '@vertz/openapi';

const result = await generateFromOpenAPI({
  source: './openapi.json',
  output: './src/generated',
  baseURL: 'https://api.example.com',
  groupBy: 'tag',
  schemas: false,
});

console.log(`${result.written} files written, ${result.skipped} unchanged`);

Supported specs

  • OpenAPI 3.0.x and 3.1.x
  • JSON and YAML formats
  • File paths and URLs