Parser 
We parse your input before making it available to plugins. Configuring the parser is optional, but it provides an ideal opportunity to modify or validate your input as needed.
Patch 
Sometimes you need to modify raw input before it's processed further. A common use case is fixing an invalid specification or adding a missing field. For this reason, custom patches are applied before any parsing takes place.
You can add custom patches with patch.
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    patch: {
      schemas: {
        Foo: (schema) => { 
          // convert date-time format to timestamp
          delete schema.properties.updatedAt.format; 
          schema.properties.updatedAt.type = 'number'; 
        }, 
        Bar: (schema) => { 
          // add missing property
          schema.properties.meta = { 
            additionalProperties: true, 
            type: 'object', 
          }; 
          schema.required = ['meta']; 
        }, 
        Baz: (schema) => { 
          // remove property
          delete schema.properties.internalField; 
        }, 
      },
    },
  },
};Validate 
WARNING
The validator feature is very limited. You can help improve it by submitting more use cases.
If you don't control or trust your input, you might want to validate it. Any detected errors in your input will exit @hey-api/openapi-ts and no plugins will be executed.
To validate your input, set validate_EXPERIMENTAL to true.
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    validate_EXPERIMENTAL: true, 
  },
};Filters 
Filters allow you to trim your input before it's processed further, so your output contains only relevant resources.
Operations 
Set include to match operations to be included or exclude to match operations to be excluded. Both exact keys and regular expressions are supported. When both rules match the same operation, exclude takes precedence over include.
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    filters: {
      operations: {
        include: ['GET /api/v1/foo', '/^[A-Z]+ /api/v1//'], 
      },
    },
  },
};export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    filters: {
      operations: {
        exclude: ['GET /api/v1/foo', '/^[A-Z]+ /api/v1//'], 
      },
    },
  },
};Tags 
Set include to match tags to be included or exclude to match tags to be excluded. When both rules match the same tag, exclude takes precedence over include.
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    filters: {
      tags: {
        include: ['v2'], 
      },
    },
  },
};export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    filters: {
      tags: {
        exclude: ['v1'], 
      },
    },
  },
};Deprecated 
You can filter out deprecated resources by setting deprecated to false.
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    filters: {
      deprecated: false, 
    },
  },
};Schemas 
Set include to match schemas to be included or exclude to match schemas to be excluded. Both exact keys and regular expressions are supported. When both rules match the same schema, exclude takes precedence over include.
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    filters: {
      schemas: {
        include: ['Foo', '/^Bar/'], 
      },
    },
  },
};export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    filters: {
      schemas: {
        exclude: ['Foo', '/^Bar/'], 
      },
    },
  },
};Parameters 
Set include to match parameters to be included or exclude to match parameters to be excluded. Both exact keys and regular expressions are supported. When both rules match the same parameter, exclude takes precedence over include.
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    filters: {
      parameters: {
        include: ['QueryParameter', '/^MyQueryParameter/'], 
      },
    },
  },
};export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    filters: {
      parameters: {
        exclude: ['QueryParameter', '/^MyQueryParameter/'], 
      },
    },
  },
};Request Bodies 
Set include to match request bodies to be included or exclude to match request bodies to be excluded. Both exact keys and regular expressions are supported. When both rules match the same request body, exclude takes precedence over include.
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    filters: {
      requestBodies: {
        include: ['Payload', '/^SpecialPayload/'], 
      },
    },
  },
};export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    filters: {
      requestBodies: {
        exclude: ['Payload', '/^SpecialPayload/'], 
      },
    },
  },
};Responses 
Set include to match responses to be included or exclude to match responses to be excluded. Both exact keys and regular expressions are supported. When both rules match the same response, exclude takes precedence over include.
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    filters: {
      responses: {
        include: ['Foo', '/^Bar/'], 
      },
    },
  },
};export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    filters: {
      responses: {
        exclude: ['Foo', '/^Bar/'], 
      },
    },
  },
};Orphaned resources 
If you only want to exclude orphaned resources, set orphans to false. This is the default value when combined with any other filters. If this isn't the desired behavior, you may want to set orphans to true to always preserve unused resources.
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    filters: {
      orphans: false, 
    },
  },
};Order 
For performance reasons, we don't preserve the original order when filtering out resources. If maintaining the original order is important to you, set preserveOrder to true.
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    filters: {
      preserveOrder: true, 
    },
  },
};Transforms 
You can think of transforms as deterministic patches. They provide an easy way to apply the most commonly used input transformations.
Enums 
Your input might contain two types of enums:
- enums defined as reusable components (root enums)
 - non-reusable enums nested within other schemas (inline enums)
 
You may want all enums to be reusable. This is because only root enums are typically exported by plugins. Inline enums will never be directly importable since they're nested inside other schemas.
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    transforms: {
      enums: 'root', 
    },
  },
};export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    transforms: {
      enums: 'inline', 
    },
  },
};You can customize the naming and casing pattern for enums schemas using the .name and .case options.
Read-write 
Your schemas might contain read-only or write-only fields. Using such schemas directly could mean asking the user to provide a read-only field in requests, or expecting a write-only field in responses. We separate schemas for requests and responses if direct usage would result in such scenarios.
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    transforms: {
      readWrite: {
        requests: '{{name}}Writable', 
        responses: '{{name}}', 
      },
    },
  },
};export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    transforms: {
      readWrite: false, 
    },
  },
};You can customize the naming and casing pattern for requests and responses schemas using the .name and .case options.
Pagination 
Paginated operations are detected by having a pagination keyword in its parameters or request body. By default, we consider the following to be pagination keywords: after, before, cursor, offset, page, and start.
You can provide custom pagination keywords using pagination.keywords.
import { defaultPaginationKeywords } from '@hey-api/openapi-ts';
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    pagination: {
      keywords: [
        ...defaultPaginationKeywords, 
        'extra', 
        'pagination', 
        'keywords', 
      ],
    },
  },
};export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    pagination: {
      keywords: [
        'custom', 
        'pagination', 
        'keywords', 
      ],
    },
  },
};Hooks 
Hooks affect runtime behavior but aren’t tied to any single plugin. They can be configured globally via parser.hooks or per plugin through the ~hooks property.
Operations 
Each operation has a list of classifiers that can include query, mutation, both, or none. Plugins may use these values to decide whether to generate specific output. For example, you usually don’t want to generate TanStack Query options for PATCH operations.
Query operations 
By default, GET operations are classified as query operations.
Mutation operations 
By default, DELETE, PATCH, POST, and PUT operations are classified as mutation operations.
Example: POST search query 
Imagine your API has a POST /search endpoint that accepts a large payload. By default, it's classified as a mutation, but in practice it behaves like a query, and your state management plugin should generate query hooks.
You can fix this by classifying the operation as query in a matcher. If a matcher returns no value, we fall back to less specific matchers until one does.
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  parser: {
    hooks: {
      operations: {
        isQuery: (op) => {
          if (op.method === 'post' && op.path === '/search') { 
            return true; 
          } 
        },
      },
    },
  },
};export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  plugins: [
    {
      name: '@tanstack/react-query',
      '~hooks': {
        operations: {
          getKind: (op) => {
            if (op.method === 'post' && op.path === '/search') { 
              return ['query']; 
            } 
          },
        },
      },
    },
  ],
};Examples 
You can view live examples on StackBlitz.
Sponsors 
Help Hey API stay around for the long haul by becoming a sponsor.

