Skip to main content

Import Zod schemas

Zod is where many TypeScript projects keep their runtime schema. A Zod schema carries the validation rules an API description needs — lengths, patterns, formats, numeric bounds — which a plain TypeScript type does not. Apiome imports a module's exported Zod schemas, with those rules, as schema types in the catalog.

What you can import​

You haveImport it as
One module that does import { z } from 'zod' and exports schemasOne file, or paste the source
Modules that import schemas from one another, with a root moduleOne archive with all the modules; the root is the module whose exports you want

Only the root module's exported schemas become part of the catalog item. A schema another module exports appears only when an exported schema refers to it.

Apiome reads the Zod 3 API (zod 3.x, or zod/v3). A module written against the Zod 4 entry points (zod/v4, zod/mini) is refused with FORMAT_VERSION_UNSUPPORTED.

Import it​

Import the file like any other specification: in the import wizard, with apiome import, or through the REST API (see Import a specification). Apiome recognises a module that imports zod and exports schemas, and picks Zod schemas (zod). A module of plain interface and type declarations goes to TypeScript types instead.

The schemas land in the Catalog as a schemas-only item, named after the root module's first exported object schema.

How the module is read​

A Zod schema is a value, so Apiome has to run the module to read it. It runs it in a sandbox:

  • The module can read nothing outside Apiome's own toolchain, start no process and open no network connection.
  • It sees an empty environment, so it cannot read the service's settings or secrets.
  • Only zod and the modules in your upload can be imported.
  • Importing the module and reading its schemas each have a 5-second time limit. A module that loops forever fails with INPUT_TIME_LIMIT.

A module that needs anything else at import time — environment variables, a configuration file, a network call — fails with INPUT_SEMANTIC_INVALID. Move that logic out of the schema module, or import a module that only declares schemas.

What each schema becomes​

ZodBecomes
z.object({ … })A record. merge, extend, pick, omit, partial and required are applied first.
z.enum([…]), z.nativeEnum(…)An enum.
z.union([…]), z.discriminatedUnion(…)A union. Inline object variants become records named after their discriminant, for example Problem_validation.
z.intersection(a, b) of objectsOne record with the properties of both.
z.array, z.set, z.tupleA list (set adds unique items; a tuple is bounded by its length).
z.record, z.mapA map.
A reference to another exported schema, including z.lazy recursionA reference to that schema's type.

Constraints are kept on the field:

ZodConstraint
.min(), .max(), .length()Minimum and maximum length (strings) or item count (arrays and sets)
.regex(), .startsWith(), .endsWith(), .includes()A pattern
.email(), .url(), .uuid(), .datetime(), .date(), .time()A format
.int()An integer type
.gt(), .gte(), .lt(), .lte(), .positive(), .nonnegative(), .multipleOf()Numeric bounds
.optional(), .nullable(), .nullish()A nullable field
.default()The field's default value
.describe()The description

What is declared, not imported​

Some Zod constructs have no schema equivalent. Apiome lists each one in the import's coverage ledger, under the schema's name, instead of dropping it silently:

  • Kept, with the rule listed: refine and superRefine, transform (including trim, toLowerCase and toUpperCase), preprocess, brand, pipe and z.coerce.*. The schema they wrap is imported; the rule itself is not.
  • Left out: z.custom(), z.function(), z.promise(), and schemas with no data meaning (never, symbol, NaN). Nothing is turned into any.
  • A tuple's per-position types and a catchall schema are recorded on the type and listed too.

When an import is refused​

Error codeWhy
INPUT_MALFORMEDThe module has a TypeScript syntax error, such as an unclosed call.
INPUT_TRUNCATEDThe module ends in the middle of a schema.
INPUT_SEMANTIC_INVALIDThe module exports no Zod schema, or it threw while it was being run (for example, it reads an environment variable).
INPUT_TIME_LIMITRunning the module, or reading its schemas, took longer than the time limit.
INPUT_REFERENCE_UNRESOLVEDThe module imports something other than zod and the modules in the upload.
FORMAT_MISMATCHThe module does not import zod; plain types belong to TypeScript types.
FORMAT_VERSION_UNSUPPORTEDThe module imports the Zod 4 API (zod/v4, zod/mini).
INPUT_ENCODING_INVALIDThe file is not UTF-8 (for example, it was saved as UTF-16).

What is inferred​

On the catalog item, a schema Apiome names (an anonymous object or a generic instantiation) is synthesized. Those entities carry a badge with the evidence, and the Provenance filter on the Overview tab narrows to them — see Declared, inferred and synthesized.