> For the complete documentation index, see [llms.txt](https://docs.ebbot.ai/ebbot-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ebbot.ai/ebbot-docs/developer-resources/ebbot-automations/integrations-sdk/json-schema-flow-builder-expectations.md).

# JSON Schema - Flow builder expectations

***

### Quick summary

* The editor supports a focused subset of JSON Schema: primitives, objects, arrays, and local `$defs` references.
* Supported primitive types: `string`, `number`, `integer`, `boolean`.
* Structured types: `object` (with `properties`), `array` (with `items`).
* Local definitions with `$defs` and `$ref` (format: `#/$defs/<Key>`) are supported.
* Avoid advanced or ambiguous JSON Schema constructs such as `oneOf` / `anyOf` / `allOf` and remote `$ref` URLs if you want consistent UI behaviour.

***

### Supported schema constructs

The editor expects schema values to look like one of the following:

* Primitive types:
  * `type: "string"` — optional `enum` for select lists; optional `format` (used for sample/default values such as `uuid`, `email`, `uri`)
  * `type: "number"`
  * `type: "integer"`
  * `type: "boolean"`
* Object:
  * `type: "object"`
  * `properties: { <name>: Schema }`
  * optional `required: string[]`
  * optional `title` and `description` for labels and help text
* Array:
  * `type: "array"`
  * `items: Schema` (a single schema that describes array items)
  * optional `minItems` and `maxItems`
* Local references:
  * `$defs` at the root and `$ref` that reference them, in the form `#/$defs/<Key>`
* Fallback:
  * `type: "unknown"` — used internally when a schema cannot be resolved

Notes:

* Complex features such as `oneOf`, `anyOf`, `allOf`, `patternProperties`, and other advanced constraints are not interpreted for UI generation and path picking. Keep schemas simple and explicit for the best editor experience.
* Arrays are treated as homogeneous item lists (single `items` schema). Tuple-style arrays are not reliably supported.

***

### How schemas are used by the frontend

1. Schema-driven forms
   * Object `properties` map to form fields and editors.
   * `required` marks fields as required in the UI and prevents their removal from form instances.
   * `enum` on strings becomes a dropdown of allowed values.
2. Path and field selection
   * The UI traverses `object.properties` and `array.items` to build selectable paths (for example: `$.nodeResults["<id>"].payload.someField`).
   * `$ref` references that resolve to local `$defs` are expanded so nested fields are presented to users for selection.
3. Validation
   * Action parameters and other per-node inputs are validated using a standard JSON Schema validator against the declared schema.
   * For dynamic features (like structured output configuration), the editor validates that the supplied JSON Schema is syntactically valid.
4. Sample/default values
   * For previews and sample generation, the editor uses simple mappings:
     * `string` → `"string"` (or a format-based sample for `uuid`, `email`, `uri`)
     * `number` / `integer` → `1`
     * `boolean` → `true`
     * `array` → `[ sampleItem ]`
     * `object` → `{ ...sampleProperties }`

***

### Recommended schema shapes

Below are minimal example fragments showing recommended shapes. Use these as templates to author schemas that the editor will understand.

Example: simple object

```json
{
  "type": "object",
  "title": "Person",
  "properties": {
    "id": { "type": "string", "format": "uuid" },
    "name": { "type": "string" },
    "age": { "type": "integer" },
    "tags": { "type": "array", "items": { "type": "string" } }
  },
  "required": ["id", "name"]
}
```

Example: local `$defs` + `$ref`

```json
{
  "$defs": {
    "Address": {
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" }
      },
      "required": ["street", "city"]
    }
  },
  "type": "object",
  "properties": {
    "billingAddress": { "$ref": "#/$defs/Address" },
    "shippingAddress": { "$ref": "#/$defs/Address" }
  }
}
```

Example: enum for select inputs

```json
{
  "type": "string",
  "enum": ["pending", "processing", "complete"]
}
```

***

### Action schema pattern

When describing an action that appears in the editor (for example, a callable backend function), provide a description of call parameters using an object schema. The UI will render inputs for each property and will validate values against that schema.

Recommended minimal action parameters shape:

```json
{
  "type": "object",
  "properties": {
    "userId": { "type": "string", "format": "uuid" },
    "includeHistory": { "type": "boolean" }
  },
  "required": ["userId"]
}
```

* Keep parameters explicit and avoid ambiguous constructs.
* Use `required` for mandatory parameters.
* Use `enum` to specify limited string options.

***

### Trigger schema pattern

For triggers (events that supply a payload to flows), provide a top-level schema that includes a `payload` property describing the event payload. This enables downstream nodes to pick paths into the trigger payload.

Minimal trigger schema example:

```json
{
  "type": "object",
  "properties": {
    "id": { "type": "string" },
    "name": { "type": "string" },
    "connectionId": { "type": "string" },
    "subscriptionId": { "type": "string" },
    "payload": {
      "type": "object",
      "properties": {
        "orderId": { "type": "string" },
        "total": { "type": "number" }
      },
      "required": ["orderId"]
    }
  },
  "required": ["id", "name", "connectionId", "payload"]
}
```

If the `payload` schema is missing or loosely defined, the editor will not be able to provide helpful path options for selecting payload fields.

***

### LLM structured output schemas

Some editors support attaching a JSON Schema describing a language model's structured output. For best results:

* Ensure the structured output schema is a valid JSON Schema document.
* Keep the schema within the supported subset if you want path pickers and type-aware helpers to work.
* The editor performs a schema-level validity check, but only the supported constructs will be used for UI interactions.

#### Structured output example

This JSON schema defines the structured output for an AI support response, containing the generated email text and a boolean flag indicating if the response was grounded in the uploaded customer knowledge base.

```json
{
  "title": "EmailResponseSchema",
  "type": "object",
  "properties": {
    "email_response": {
      "type": "string",
      "description": "The generated text body of the email response."
    },
    "relevant_sources": {
      "type": "boolean",
      "description": "Indicates whether any relevant sources were found or used to generate the response."
    }
  },
  "required": [
    "email_response",
    "relevant_sources"
  ],
  "additionalProperties": false
}
```

Below is an example of the output generated by the schema. The `email_response` contains the AI-generated reply, while `relevant_sources` indicates whether the response was informed by the uploaded knowledge base.

```json
{
  "email_response": "Hi John, thanks for reaching out. Here is the info you requested...",
  "relevant_sources": true
}
```

***

### Manifest example

Below is a small, self-contained manifest example that demonstrates common patterns: an action with parameters and a result using `$defs`, and a trigger with subscription configuration and a payload schema. This example is intentionally compact while showing the local `$defs` usage, an action `parameters` object, and a trigger `payload` object.

```json
{
  "name": "example-integration",
  "version": "1.0.0",
  "actions": [
    {
      "type": "action",
      "name": "get_user",
      "displayName": "Get User",
      "description": "Fetch a user by id",
      "schema": {
        "call": {
          "type": "function",
          "function": {
            "name": "getUser",
            "description": "Fetch user by ID",
            "parameters": {
              "type": "object",
              "properties": {
                "userId": { "type": "string", "format": "uuid" },
                "includeHistory": { "type": "boolean" }
              },
              "required": ["userId"]
            }
          }
        },
        "result": {
          "type": "object",
          "$defs": {
            "User": {
              "type": "object",
              "properties": {
                "id": { "type": "string", "format": "uuid" },
                "email": { "type": "string", "format": "email" },
                "name": { "type": "string" }
              },
              "required": ["id", "email"]
            }
          },
          "properties": {
            "user": { "$ref": "#/$defs/User" }
          }
        }
      }
    }
  ],
  "triggers": [
    {
      "type": "trigger",
      "name": "order_created",
      "description": "Fires when an order is created",
      "subscriptionSchema": {
        "type": "object",
        "properties": {
          "callback": {
            "type": "object",
            "properties": {
              "url": { "type": "string" },
              "method": { "type": "string" }
            },
            "required": ["url", "method"]
          },
          "data": {
            "type": "object",
            "properties": {
              "storeId": { "type": "string" }
            },
            "required": ["storeId"]
          }
        },
        "required": ["callback", "data"]
      },
      "schema": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "connectionId": { "type": "string" },
          "subscriptionId": { "type": "string" },
          "payload": {
            "type": "object",
            "properties": {
              "orderId": { "type": "string" },
              "amount": { "type": "number" },
              "currency": { "type": "string" },
              "customer": {
                "type": "object",
                "properties": {
                  "id": { "type": "string" },
                  "email": { "type": "string", "format": "email" },
                  "name": { "type": "string" }
                },
                "required": ["id"]
              }
            },
            "required": ["orderId", "amount"]
          }
        },
        "required": ["id", "name", "connectionId", "payload"]
      }
    }
  ],
  "connection": {
    "type": "object",
    "properties": {
      "data": {
        "type": "object",
        "properties": {
          "endpoint": { "type": "string", "format": "uri" },
          "apiKey": { "type": "string" }
        },
        "required": ["endpoint", "apiKey"]
      }
    },
    "required": ["data"]
  }
}
```

This manifest shows:

* An action (`getUser`) whose call parameters are an object with a required `userId`.
* The action's `result` contains a local `$defs` entry `User`, referenced in `properties.user`.
* A trigger (`order_created`) with both a `subscriptionSchema` (for installing/configuring the trigger) and a `schema` containing a detailed `payload` object.

Use this example as a base and add other fields and definitions as needed while staying within the documented supported subset.

***

### Practical authoring checklist

Before publishing an integration manifest or schema, confirm:

* [ ] Use only the supported constructs: `object`, `array`, `string`, `number`, `integer`, `boolean`.
* [ ] Define `properties` for objects and `items` for arrays.
* [ ] Add `required` for properties that must be present.
* [ ] Use local `$defs` and `$ref` of the form `#/$defs/<Key>` for reusable definitions.
* [ ] For actions, provide an explicit object schema describing call parameters.
* [ ] For triggers, include a descriptive `payload` schema so downstream path selection works.
* [ ] Ensure any JSON Schema you supply is syntactically valid.

***

### Common pitfalls

* Avoid `oneOf` / `anyOf` / `allOf` for fields intended to be used in the editor UI — they introduce ambiguity for path selection and form rendering.
* Avoid remote/external `$ref` URLs if you want the editor to resolve nested structures in the browser; prefer local `$defs`.
* Do not rely on pattern-based property names (e.g., `patternProperties`) for form generation — the editor expects concrete property names.
* Tuple-style `items` arrays are not guaranteed to be handled correctly; prefer a single `items` schema describing homogeneous array elements.
