response_schema automatically. The shape you pass determines what they type into. This page lists every shape that renders well, and what falls back to a JSON textarea.
Primitives
Map cleanly to form fields.| Pydantic type | Reviewer sees |
|---|---|
str with max_length <= 200 | Single-line text input |
str with no max or max_length > 200 | Multi-line textarea |
int, float | Number input (with decimal support for floats) |
bool | Yes/No toggle |
Enum of strings | Dropdown of the enum values |
Optional fields
Optional[X] flattens to the underlying type. The form field is unrequired but renders as the inner kind, not as a generic JSON textarea.
Nested objects
Render as an indented section with the inner fields stacked vertically. Useful for grouping related data.Lists of objects (the killer feature)
list[BaseModel] becomes a spreadsheet-style editable table on the reviewer’s dashboard. One column per property of the element model. The reviewer adds rows, edits cells inline, removes rows.
line_items:
Multi-page response patterns
Three common ways to structure a response for a multi-page document. Pick the one that matches your downstream code; the SDK doesn’t enforce any particular pattern.Pattern 1: Flat list across all pages (simplest)
Pattern 2: Page-keyed structure
repeatable_group (spreadsheet) where each row is itself a section (the per-page object). The reviewer adds one row per page and fills in the section per row. Useful when your downstream code reasons about pages explicitly.
Pattern 3: Top-level totals + nested table
Fields and constraints we recognize
| Pydantic feature | Effect on the form |
|---|---|
Field(description="...") | Becomes the hint text under the field |
Field(title="...") | Becomes the field label (overrides the property name) |
Field(max_length=N) | Short vs long text rendering (≤200 → short) |
Field(min_length=N) | Validation hint, shown on submit if violated |
Field(default=...) | Used as the field’s initial value if no prior_extraction is supplied |
What doesn’t render well (yet)
Some shapes fall back to a long_text JSON textarea. The reviewer can still submit (by typing JSON), but the UX isn’t ideal. v1 limitations:Union[str, int]and similar multi-variant unions- Discriminated unions
- Self-referential schemas (a model that references itself)
- Schemas nested deeper than 6 levels
Examples
The smoke test we use in CI is a real reference for what works:Where to go next
The three flows
Combine schemas with Flow A (prior_extraction) for pre-filled forms.
Providers
Flow B: which provider you pick affects how the extraction maps to your schema.