Skip to main content

Gates

A gate is a named validation checkpoint. It defines what data structure you expect, what business rules must hold, and what happens after validation succeeds (rendering, approval, delivery).

Gate Identifiers

Every gate has three identifiers you can use interchangeably in API calls:

TypeFormatExample
UUID36 characters550e8400-e29b-41d4-a716-446655440000
shortIdfgate_ + 8 charsfgate_a1b2c3d4
sluglowercase + hyphensorder-validation

The slug is auto-generated from the gate name and is unique within your workspace.


Schema Definition

Gate schemas use an object format to define expected fields:

{
"type": "object",
"properties": {
"customerName": { "type": "string", "required": true },
"email": { "type": "string", "required": true, "format": "email" },
"amount": { "type": "number", "required": true, "min": 0 },
"isPriority": { "type": "boolean", "required": false },
"orderDate": { "type": "date", "required": true },
"tags": { "type": "array", "itemType": "string" },
"address": {
"type": "object",
"properties": {
"street": { "type": "string", "required": true },
"city": { "type": "string", "required": true },
"zip": { "type": "string", "required": true }
}
}
}
}

Supported Types

TypeDescriptionConstraints
stringText valueminLength, maxLength, format, allowedValues
numberNumeric valuemin, max
booleanTrue/false
dateDate string
arrayList of itemsitemType (required)
objectNested objectproperties (required)

String Formats

The format constraint validates string patterns:

FormatValidates
emailEmail address
urlURL

Allowed Values

Restrict a field to a set of valid options:

{
"status": {
"type": "string",
"required": true,
"allowedValues": ["pending", "active", "completed", "cancelled"]
}
}

Import from Template

If you have an existing Rynko document template, you can import its variables as a gate schema:

curl -X POST https://api.rynko.dev/api/flow/gates/ORDER_GATE_ID/import-schema \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "templateId": "invoice-template" }'

This copies the template's variable definitions into the gate schema and sets the gate's validation mode to variables.

Import from Pydantic or Zod

If your validation logic already lives in a Pydantic model (Python) or a Zod schema (TypeScript), you can paste its JSON Schema output directly into the gate — no need to rebuild the schema from scratch.

Generate the JSON Schema output

import json
from pydantic import BaseModel
from typing import Optional
from datetime import date

class OrderModel(BaseModel):
customer_name: str
email: str
amount: float
quantity: int
order_date: date
notes: Optional[str] = None

# Pydantic v2
print(json.dumps(OrderModel.model_json_schema(), indent=2))

# Pydantic v1
# print(json.dumps(OrderModel.schema(), indent=2))

Copy the printed JSON output to your clipboard.

Import in the dashboard

  1. Open your gate and click Schema & Validate.
  2. Click Import from Pydantic / Zod.
  3. Select the Pydantic or Zod tab.
  4. Paste the JSON output into the text area.
  5. Click Parse Schema to preview what will be imported.
  6. Review any warnings, then click Import.

The import replaces the existing schema and merges any generated business rules into your existing ones (existing rules are preserved).

What gets imported

Schema featureImported as
Object propertiesGate schema properties with mapped types
required fieldsrequired: true on each property
minimum / maximummin / max constraints
minLength / maxLengthString length constraints
patternRegex pattern constraint
enum / constallowedValues constraint
defaultDefault value constraint
format: date or date-timedate type
format: emailString with email format
integer typenumber type + multipleOf: 1 constraint
Nested $ref objectsNested object properties (resolved recursively)
anyOf / oneOf with a null variantNullable field (required: false)
if / then / elseBusiness rule (where convertible)
uniqueItems: true on an arrayBusiness rule checking array uniqueness
not constraintBusiness rule (where convertible)

Understanding import warnings

Any part of the schema that could not be converted automatically produces a warning. Warnings are shown immediately after parsing — review each one and resolve it in the Schema Editor or Business Rules section before saving.

Warning typeWhat happenedWhat to do
union typeThe field is a union of multiple incompatible types (e.g. Union[A, B, C]). Only the first type was imported.Open the Schema Editor and correct the field type, or split it into separate fields.
allOf merge conflictTwo allOf schemas defined conflicting values for the same key. The last value was used.Verify the field's settings in the Schema Editor.
depth limitThe model exceeds 15 levels of nesting. Properties beyond that were not imported.Add the missing nested fields manually in the Schema Editor.
notA not constraint is too complex to auto-convert. It was skipped.Add a Business Rule manually using !(expression) syntax.
if/then/else skippedA conditional rule's condition uses unsupported patterns. The rule was skipped entirely.Add a Business Rule manually to replicate the logic.
if/then/else truncatedA generated conditional rule exceeded the 450-character expression limit and was truncated.Open Business Rules, find the affected rule, and shorten or rewrite it.
Fixing warnings before going live

