---
title: "Zod v3 Plugin"
description: "Generate Zod v3 schemas from OpenAPI with the Zod plugin for openapi-ts. Fully compatible with validators, transformers, and all core features."
url: "https://heyapi.dev/docs/openapi/typescript/plugins/zod/v3"
---

### About

[Section titled “About”](#about)

[Zod](https://v3.zod.dev/) is a TypeScript-first schema validation library with static type inference.

The Zod plugin for Hey API generates schemas from your OpenAPI spec, fully compatible with validators, transformers, and all core features.

## Features

[Section titled “Features”](#features)

* Zod v3 support
* seamless integration with `@hey-api/openapi-ts` ecosystem
* Zod schemas for requests, responses, and reusable definitions
* minimal learning curve thanks to extending the underlying technology

## Installation

[Section titled “Installation”](#installation)

In your [configuration](https://heyapi.dev/openapi-ts/get-started), add `zod` to your plugins and you’ll be ready to generate Zod artifacts. 🎉

openapi-ts.config.ts

```js
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  plugins: [
    // ...other plugins
    {
      name: 'zod',
      compatibilityVersion: 3,
    },
  ],
};
```

### SDKs

[Section titled “SDKs”](#sdks)

To add data validators to your SDKs, set `sdk.validator` to `true`.

openapi-ts.config.ts

```js
export default {
  input: 'hey-api/backend', // sign up at app.heyapi.dev
  output: 'src/client',
  plugins: [
    // ...other plugins
    {
      name: 'zod',
      compatibilityVersion: 3,
    },
    {
      name: '@hey-api/sdk',
      validator: true,
    },
  ],
};
```

Learn more about data validators in your SDKs on the [SDKs](https://heyapi.dev/openapi-ts/plugins/sdk#validators) page.

## Output

[Section titled “Output”](#output)

The Zod plugin will generate the following artifacts, depending on the input specification.

## Requests

[Section titled “Requests”](#requests)

A Zod schema is generated for every request layer of each endpoint.

* example

  zod.gen.ts

  ```ts
  const zDeletePetHeaders = z.object({
    api_key: z.string().optional(),
  });


  const zDeletePetPath = z.object({
    petId: z.number(),
  });


  const zDeletePetQuery = z.object({
    additionalMetadata: z.string(),
  });
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: 'zod',
        compatibilityVersion: 3,
        requests: true,
      },
    ],
  };
  ```

You can customize the naming and casing pattern for `requests` schemas using the `.name` and `.case` options.

## Responses

[Section titled “Responses”](#responses)

A single Zod schema is generated for all endpoint’s responses. If the endpoint describes multiple responses, the generated schema is a union of all possible response shapes.

* example

  zod.gen.ts

  ```ts
  const zResponse = z.union([
    z.object({
      foo: z.string().optional(),
    }),
    z.object({
      bar: z.number().optional(),
    }),
  ]);
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: 'zod',
        compatibilityVersion: 3,
        responses: true,
      },
    ],
  };
  ```

You can customize the naming and casing pattern for `responses` schemas using the `.name` and `.case` options.

## Definitions

[Section titled “Definitions”](#definitions)

A Zod schema is generated for every reusable definition from your input.

* example

  zod.gen.ts

  ```ts
  const zFoo = z.number().int();


  const zBar = z.object({
    bar: z.array(z.number().int()).optional(),
  });
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: 'zod',
        compatibilityVersion: 3,
        definitions: true,
      },
    ],
  };
  ```

You can customize the naming and casing pattern for `definitions` schemas using the `.name` and `.case` options.

## ISO Datetimes

[Section titled “ISO Datetimes”](#iso-datetimes)

By default, values without a timezone or with a timezone offset are not allowed in the `z.string().datetime()` method.

### Timezone offsets

[Section titled “Timezone offsets”](#timezone-offsets)

You can allow values with timezone offsets by setting `dates.offset` to `true`.

* example

  zod.gen.ts

  ```ts
  export const zFoo = z.string().datetime({ offset: true });
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: 'zod',
        compatibilityVersion: 3,
        dates: {
          offset: true,
        },
      },
    ],
  };
  ```

### Local times

[Section titled “Local times”](#local-times)

You can allow values without a timezone by setting `dates.local` to `true`.

* example

  zod.gen.ts

  ```ts
  export const zFoo = z.string().datetime({ local: true });
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: 'zod',
        compatibilityVersion: 3,
        dates: {
          local: true,
        },
      },
    ],
  };
  ```

## Metadata

[Section titled “Metadata”](#metadata)

It’s often useful to associate a schema with some additional [metadata](https://v3.zod.dev/?id=describe) for documentation, code generation, AI structured outputs, form validation, and other purposes. If this is your use case, you can set `metadata` to `true` to generate additional metadata about schemas.

* example

  zod.gen.ts

  ```ts
  export const zFoo = z.string().describe('Additional metadata');
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: 'zod',
        compatibilityVersion: 3,
        metadata: true,
      },
    ],
  };
  ```

## Types

[Section titled “Types”](#types)

In addition to Zod schemas, you can generate schema-specific types. These can be generated for all schemas or for specific resources.

* example

  zod.gen.ts

  ```ts
  export type ResponseZodType = z.infer<typeof zResponse>;
  ```

* config

  openapi-ts.config.ts

  ```js
  export default {
    input: 'hey-api/backend', // sign up at app.heyapi.dev
    output: 'src/client',
    plugins: [
      // ...other plugins
      {
        name: 'zod',
        compatibilityVersion: 3,
        types: {
          infer: false, // by default, no `z.infer` types
        },
        responses: {
          types: {
            infer: true, // `z.infer` types only for response schemas
          },
        },
      },
    ],
  };
  ```

You can customize the naming and casing pattern for schema-specific `types` using the `.name` and `.case` options.

## Resolvers

[Section titled “Resolvers”](#resolvers)

You can further customize this plugin’s behavior using [resolvers](https://heyapi.dev/openapi-ts/plugins/concepts/resolvers).

## API

[Section titled “API”](#api)

You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/zod/types.ts) interface.

## Examples

You can view live examples on [StackBlitz](https://stackblitz.com/orgs/github/hey-api/collections/openapi-ts-examples) or on [GitHub](https://github.com/hey-api/openapi-ts/tree/main/examples).
