Skip to content

Structured Output

When you define an output schema in the Promptly CMS, the SDK can automatically build Zod schemas at runtime for use with the Vercel AI SDK.

  1. Define a structured output schema in the CMS using the schema builder
  2. The schema fields are included in the prompt’s API response
  3. Use buildZodSchema() to build a Zod schema from these fields at runtime
  4. Pass it to the AI SDK’s Output.object() for validated, typed responses

For more control, use the buildZodSchema function from the /schema subpath export:

import { buildZodSchema } from '@promptlycms/prompts/schema';
const result = await promptly.getPrompt('extract-entities');
// Build a Zod schema from the CMS schema fields
const schema = buildZodSchema(result.config.schema);
// Use it however you need
const validated = schema.parse(data);

Generate Zod source code as a string for use in codegen pipelines:

import { schemaFieldsToZodSource } from '@promptlycms/prompts/schema';
const result = await promptly.getPrompt('extract-entities');
const source = schemaFieldsToZodSource(result.config.schema);
// source is a string like:
// z.object({
// name: z.string().min(1, 'Required'),
// age: z.number().int().positive(),
// tags: z.array(z.string()),
// })

The schema builder supports all common Zod types:

TypeZod equivalent
stringz.string()
numberz.number()
booleanz.boolean()
datez.date()
bigintz.bigint()
enumz.enum([...])
literalz.literal(...)
arrayz.array(...)
objectz.object({})
recordz.record(...)
mapz.map(...)
setz.set(...)
unionz.union([...])
intersectionz.intersection(...)
nullz.null()
undefinedz.undefined()
anyz.any()
unknownz.unknown()

Fields can include validation rules:

  • Size: min, max, length
  • String: email, url, uuid, cuid, cuid2, ulid, regex, startsWith, endsWith, datetime, ip
  • Number: int, positive, negative, multipleOf, finite, safe
  • Transforms: trim, toLowerCase, toUpperCase
  • Modifiers: optional, nullable, nullish, default, catch, readonly
  • Coercion: Fields can be marked as coercible (e.g. z.coerce.number())