{
  "$id": "https://wg-serverless.org/serverless-workflow-schema-v01.json",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "description": "Serverless Workflow is a vendor-neutral specification for defining the model of workflows responsible for orchestrating event-driven serverless applications",
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "Workflow unique identifier",
      "minLength": 1
    },
    "name": {
      "type": "string",
      "description": "Workflow name",
      "minLength": 1
    },
    "description": {
      "type": "string",
      "description": "Workflow description"
    },
    "version": {
      "type": "string",
      "description": "Workflow version",
      "minLength": 1
    },
    "schemaVersion": {
      "type": "string",
      "description": "Serverless Workflow schema version",
      "minLength": 1
    },
    "expressionLanguage": {
      "type": "string",
      "description": "Default expression language to be used throughout the workflow definition",
      "minLength": 1
    },
    "dataInputSchema": {
      "type": "string",
      "format": "uri",
      "description": "URI to JSON Schema that workflow data input adheres to"
    },
    "dataOutputSchema": {
      "type": "string",
      "format": "uri",
      "description": "URI to JSON Schema that workflow data output adheres to"
    },
    "metadata": {
      "$ref": "#/definitions/metadata"
    },
    "events": {
      "type": "array",
      "description": "Workflow event definitions. Defines events that can be consumed or produced",
      "items": {
        "type": "object",
        "$ref": "#/definitions/eventdef"
      }
    },
    "functions": {
      "type": "array",
      "description": "Workflow function definitions",
      "items": {
        "type": "object",
        "$ref": "#/definitions/function"
      }
    },
    "states": {
      "type": "array",
      "description": "State definitions",
      "items": {
        "anyOf": [
          {
            "title": "Delay State",
            "$ref": "#/definitions/delaystate"
          },
          {
            "title": "Event State",
            "$ref": "#/definitions/eventstate"
          },
          {
            "title": "Operation State",
            "$ref": "#/definitions/operationstate"
          },
          {
            "title": "Parallel State",
            "$ref": "#/definitions/parallelstate"
          },
          {
            "title": "Switch State",
            "$ref": "#/definitions/switchstate"
          },
          {
            "title": "SubFlow State",
            "$ref": "#/definitions/subflowstate"
          },
          {
            "title": "Relay State",
            "$ref": "#/definitions/relaystate"
          },
          {
            "title": "ForEach State",
            "$ref": "#/definitions/foreachstate"
          },
          {
            "title": "Callback State",
            "$ref": "#/definitions/callbackstate"
          }
        ]
      }
    },
    "extensions": {
      "type": "array",
      "description": "Workflow extensions",
      "items": {
        "type": "object"
      }
    }
  },
  "required": [
    "id",
    "name",
    "version",
    "states"
  ],
  "definitions": {
    "metadata": {
      "type": "object",
      "description": "Metadata information"
    },
    "transition": {
      "type": "object",
      "properties": {
        "expression": {
          "description": "Expression evaluated against state's data output. Must evaluate to true for the transition to be valid",
          "$ref": "#/definitions/expression"
        },
        "nextState": {
          "type": "string",
          "description": "Name of state to transition to",
          "minLength": 1
        }
      },
      "required": [
        "nextState"
      ]
    },
    "error": {
      "type": "object",
      "properties": {
        "expression": {
          "description": "Expression that matches against the error in the state data input",
          "$ref": "#/definitions/expression"
        },
        "errorDataFilter": {
          "$ref": "#/definitions/errordatafilter"
        },
        "transition": {
          "description": "Next transition of the workflow when expression is matched",
          "$ref": "#/definitions/transition"
        }
      },
      "required": [
        "expression",
        "transition"
      ]
    },
    "eventdef": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "Unique event name",
          "minLength": 1
        },
        "source": {
          "type": "string",
          "description": "CloudEvent source"
        },
        "type": {
          "type": "string",
          "description": "CloudEvent type"
        },
        "correlationToken": {
          "type": "string",
          "description": "Context attribute name of the CloudEvent which value is to be used for event correlation"
        },
        "metadata": {
          "$ref": "#/definitions/metadata",
          "description": "Metadata information"
        }
      },
      "required": [
        "name",
        "source",
        "type"
      ]
    },
    "eventactions": {
      "type": "object",
      "properties": {
        "eventRefs": {
          "type" : "array",
          "description": "References one or more unique event names in the defined workflow events"
        },
        "actionMode": {
          "type": "string",
          "enum": [
            "SEQUENTIAL",
            "PARALLEL"
          ],
          "description": "Specifies how actions are to be performed (in sequence of parallel)",
          "default": "SEQUENTIAL"
        },
        "actions": {
          "type": "array",
          "description": "Actions to be performed if expression matches",
          "items": {
            "type": "object",
            "$ref": "#/definitions/action"
          }
        },
        "eventDataFilter": {
          "$ref": "#/definitions/eventdatafilter"
        }
      },
      "required": [
        "eventRefs",
        "actions"
      ]
    },
    "action": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "Unique action definition name"
        },
        "functionRef": {
          "description": "References a reusable function definition",
          "$ref": "#/definitions/functionref"
        },
        "actionDataFilter": {
          "$ref": "#/definitions/actiondatafilter"
        }
      },
      "required": [
        "functionRef"
      ]
    },
    "retry": {
      "type": "object",
      "description": "Retry Definition",
      "properties": {
        "expression": {
          "description": "Expression that matches against state data output",
          "$ref": "#/definitions/expression"
        },
        "interval": {
          "type": "string",
          "description": "Interval value for retry (ISO 8601 repeatable format)"
        },
        "multiplier": {
          "type": "string",
          "description": "Multiplier value by which interval increases during each attempt (ISO 8601 time format)"
        },
        "maxAttempts": {
          "type": "integer",
          "default": 1,
          "minimum": 0,
          "description": "Maximum number of retry attempts (1 by default). Value of 0 means no retries are performed"
        }
      },
      "required": [
        "expression"
      ]
    },
    "function": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "Unique function name",
          "minLength": 1
        },
        "resource": {
          "type": "string",
          "description": "Function resource (URI)"
        },
        "type": {
          "type": "string",
          "description": "Function type"
        },
        "metadata": {
          "$ref": "#/definitions/metadata"
        }
      },
      "required": [
        "name",
        "resource"
      ]
    },
    "functionref": {
      "type": "object",
      "description": "Function Reference",
      "properties": {
        "refName": {
          "type": "string",
          "description": "Name of the referenced function"
        },
        "parameters": {
          "type": "object",
          "description": "Function parameters"
        }
      },
      "required": [
        "refName"
      ]
    },
    "branch": {
      "type": "object",
      "description": "Branch Definition",
      "properties": {
        "name": {
          "type": "string",
          "description": "Branch name"
        },
        "states": {
          "type": "array",
          "description": "State Definitions",
          "items": {
            "anyOf": [
              {
                "title": "Delay State",
                "$ref": "#/definitions/delaystate"
              },
              {
                "title": "Event State",
                "$ref": "#/definitions/eventstate"
              },
              {
                "title": "Operation State",
                "$ref": "#/definitions/operationstate"
              },
              {
                "title": "Switch State",
                "$ref": "#/definitions/switchstate"
              },
              {
                "title": "SubFlow State",
                "$ref": "#/definitions/subflowstate"
              },
              {
                "title": "Relay State",
                "$ref": "#/definitions/relaystate"
              },
              {
                "title": "ForEach State",
                "$ref": "#/definitions/foreachstate"
              },
              {
                "title": "Callback State",
                "$ref": "#/definitions/callbackstate"
              }
            ]
          }
        },
        "waitForCompletion": {
          "type": "boolean",
          "default": false,
          "description": "Flow must wait for this branch to finish before continuing"
        }
      },
      "required": [
        "name",
        "states"
      ]
    },
    "delaystate": {
      "type": "object",
      "description": "Causes the workflow execution to delay for a specified duration",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique State id",
          "minLength": 1
        },
        "name": {
          "type": "string",
          "description": "State name"
        },
        "type": {
          "type": "string",
          "enum": [
            "DELAY"
          ],
          "description": "State type"
        },
        "start": {
          "$ref": "#/definitions/start",
          "description": "State start definition"
        },
        "end": {
          "$ref": "#/definitions/end",
          "description": "State end definition"
        },
        "stateDataFilter": {
          "$ref": "#/definitions/statedatafilter"
        },
        "timeDelay": {
          "type": "string",
          "description": "Amount of time (ISO 8601 format) to delay"
        },
        "onError": {
          "type": "array",
          "description": "OnError Definition",
          "items": {
            "type": "object",
            "$ref": "#/definitions/error"
          }
        },
        "transition": {
          "description": "Next transition of the workflow after the time delay",
          "$ref": "#/definitions/transition"
        },
        "dataInputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data input adheres to"
        },
        "dataOutputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data output adheres to"
        },
        "metadata": {
          "$ref": "#/definitions/metadata"
        }
      },
      "oneOf": [
        {
          "required": [
            "name",
            "type",
            "timeDelay",
            "end"
          ]
        },
        {
          "required": [
            "name",
            "type",
            "timeDelay",
            "transition"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "timeDelay",
            "transition"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "timeDelay",
            "end"
          ]
        }
      ]
    },
    "eventstate": {
      "type": "object",
      "description": "This state is used to wait for events from event sources, then consumes them and invoke one or more actions to run in sequence or parallel",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique State id",
          "minLength": 1
        },
        "name": {
          "type": "string",
          "description": "State name"
        },
        "type": {
          "type": "string",
          "enum": [
            "EVENT"
          ],
          "description": "State type"
        },
        "exclusive": {
          "type": "boolean",
          "default": true,
          "description": "If true consuming one of the defined events causes its associated actions to be performed. If false all of the defined events must be consumed in order for actions to be performed"
        },
        "eventsActions": {
          "type": "array",
          "description": "Define what events trigger one or more actions to be performed",
          "items": {
            "type": "object",
            "$ref": "#/definitions/eventactions"
          }
        },
        "timeout": {
          "type": "string",
          "description": "Time period to wait for incoming events (ISO 8601 format)"
        },
        "stateDataFilter": {
          "$ref": "#/definitions/statedatafilter"
        },
        "retry": {
          "type": "array",
          "description": "Retry Definition",
          "items": {
            "type": "object",
            "$ref": "#/definitions/retry"
          }
        },
        "onError": {
          "type": "array",
          "description": "States error handling definitions",
          "items": {
            "type": "object",
            "$ref": "#/definitions/error"
          }
        },
        "dataInputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data input adheres to"
        },
        "dataOutputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data output adheres to"
        },
        "transition": {
          "description": "Next transition of the workflow after all the actions have been performed",
          "$ref": "#/definitions/transition"
        },
        "start": {
          "$ref": "#/definitions/start",
          "description": "State start definition"
        },
        "end": {
          "$ref": "#/definitions/end",
          "description": "State end definition"
        },
        "metadata": {
          "$ref": "#/definitions/metadata"
        }
      },
      "oneOf": [
        {
          "required": [
            "name",
            "type",
            "eventsActions",
            "end"
          ]
        },
        {
          "required": [
            "name",
            "type",
            "eventsActions",
            "transition"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "eventsActions",
            "transition"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "eventsActions",
            "end"
          ]
        }
      ]
    },
    "operationstate": {
      "type": "object",
      "description": "Defines actions be performed. Does not wait for incoming events",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique State id",
          "minLength": 1
        },
        "name": {
          "type": "string",
          "description": "State name"
        },
        "type": {
          "type": "string",
          "enum": [
            "OPERATION"
          ],
          "description": "State type"
        },
        "start": {
          "$ref": "#/definitions/start",
          "description": "State start definition"
        },
        "end": {
          "$ref": "#/definitions/end",
          "description": "State end definition"
        },
        "stateDataFilter": {
          "$ref": "#/definitions/statedatafilter"
        },
        "actionMode": {
          "type": "string",
          "enum": [
            "SEQUENTIAL",
            "PARALLEL"
          ],
          "description": "Specifies whether actions are performed in sequence or in parallel",
          "default": "SEQUENTIAL"
        },
        "actions": {
          "type": "array",
          "description": "Actions to be performed",
          "items": {
            "type": "object",
            "$ref": "#/definitions/action"
          }
        },
        "retry": {
          "type": "array",
          "description": "Retry Definition",
          "items": {
            "type": "object",
            "$ref": "#/definitions/retry"
          }
        },
        "onError": {
          "type": "array",
          "description": "States error handling definitions",
          "items": {
            "type": "object",
            "$ref": "#/definitions/error"
          }
        },
        "transition": {
          "description": "Next transition of the workflow after all the actions have been performed",
          "$ref": "#/definitions/transition"
        },
        "dataInputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data input adheres to"
        },
        "dataOutputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data output adheres to"
        },
        "metadata": {
          "$ref": "#/definitions/metadata"
        }
      },
      "oneOf": [
        {
          "required": [
            "name",
            "type",
            "actionMode",
            "actions",
            "end"
          ]
        },
        {
          "required": [
            "name",
            "type",
            "actionMode",
            "actions",
            "transition"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "actionMode",
            "actions",
            "transition"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "actionMode",
            "actions",
            "end"
          ]
        }
      ]
    },
    "parallelstate": {
      "type": "object",
      "description": "Consists of a number of states that are executed in parallel",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique State id",
          "minLength": 1
        },
        "name": {
          "type": "string",
          "description": "State name"
        },
        "type": {
          "type": "string",
          "enum": [
            "PARALLEL"
          ],
          "description": "State type"
        },
        "start": {
          "$ref": "#/definitions/start",
          "description": "State start definition"
        },
        "end": {
          "$ref": "#/definitions/end",
          "description": "State end definition"
        },
        "stateDataFilter": {
          "$ref": "#/definitions/statedatafilter"
        },
        "branches": {
          "type": "array",
          "description": "Branch Definitions",
          "items": {
            "type": "object",
            "$ref": "#/definitions/branch"
          }
        },
        "retry": {
          "type": "array",
          "description": "Retry Definition",
          "items": {
            "type": "object",
            "$ref": "#/definitions/retry"
          }
        },
        "onError": {
          "type": "array",
          "description": "States error handling definitions",
          "items": {
            "type": "object",
            "$ref": "#/definitions/error"
          }
        },
        "transition": {
          "description": "Next transition of the workflow after all branches have completed execution",
          "$ref": "#/definitions/transition"
        },
        "dataInputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data input adheres to"
        },
        "dataOutputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data output adheres to"
        },
        "metadata": {
          "$ref": "#/definitions/metadata"
        }
      },
      "oneOf": [
        {
          "required": [
            "name",
            "type",
            "branches",
            "end"
          ]
        },
        {
          "required": [
            "name",
            "type",
            "branches",
            "transition"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "branches",
            "transition"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "branches",
            "transition",
            "end"
          ]
        }
      ]
    },
    "switchstate": {
      "type": "object",
      "description": "Permits transitions to other states based on criteria matching",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique State id",
          "minLength": 1
        },
        "name": {
          "type": "string",
          "description": "State name"
        },
        "type": {
          "type": "string",
          "enum": [
            "SWITCH"
          ],
          "description": "State type"
        },
        "start": {
          "$ref": "#/definitions/start",
          "description": "State start definition"
        },
        "stateDataFilter": {
          "$ref": "#/definitions/statedatafilter"
        },
        "choices": {
          "type": "array",
          "description": "Defines matching rules evaluated against state data",
          "items": {
            "anyOf": [
              {
                "title": "Single Choice",
                "$ref": "#/definitions/singlechoice"
              },
              {
                "title": "And Choice",
                "$ref": "#/definitions/andchoice"
              },
              {
                "title": "Not Choice",
                "$ref": "#/definitions/notchoice"
              },
              {
                "title": "Or Choice",
                "$ref": "#/definitions/orchoice"
              }
            ]
          }
        },
        "onError": {
          "type": "array",
          "description": "States error handling definitions",
          "items": {
            "type": "object",
            "$ref": "#/definitions/error"
          }
        },
        "default": {
          "description": "Next transition of the workflow if there is no match for any choices",
          "$ref": "#/definitions/transition"
        },
        "dataInputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data input adheres to"
        },
        "dataOutputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data output adheres to"
        },
        "metadata": {
          "$ref": "#/definitions/metadata"
        }
      },
      "oneOf": [
        {
          "required": [
            "name",
            "type",
            "choices",
            "default"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "choices",
            "default"
          ]
        }
      ]
    },
    "subflowstate": {
      "type": "object",
      "description": "Defines a sub-workflow to be executed",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique state id",
          "minLength": 1
        },
        "name": {
          "type": "string",
          "description": "State name"
        },
        "type": {
          "type": "string",
          "enum": [
            "SUBFLOW"
          ],
          "description": "State type"
        },
        "start": {
          "$ref": "#/definitions/start",
          "description": "State start definition"
        },
        "end": {
          "$ref": "#/definitions/end",
          "description": "State end definition"
        },
        "waitForCompletion": {
          "type": "boolean",
          "default": false,
          "description": "Workflow execution must wait for sub-workflow to finish before continuing"
        },
        "workflowId": {
          "type": "string",
          "description": "Sub-workflow unique id"
        },
        "stateDataFilter": {
          "$ref": "#/definitions/statedatafilter"
        },
        "onError": {
          "type": "array",
          "description": "States error handling definitions",
          "items": {
            "type": "object",
            "$ref": "#/definitions/error"
          }
        },
        "transition": {
          "description": "Next transition of the workflow after SubFlow has completed execution",
          "$ref": "#/definitions/transition"
        },
        "dataInputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data input adheres to"
        },
        "dataOutputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data output adheres to"
        },
        "metadata": {
          "$ref": "#/definitions/metadata"
        }
      },
      "oneOf": [
        {
          "required": [
            "name",
            "type",
            "workflowId",
            "end"
          ]
        },
        {
          "required": [
            "name",
            "type",
            "workflowId",
            "transition"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "workflowId",
            "transition"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "workflowId",
            "end"
          ]
        }
      ]
    },
    "relaystate": {
      "type": "object",
      "description": "Set up and relay the state's data input to data output. Does not perform any actions",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique state id",
          "minLength": 1
        },
        "name": {
          "type": "string",
          "description": "State name"
        },
        "type": {
          "type": "string",
          "enum": [
            "RELAY"
          ],
          "description": "State type"
        },
        "start": {
          "$ref": "#/definitions/start",
          "description": "State start definition"
        },
        "end": {
          "$ref": "#/definitions/end",
          "description": "State end definition"
        },
        "inject": {
          "type": "object",
          "description": "JSON object which can be set as states data input and can be manipulated via filters"
        },
        "stateDataFilter": {
          "$ref": "#/definitions/statedatafilter"
        },
        "transition": {
          "description": "Next transition of the workflow after subflow has completed",
          "$ref": "#/definitions/transition"
        },
        "dataInputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data input adheres to"
        },
        "dataOutputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data output adheres to"
        },
        "metadata": {
          "$ref": "#/definitions/metadata"
        }
      },
      "oneOf": [
        {
          "required": [
            "name",
            "type",
            "end"
          ]
        },
        {
          "required": [
            "name",
            "type",
            "transition"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "transition"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "end"
          ]
        }
      ]
    },
    "foreachstate": {
      "type": "object",
      "description": "Execute a set of defined states for each element of the data input array",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique State id",
          "minLength": 1
        },
        "name": {
          "type": "string",
          "description": "State name"
        },
        "type": {
          "type": "string",
          "enum": [
            "FOREACH"
          ],
          "description": "State type"
        },
        "start": {
          "$ref": "#/definitions/start",
          "description": "State start definition"
        },
        "end": {
          "$ref": "#/definitions/end",
          "description": "State end definition"
        },
        "inputCollection": {
          "type": "string",
          "description": "JSONPath expression selecting a JSON array element of the states data input"
        },
        "outputCollection": {
          "type": "string",
          "description": "JSONPath expression specifying where in the states data output to place the final data output of each iteration of the executed states"
        },
        "inputParameter": {
          "type": "string",
          "description": "JSONPath expression specifying a JSON object field of the states data input. For each parallel iteration, this field will get populated with a unique element of the inputCollection array"
        },
        "max": {
          "type": "integer",
          "default": "0",
          "minimum": 0,
          "description": "Specifies how upper bound on how many iterations may run in parallel"
        },
        "timeDelay": {
          "type": "string",
          "description": "Amount of time (ISO 8601 format) to wait between each iteration "
        },
        "states": {
          "type": "array",
          "description": "States to be executed for each of the elements of inputCollection",
          "items": {
            "anyOf": [
              {
                "title": "Delay State",
                "$ref": "#/definitions/delaystate"
              },
              {
                "title": "Event State",
                "$ref": "#/definitions/eventstate"
              },
              {
                "title": "Operation State",
                "$ref": "#/definitions/operationstate"
              },
              {
                "title": "Switch State",
                "$ref": "#/definitions/switchstate"
              },
              {
                "title": "SubFlow State",
                "$ref": "#/definitions/subflowstate"
              },
              {
                "title": "Relay State",
                "$ref": "#/definitions/relaystate"
              },
              {
                "title": "ForEach State",
                "$ref": "#/definitions/foreachstate"
              },
              {
                "title": "Callback State",
                "$ref": "#/definitions/callbackstate"
              }
            ]
          }
        },
        "stateDataFilter": {
          "$ref": "#/definitions/statedatafilter"
        },
        "retry": {
          "type": "array",
          "description": "Retry Definition",
          "items": {
            "type": "object",
            "$ref": "#/definitions/retry"
          }
        },
        "onError": {
          "type": "array",
          "description": "States error handling definitions",
          "items": {
            "type": "object",
            "$ref": "#/definitions/error"
          }
        },
        "transition": {
          "description": "Next transition of the workflow after state has completed",
          "$ref": "#/definitions/transition"
        },
        "dataInputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data input adheres to"
        },
        "dataOutputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data output adheres to"
        },
        "metadata": {
          "$ref": "#/definitions/metadata"
        }
      },
      "oneOf": [
        {
          "required": [
            "name",
            "type",
            "inputCollection",
            "inputParameter",
            "states",
            "end"
          ]
        },
        {
          "required": [
            "name",
            "type",
            "inputCollection",
            "inputParameter",
            "states",
            "transition"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "inputCollection",
            "inputParameter",
            "states",
            "end"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "inputCollection",
            "inputParameter",
            "states",
            "transition"
          ]
        }
      ]
    },
    "callbackstate": {
      "type": "object",
      "description": "This state performs an action, then waits for the callback event that denotes completion of the action",
      "properties": {
        "id": {
          "type": "string",
          "description": "Unique state id",
          "minLength": 1
        },
        "name": {
          "type": "string",
          "description": "State name"
        },
        "type": {
          "type" : "string",
          "enum": ["CALLBACK"],
          "description": "State type"
        },
        "action": {
          "description": "Defines the action to be executed",
          "$ref": "#/definitions/action"
        },
        "eventRef": {
          "type" : "string",
          "description": "References an unique callback event name in the defined workflow events"
        },
        "timeout": {
          "type": "string",
          "description": "Time period to wait for incoming events (ISO 8601 format)"
        },
        "eventDataFilter": {
          "description": "Callback event data filter definition",
          "$ref": "#/definitions/eventdatafilter"
        },
        "stateDataFilter": {
          "description": "State data filter definition",
          "$ref": "#/definitions/statedatafilter"
        },
        "retry": {
          "type": "array",
          "description": "States retry definitions",
          "items": {
            "type": "object",
            "$ref": "#/definitions/retry"
          }
        },
        "onError": {
          "type": "array",
          "description": "States error handling definitions",
          "items": {
            "type": "object",
            "$ref": "#/definitions/error"
          }
        },
        "dataInputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data input adheres to"
        },
        "dataOutputSchema": {
          "type": "string",
          "format": "uri",
          "description": "URI to JSON Schema that state data output adheres to"
        },
        "transition": {
          "description": "Next transition of the workflow after all the actions have been performed",
          "$ref": "#/definitions/transition"
        },
        "start": {
          "$ref": "#/definitions/start",
          "description": "State start definition"
        },
        "end": {
          "$ref": "#/definitions/end",
          "description": "State end definition"
        },
        "metadata": {
          "$ref": "#/definitions/metadata"
        }
      },
      "oneOf": [
        {
          "required": [
            "name",
            "type",
            "action",
            "eventRef",
            "timeout",
            "end"
          ]
        },
        {
          "required": [
            "name",
            "type",
            "action",
            "eventRef",
            "timeout",
            "transition"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "action",
            "eventRef",
            "timeout",
            "end"
          ]
        },
        {
          "required": [
            "start",
            "name",
            "type",
            "action",
            "eventRef",
            "timeout",
            "transition"
          ]
        }
      ]
    },
    "defaultchoice": {
      "type": "object",
      "description": "Default Choice",
      "properties": {
        "path": {
          "type": "string",
          "description": "JSONPath that selects an element of state data"
        },
        "value": {
          "type": "string",
          "description": "Matching value"
        },
        "operator": {
          "type": "string",
          "enum": [
            "Exists",
            "Equals",
            "LessThan",
            "LessThanEquals",
            "GreaterThan",
            "GreaterThanEquals"
          ],
          "description": "Specifies how the input data is compared with the values"
        }
      },
      "required": [
        "path",
        "value",
        "operator"
      ]
    },
    "singlechoice": {
      "type": "object",
      "description": "Single Choice",
      "allOf": [
        {
          "$ref": "#/definitions/defaultchoice"
        }
      ],
      "properties": {
        "transition": {
          "description": "Next transition of the workflow if there is a valid match",
          "$ref": "#/definitions/transition"
        }
      },
      "required": [
        "transition"
      ]
    },
    "andchoice": {
      "type": "object",
      "description": "And Choice",
      "properties": {
        "and": {
          "type": "array",
          "description": "List of choices",
          "items": {
            "type": "object",
            "$ref": "#/definitions/defaultchoice"
          }
        },
        "transition": {
          "description": "Next transition of the workflow if there is a valid match",
          "$ref": "#/definitions/transition"
        }
      },
      "required": [
        "and",
        "transition"
      ]
    },
    "orchoice": {
      "type": "object",
      "description": "Or Choice",
      "properties": {
        "or": {
          "type": "array",
          "description": "List of choices",
          "items": {
            "type": "object",
            "$ref": "#/definitions/defaultchoice"
          }
        },
        "transition": {
          "description": "Next transition of the workflow if there is a valid match",
          "$ref": "#/definitions/transition"
        }
      },
      "required": [
        "or",
        "transition"
      ]
    },
    "notchoice": {
      "type": "object",
      "description": "Not Choice",
      "properties": {
        "not": {
          "type": "object",
          "$ref": "#/definitions/defaultchoice",
          "description": "Not Choice"
        },
        "transition": {
          "description": "Next transition of the workflow if there is a valid match",
          "$ref": "#/definitions/transition"
        }
      },
      "required": [
        "not",
        "transition"
      ]
    },
    "expression": {
      "type": "object",
      "description": "Defines the expression language and body of the expression",
      "properties": {
        "language": {
          "type": "string",
          "description": "Expression language. For example 'spel', 'jexl', 'cel', etc"
        },
        "body": {
          "type": "string",
          "description": "The expression body"
        }
      },
      "required": [
        "body"
      ]
    },
    "start": {
      "type": "object",
      "description": "State start definition",
      "properties": {
        "kind": {
          "type": "string",
          "enum": [
            "DEFAULT",
            "SCHEDULED"
          ],
          "description": "Kind of start definition"
        },
        "schedule": {
          "description": "If kind is SCHEDULED, define when the starting state is or becomes active",
          "$ref": "#/definitions/schedule"
        }
      },
      "if": {
        "properties": {
          "kind": {
            "const": "SCHEDULED"
          }
        }
      },
      "then": {
        "required": [
          "kind",
          "schedule"
        ]
      },
      "else": {
        "required": [
          "kind"
        ]
      }
    }, 
    "schedule": {
      "type": "object",
      "description": "Start state schedule definition",
      "properties": {
        "interval": {
          "type": "string",
          "description":  "Time interval describing when the workflow starting state is active"
        }
      },
      "required": [
        "interval"
      ]
    },
    "end": {
      "type": "object",
      "description": "State end definition",
      "properties": {
        "kind": {
          "type": "string",
          "enum": [
            "DEFAULT",
            "TERMINATE",
            "EVENT"
          ],
          "description": "Kind of end definition"
        },
        "produceEvent": {
          "description": "If end kind is EVENT, select one of the defined events by name and set its data",
          "$ref": "#/definitions/produceevent"
        }
      },
      "if": {
        "properties": {
          "kind": {
            "const": "EVENT"
          }
        }
      },
      "then": {
        "required": [
          "kind",
          "produceEvent"
        ]
      },
      "else": {
        "required": [
          "kind"
        ]
      }
    },
    "produceevent": {
      "type": "object",
      "description": "Produce an event and set its data",
      "properties": {
        "nameRef": {
          "type": "string",
          "description": "References a name of a defined event"
        },
        "data": {
          "type": "string",
          "description": "JSONPath expression which selects parts of the states data output to become the data of the produced event"
        }
      },
      "required": [
        "nameRef"
      ]
    },
    "statedatafilter": {
      "type": "object",
      "properties": {
        "dataInputPath": {
          "type": "string",
          "description": "JSONPath definition that selects parts of the states data input"
        },
        "dataOutputPath": {
          "type": "string",
          "description": "JSONPath definition that selects parts of the states data output"
        }
      },
      "required": []
    },
    "eventdatafilter": {
      "type": "object",
      "properties": {
        "dataOutputPath": {
          "type": "string",
          "description": "JSONPath definition that selects parts of the event data, to be merged with the states data"
        }
      },
      "required": []
    },
    "actiondatafilter": {
      "type": "object",
      "properties": {
        "dataInputPath": {
          "type": "string",
          "description": "JSONPath definition that selects parts of the states data input to be the action data"
        },
        "dataResultsPath": {
          "type": "string",
          "description": "JSONPath definition that selects parts of the actions data result, to be merged with the states data"
        }
      },
      "required": []
    },
    "errordatafilter": {
      "type": "object",
      "properties": {
        "dataOutputPath": {
          "type": "string",
          "description": "JSONPath definition that selects parts of the error data, to be merged with the states data"
        }
      },
      "required": []
    }
  }
}