After importing, click Edit Schema to review all properties, then expand Business Rules to check any auto-generated rules. Don't activate the gate until all warnings are resolved.

Limits

  • $ref references are resolved recursively; circular references are safely treated as plain object.
  • Maximum nesting depth: 15 levels.
  • Maximum business rules per gate: 20. If the import would push you over this limit, remove some existing rules first or reduce the rules in the imported schema.

Business Rules

Business rules are cross-field expressions that enforce domain logic beyond simple type checking.

Rule Structure

{
"businessRules": [
{
"id": "rule_date_order",
"name": "End date after start date",
"expression": "endDate > startDate",
"errorMessage": "End date must be after start date",
"enabled": true
},
{
"id": "rule_total_check",
"name": "Line items match total",
"expression": "quantity * unitPrice == totalAmount",
"errorMessage": "Total amount does not match quantity * unit price",
"enabled": true
}
]
}

Expression Syntax

Expressions have access to all payload fields as variables. Supported operations:

CategoryExamples
Comparison>, <, >=, <=, ==, !=
Logical&&, ||, !
Arithmetic+, -, *, /, %
Math functionsround(), max(), min(), abs(), pow()
String accessField values are available directly by name

A rule passes when its expression evaluates to a truthy value. All enabled rules are evaluated independently (no short-circuit) — you'll see all failures at once.

Limits

  • Maximum 20 business rules per gate
  • Expression maximum length: 500 characters
  • Expressions are security-validated at save time (no eval, require, or prototype access)

Validation Modes

Variables Mode (default)

Validates a JSON object against the schema. This is the standard mode for structured payloads.

Freetext Mode

Validates unstructured text content (articles, reports, code snippets). Configure with:

{
"validationMode": "freetext",
"freetextConfig": {
"contentFormat": "markdown",
"max_content_length": 50000
}
}
Content FormatDescription
plaintextPlain text
markdownMarkdown formatted
htmlHTML content
codeSource code (set codeLanguage for syntax context)

In freetext mode, business rules are not evaluated.


Gate Configuration

Approval

Enable human review before delivery:

{
"approvalMode": "manual",
"approvalConfig": {
"approvers": [
{ "type": "internal", "email": "reviewer@company.com" },
{ "type": "external", "email": "client@partner.com" }
],
"timeout_hours": 48
}
}
  • auto (default) — runs proceed directly after validation
  • manual — runs wait for an approver to approve or reject

See Approvals for details on the review workflow.

Delivery

Forward validated (and approved) payloads to external systems:

{
"deliveryChannels": [
{
"type": "webhook",
"config": {
"url": "https://api.yourapp.com/webhook",
"headers": { "X-Custom-Header": "value" }
}
}
]
}

Webhook deliveries include an HMAC-SHA256 signature in the X-Rynko-Signature header for verification. Failed deliveries are retried up to 3 times with exponential backoff.

Rendering

Optionally render a document from the validated payload:

{
"renderMode": "rynko",
"renderTemplateId": "invoice-template",
"renderConfig": { "format": "pdf" }
}
Render ModeDescription
none (default)No rendering — validation only
rynkoRender a Rynko document template using the payload as variables
custom_apiForward to a custom rendering API

Rate Limiting

Throttle submissions per gate:

{
"maxSubmissionsPerMinute": 60
}

When the limit is exceeded, the API returns HTTP 429 with a retryAfter value in seconds.

Circuit Breaker

Automatically pause a gate when failures spike:

{
"circuitBreakerEnabled": true,
"maxFailures": 5,
"cooldownSeconds": 300
}

After maxFailures consecutive failures, the circuit opens and rejects new submissions for cooldownSeconds. This prevents cascading failures.

Notifications

Control how you're notified about gate activity:

{
"notificationMode": "digest",
"notificationDigestMinutes": 5
}
ModeBehavior
immediateNotify on every event
digest (default)Batch notifications every N minutes

Gate Status

StatusDescription
activeAccepting submissions (default)
pausedRejecting new submissions
archivedSoft-deleted, not visible in listings

Update a gate's status:

curl -X PUT https://api.rynko.dev/api/flow/gates/GATE_ID \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "status": "paused" }'

Schema Versioning

Every schema update creates a new version. Each run records the schema version it was validated against. List versions:

curl https://api.rynko.dev/api/flow/gates/GATE_ID/versions \
-H "Authorization: Bearer YOUR_API_KEY"

This lets you track how your validation requirements have evolved and correlate runs with the schema version they used.