Import a Gate Schema from Pydantic or Zod
If your validation logic already exists as a Pydantic model (Python) or a Zod schema (TypeScript), you can import it directly into a Flow gate. This tutorial walks through the full process: generating the JSON Schema output, pasting it into the gate editor, understanding warnings, and reviewing the imported rules before going live.
Time: 10 minutes Difficulty: Beginner
Prerequisites
- A Rynko account with Flow enabled
- A gate created in your workspace (create one)
- An existing Pydantic model or a Zod schema
Step 1: Generate JSON Schema from your model
The importer expects standard JSON Schema. Both Pydantic and Zod can produce this output directly.
- Pydantic (Python)
- Zod (TypeScript)
Run the following snippet with your model. Replace InvoiceModel with your own class:
import json
from pydantic import BaseModel, field_validator
from typing import Optional, List
from datetime import date
class LineItem(BaseModel):
description: str
quantity: int
unit_price: float
class InvoiceModel(BaseModel):
customer_name: str
customer_email: str
invoice_number: str
issue_date: date
due_date: date
line_items: List[LineItem]
notes: Optional[str] = None
paid: bool = False
# Pydantic v2 — recommended
print(json.dumps(InvoiceModel.model_json_schema(), indent=2))
# Pydantic v1
# print(json.dumps(InvoiceModel.schema(), indent=2))
Run with:
python generate_schema.py
Install zod-to-json-schema if you haven't already:
npm install zod-to-json-schema
Then run:
import { z } from 'zod';
import { zodToJsonSchema } from 'zod-to-json-schema';
const LineItemSchema = z.object({
description: z.string(),
quantity: z.number().int().min(1),
unitPrice: z.number().positive(),
});
const InvoiceSchema = z.object({
customerName: z.string(),
customerEmail: z.string().email(),
invoiceNumber: z.string().regex(/^INV-\d{4}-\d+$/),
issueDate: z.string().date(),
dueDate: z.string().date(),
lineItems: z.array(LineItemSchema),
notes: z.string().optional(),
paid: z.boolean().default(false),
});
console.log(JSON.stringify(zodToJsonSchema(InvoiceSchema), null, 2));
Run with:
npx tsx generate_schema.ts
You should see a JSON object starting with { "type": "object", "properties": { ... } }. Copy the entire output.
If the root of the output is something like { "$schema": "...", "$ref": "#/definitions/..." }, that's fine — the importer resolves $ref references automatically. Paste the full output as-is.
Step 2: Open the import dialog
- Go to Flow → Gates in the dashboard.
- Click the gate you want to configure (or create a new one).
- Click the Schema & Validate step card.
- In the Schema section, click Import from Pydantic / Zod.
The import dialog opens with two tabs: Pydantic and Zod.
Step 3: Paste and parse
- Select the correct tab for your schema source.
- Paste your JSON Schema output into the text area.
- Click Parse Schema.
The dialog previews what will be imported:
- Properties to import — the number of top-level fields found.
- Business rules to add — rules auto-generated from constraints like
if/then/else,uniqueItems, andnot. - Warnings — anything that could not be converted automatically.
A green checkmark means the schema parsed successfully. Review warnings before proceeding.
Step 4: Understand the warnings
Warnings appear when part of your schema cannot be converted automatically. Each warning shows a feature badge, the affected field name, and a description of what happened and what to do.
| Warning type | Cause | What to do |
|---|---|---|
| union type | Field uses Union[A, B] or z.union([...]) with multiple non-null types. Only the first type was imported. | Open the Schema Editor after importing and correct the field type manually, or split it into separate fields. |
| allOf merge conflict | Two allOf sub-schemas disagree on the same key. The last value was used. | Verify the field settings in the Schema Editor. |
| depth limit | Your model is nested more than 15 levels deep. Properties beyond that were skipped. | Add the missing nested fields manually in the Schema Editor. |
| not | A not constraint is too complex to auto-convert. It was skipped. | Add a Business Rule manually: !(fieldName == forbiddenValue). |
| if/then/else skipped | A conditional rule could not be expressed automatically. It was skipped entirely. | Add a Business Rule manually to replicate the condition. |
| if/then/else truncated | A generated conditional rule is longer than 450 characters and was cut short. | After importing, open Business Rules and rewrite or shorten the truncated rule. |
Don't activate the gate until all warnings are resolved. A truncated or skipped business rule means some of your validation logic is missing.
Step 5: Import
Once you're happy with the preview, click Import.
- The existing gate schema is replaced with the imported one.
- Existing business rules are preserved — imported rules are appended.
- Any linked Rynko render template is updated to the imported schema's source.
Each gate supports a maximum of 20 business rules. If the import would push you over this limit, the Import button will be disabled. Remove some existing rules first or reduce the rules in the imported schema.
Step 6: Review the imported schema
After importing, the Schema & Validate dialog shows a summary of your new schema.
- Click Edit Schema to open the Schema Editor and verify all field types are correct.
- Expand Business Rules to review any auto-generated rules. Check that each rule's expression and error message make sense.
- Click Save to apply everything to the gate.
Example: what the invoice model imports as
Given the Pydantic InvoiceModel from Step 1, the gate schema will contain:
| Field | Type | Required | Constraints |
|---|---|---|---|
customer_name | string | yes | — |
customer_email | string | yes | — |
invoice_number | string | yes | — |
issue_date | date | yes | — |
due_date | date | yes | — |
line_items | array of object | yes | — |
notes | string | no | — |
paid | boolean | no | default: false |
And the Zod version with .regex(/^INV-\d{4}-\d+$/) would also produce a pattern constraint on invoiceNumber.
Troubleshooting
"The pasted JSON does not describe an object model"
The importer expects the root of the JSON to be an object schema. Check that you're pasting the full output, not just a subset. If using Pydantic v1 with nested models, make sure to call .schema() on the top-level model, not a nested one.
Parse fails with "Invalid JSON"
A common cause is copying only part of the output (e.g. stopping before the last }). Try copying again from scratch using json.dumps(..., indent=2) in Python or JSON.stringify(..., null, 2) in TypeScript.
Union warnings for all my object fields
If every object field shows a union type warning with "object, object, object", your schema uses $ref references inside anyOf. This is common with Pydantic v2 models that use discriminated unions. The first variant is imported — check each affected field and adjust types manually in the Schema Editor.
Imported business rules have wrong field names
Pydantic uses snake_case by default (customer_name), while Zod typically uses camelCase (customerName). Make sure your business rule expressions reference the field names exactly as they appear in the imported schema.
Next steps
- Gates reference — full schema syntax, constraints, and business rule expressions
- Business rules — write cross-field validation expressions
- Submit your first run — validate a payload against the imported schema
- Set up approvals — add a human review step before delivery