Skip to content

JSON Schema and Parsing

Orvanta leverages JSON Schema to define the structure and validation rules for JSON data, adhering to the JSON Schema standard (version 2020-12).

A JSON Schema defines properties, types, and constraints of a JSON object through these components:

  • $schema: URL pointing to the JSON Schema specification
  • type: The JSON object type (object, string, number, etc.)
  • properties: Dictionary defining object properties with descriptions and types
  • required: List of mandatory properties
  • Additional features for validation (regex patterns, custom formats)

Orvanta uses JSON Schema to define input specifications for scripts and flows, and to specify connection types. The schema must have properties matching declared function arguments, with support for types including: integer, number, string, boolean, object, array, and any.

Each parameter in a script’s main function corresponds to a field in the JSON Schema. Type mappings exist between languages and JSON Schema:

Python to JSON Schema:

  • str → string
  • float → number
  • int → integer
  • bool → boolean
  • dict → object
  • list → any[]
  • List[str] → string[]
  • bytes → string with encodingFormat: base64
  • datetime → string with format: date-time

TypeScript to JSON Schema:

  • string → string
  • object → object
  • boolean → boolean
  • number → number
  • string[] → string[]

TypeScript supports special Orvanta-specific types:

  • orvanta.Base64 → string with encodingFormat: base64
  • orvanta.Email → string with format: email
  • orvanta.Sql → string with format: sql
  • <ResourceType> → object with format: resource-{resource_type}

Flow input parameters are defined through a JSON Schema where each “Flow Input” argument corresponds to a JSON Schema field. The schema can be modified in the Flow Input menu and viewed in the Export/OpenFlow section.

Connection types associate with JSON Schemas to validate connection object properties against specified type constraints.

Main function arguments support advanced settings affecting auto-generated UI and JSON Schema:

Common Settings:

  • Name
  • Type
  • Description
  • Custom Title
  • Placeholder
  • Field settings (type-dependent)

Type-Specific Configurations:

TypeAdvanced Configuration
IntegerMin/Max, Currency, Currency locale
NumberMin/Max, Currency, Currency locale
StringTextarea rows, variable picker toggle, password flag, file (base64), enum, format (email, hostname, uri, uuid, ipv4, yaml, sql, date-time), regex pattern
BooleanNone
ConnectionConnection type specification
ObjectObject properties or template path to JSON schema resource
ArrayItem type specification (strings, enum strings, objects, numbers, bytes)
AnyNone

In the argument’s advanced settings, Show this field only when conditions are met takes an expression that decides whether the field appears in the input form. It is stored as showExpr in the schema.

The expression sees one variable, fields: an object holding the current values of the form’s other fields. Evaluating it never changes anything. It has no side effects, and it is not general JavaScript: it is read by a restricted parser that supports only the subset below.

PartSupported
Field accessfields.x, fields?.x, fields["x"], array indexes such as fields.tags[0], and length on strings and arrays. Only a value’s own data properties are read.
Literalsstrings, numbers, true, false, null, undefined, NaN, Infinity, and arrays such as ["a", "b"]
Unary operators!, -, +, typeof
Binary operators==, !=, ===, !==, <, >, <=, >=, +, -, *, /, %, &&, ||, ??
Conditionalcondition ? a : b
Method callsOn strings: includes, startsWith, endsWith, indexOf, toLowerCase, toUpperCase, trim. On arrays: includes, indexOf.

A leading return, a trailing ;, and // or /* */ comments are accepted and ignored.

// show when "mode" is "advanced"
fields.mode == "advanced"
// show when at least one of two checkboxes is ticked
fields.email_alerts || fields.sms_alerts
// show when "country" is one of a list
["NL", "BE", "DE"].includes(fields.country)
// show when a string field starts with a prefix, ignoring case
(fields.name ?? "").toLowerCase().startsWith("acme")
// show when the list has more than two items
fields.items.length > 2

Anything outside the subset (another variable, a function call that is not in the table, assignment, template literals, arrow functions, new) cannot be evaluated. So can an expression that fails at runtime, for example reading a property of an unset field with fields.a.b when a is empty. In both cases the field is shown: the condition fails open, so a mistake in the expression never hides an input the user needs. Use fields?.a?.b to read a nested value that may be unset. A method call on an unset field also fails this way (fields.name.trim() when name is empty), so guard it first, as in (fields.name ?? "").trim().

The oneOf type enables users to select between multiple object variants through auto-generated UI. TypeScript syntax:

example_oneof: { label: "Option 1", attribute: string } | { label: "Option 2", other_attribute: string }

The selected object is returned as the result. This works in scripts, flows, webhooks, and CLI operations.

Dynamic select creates select fields with options that recompute based on other input values.

Export both a type as DynSelect_<name> and a function as <name>:

export type DynSelect_foo = string;
export async function foo(x: string, y: number, text: string) {
if (text === '42') {
return [{ value: '42', label: 'The answer to the universe' }];
}
return [{ value: '1', label: 'Foo' + x + y }];
}
export async function main(y: number, x: string, xy: DynSelect_foo) {
return xy;
}

Python equivalent:

DynSelect_foo = str
def foo(x: str, y: int, text):
if text == "42":
return [{"value": "42", "label": "The answer to the universe"}]
return [{"value": '1', "label": 'Foo' + x + str(y)}]
def main(x: str, y: int, xy: DynSelect_foo):
return xy

Define one function per flow input field with dynamic select type. Function names must match the field names exactly. No export type is required.

Select options recompute dynamically based on other input arguments. Custom filtering and sorting logic can be implemented within the function.

By default, Orvanta does not explicitly validate schemas. To enforce validation (useful for webhooks), add the schema_validation annotation as a comment at the script’s top:

// schema_validation
export async function main(
a: number,
b: 'my' | 'enum',
e = 'inferred type string from default arg',
f = { nested: 'object' },
g:
| { label: 'Variant 1'; foo: string; }
| { label: 'Variant 2'; bar: number; }
) {
return { foo: a };
}

Jobs fail if payloads don’t match the schema. Validation checks type, shape, required fields, and strict enums. Regex pattern matching on strings is not yet supported. This feature is available across all languages.