# Arazzo: OpenAPI Workflows
Source: https://speakeasy.com/openapi/arazzo

import { Table } from "@/mdx/components";



The Arazzo Specification is a new addition to the OpenAPI Specification that allows you to define sequences of operations for your API.

An Arazzo description is a separate document that references your OpenAPI document and describes how to combine operations from your OpenAPI document into step-by-step sequences.

Arazzo descriptions are useful for:

- Defining complex sequences of operations that involve multiple API calls.
- Documenting the expected behavior of your API in a more structured way than a narrative description.
- Generating code to execute the sequences of operations.
- Generating tests to verify that the sequences of operations behave as expected.
- Generating documentation that explains how to use the sequences of operations.

## Arazzo Description Structure

An Arazzo description is a JSON or YAML document that follows the structure defined by the Arazzo Specification.

### Arazzo version

| Field Name | Type     | Required |
| ---------- | -------- | -------- |
| `arazzo`   | `string` | ✅       |

The version of the Arazzo Specification that the document uses. The value must be a supported [version number](#arazzo-specification-versions).

```yaml
workflowsSpec: 1.0.0-prerelease
```

### Info metadata

| Field Name | Type                        | Required |
| ---------- | --------------------------- | -------- |
| `info`     | [Info Object](#info-object) | ✅       |

Provides metadata about the Arazzo description.

```yaml
info:
  title: Speakeasy Bar Workflows
  summary: Workflows for managing the Speakeasy Bar API
  description: >
    This document defines workflows for managing the [Speakeasy Bar API](https://bar.example.com), including
    creating new drinks, managing inventory, and processing orders.
  version: 4.6.3
```

### Source description

| Field Name           | Type                                                      | Required |
| -------------------- | --------------------------------------------------------- | -------- |
| `sourceDescriptions` | [[Source Description Object](#source-description-object)] | ✅       |

An array of [source description objects](#source-description-object) defining the OpenAPI or other documents containing the operations referenced by the workflows. The array must contain at least one source.

```yaml
sourceDescriptions:
  - name: speakeasyBar
    url: https://bar.example.com/openapi.yaml
    type: openapi
  - name: printsAndBeeps
    url: https://output.example.com/workflows.yaml
    type: workflowsSpec
```

### Workflows

| Field Name  | Type                                  | Required |
| ----------- | ------------------------------------- | -------- |
| `workflows` | [[Workflow Object](#workflow-object)] | ✅       |

An array of [workflow objects](#workflow-object) defining the workflows. The array must contain at least one workflow.

```yaml
workflows:
  - workflowId: createDrink
    summary: Create a new drink in the bar's menu
    inputs:
      allOf:
        - $ref: "#/components/inputs/authenticate"
        - type: object
          properties:
            drink_name:
              type: string
            drink_type:
              type: string
            drink_price_usd_cent:
              type: integer
            ingredients:
              type: array
              items:
                type: string
    steps:
      - stepId: authenticate
        operationId: authenticate
        parameters:
          - reference: $components.parameters.username
          - reference: $components.parameters.password
      - stepId: createDrink
        operationId: createDrink
        parameters:
          - reference: $components.parameters.authorization
          - name: name
            in: query
            value: $inputs.drink_name
          - name: type
            in: query
            value: $inputs.drink_type
          - name: price
            in: query
            value: $inputs.drink_price_usd_cent
          - name: ingredients
            in: query
            value: $inputs.ingredients
  - workflowId: makeDrink
    summary: Order a drink and check the order status
    inputs:
      - name: orderType
        description: The type of order
        type: string
        required: true
      - name: productCode
        description: The product code of the drink
        type: string
        required: true
      - name: quantity
        description: The quantity of the drink
        type: integer
        required: true
    steps:
      - stepId: orderDrink
        operationId: createOrder
        parameters:
          - name: orderType
            in: body
            value: $inputs.orderType
          - name: productCode
            in: body
            value: $inputs.productCode
          - name: quantity
            in: body
            value: $inputs.quantity
      - stepId: checkStatus
        operationId: getOrder
        parameters:
          - name: orderNumber
            in: path
            value: $orderDrink.orderNumber
        successCriteria:
          - type: simple
            condition: $checkStatus.status == 'completed'
        onSuccess:
          - name: printReceipt
            type: goto
            workflowId: $sourceDescriptions.printsAndBeeps.printReceipt
            criteria:
              - type: simple
                condition: $checkStatus.status == 'completed'
        onFailure:
          - name: beepLoudly
            type: goto
            workflowId: $sourceDescriptions.printsAndBeeps.beepLoudly
            criteria:
              - type: simple
                condition: $checkStatus.status == 'failed'
  - workflowId: addIngredient
    summary: Add a new ingredient to the bar's inventory
    inputs:
      - name: username
        description: The username of the manager
        type: string
        required: true
      - name: password
        description: The password of the manager
        type: string
        required: true
      - name: ingredient_name
        description: The name of the ingredient
        type: string
        required: true
      - name: ingredient_type
        description: The type of the ingredient
        type: string
        required: true
      - name: ingredient_stock
        description: The stock of the ingredient
        type: integer
        required: true
      - name: productCode
        description: The product code of the ingredient
        type: string
        required: true
    steps:
      - stepId: authenticate
        operationId: authenticate
        parameters:
          - reference: $components.parameters.username
            value: admin
          - reference: $components.parameters.password
      - stepId: addIngredient
        operationId: createIngredient
        parameters:
          - reference: $components.parameters.authorization
          - name: name
            in: query
            value: $inputs.ingredient_name
          - name: type
            in: query
            value: $inputs.ingredient_type
          - name: stock
            in: query
            value: $inputs.ingredient_stock
          - name: productCode
            in: query
            value: $inputs.productCode
components:
  inputs:
    authenticate:
      type: object
      properties:
        username:
          type: string
        password:
          type: string
  parameters:
    authorization:
      name: Authorization
      in: header
      value: $authenticate.outputs.token
    username:
      name: username
      in: body
      value: $inputs.username
    password:
      name: password
      in: body
      value: $inputs.password
```

This table shows all fields at the root of the Arazzo Specification:

<Table
  data={[
    {
      fieldName: "`arazzo`",
      type: "`string`",
      required: "✅",
      description: "The version of the Arazzo Specification that the document uses. The value must be a supported [version number](#arazzo-specification-versions)."
    },
    {
      fieldName: "`info`",
      type: "[Info Object](#info-object)",
      required: "✅",
      description: "Provides metadata about the Arazzo description."
    },
    {
      fieldName: "`sourceDescriptions`",
      type: "[[Source Description Object](#source-description-object)]",
      required: "✅",
      description: "An array of [source description objects](#source-description-object) defining the OpenAPI or other documents containing the operations referenced by the workflows. The array must contain at least one source."
    },
    {
      fieldName: "`workflows`",
      type: "[[Workflow Object](#workflow-object)]",
      required: "✅",
      description: "An array of [workflow objects](#workflow-object) defining the workflows. The array must contain at least one workflow."
    },
    {
      fieldName: "`components`",
      type: "[Components Object](#components-object)",
      required: "",
      description: "An element to hold reusable schemas for the workflow, for example, inputs and parameters."
    },
    {
      fieldName: "`x-*`",
      type: "[Extensions](#arazzo-specification-extensions)",
      required: "",
      description: "Any number of extension fields can be added to the Arazzo description that can be used by tooling and vendors. When provided at this level, the extensions generally apply to the entire document."
    }
  ]}
  columns={[
    { key: "fieldName", header: "Field Name" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

## Arazzo Specification Versions

The `arazzo` field contains the version number of the Arazzo Specification that the document conforms to. Tooling should use this value to interpret the document correctly.

The current version of the Arazzo Specification is 1.0.0-prerelease, but keep in mind that the specification is still under development.

## Info Object

Provides metadata about the Arazzo description.

<Table
  data={[
    {
      fieldName: "`title`",
      type: "`string`",
      required: "✅",
      description: "A human-readable title for the set of workflows."
    },
    {
      fieldName: "`summary`",
      type: "`string`",
      required: "",
      description: "A short summary of the Arazzo description."
    },
    {
      fieldName: "`description`",
      type: "`string`",
      required: "",
      description: "A longer description of the Arazzo description. [CommonMark syntax](https://spec.commonmark.org/) may be used for rich text representation."
    },
    {
      fieldName: "`version`",
      type: "`string`",
      required: "✅",
      description: "A version string indicating the version of the Arazzo document."
    },
    {
      fieldName: "`x-*`",
      type: "[Extensions](#arazzo-specification-extensions)",
      required: "",
      description: "Any number of extension fields can be added that can be used by tooling and vendors."
    }
  ]}
  columns={[
    { key: "fieldName", header: "Field Name" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

Below is an example of an `info` object in an Arazzo document:

```yaml filename="arazzo.yaml"
info:
  title: Speakeasy Bar Workflows
  summary: Workflows for managing the Speakeasy Bar API
  description: >
    This document defines workflows for managing the [Speakeasy Bar API](https://bar.example.com), including
    creating new drinks, managing inventory, and processing orders.
  version: 4.6.3
```

## Source Description Object

A source description points to an OpenAPI document containing the operations referenced by the workflows in this document. It may also reference other Arazzo documents.

<Table
  data={[
    {
      fieldName: "`name`",
      type: "`string`",
      required: "✅",
      description: "A name for the source document, used to reference it from other parts of the Arazzo description. The name must be unique within the `sourceDescriptions` array and may only contain alphanumeric characters, underscores, and dashes."
    },
    {
      fieldName: "`url`",
      type: "`string`",
      required: "✅",
      description: "The URL of the source document. This identifier must conform to [RFC 3986 section 4.1](https://datatracker.ietf.org/doc/html/rfc3986#section-4.1) for absolute URLs or [section 4.2](https://datatracker.ietf.org/doc/html/rfc3986#section-4.2) for relative URIs."
    },
    {
      fieldName: "`type`",
      type: "`string`",
      required: "",
      description: "The type of the source document. Supported values are `openapi`, indicating an OpenAPI document, or `arazzo` indicating another Arazzo description. Additional values may be supported in future versions of the specification."
    },
    {
      fieldName: "`x-*`",
      type: "[Extensions](#arazzo-specification-extensions)",
      required: "",
      description: "Any number of extension fields can be added to the source description object that can be used by tooling and vendors."
    }
  ]}
  columns={[
    { key: "fieldName", header: "Field Name" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

Below is an example of two source description objects in an Arazzo description document:

```yaml filename="arazzo.yaml"
sourceDescriptions:
  - name: speakeasyBar
    url: https://bar.example.com/openapi.yaml
    type: openapi
  - name: printsAndBeeps
    url: https://output.example.com/workflows.yaml
    type: workflowsSpec
```

## Workflow Object

A workflow object defines a sequence of operations.

<Table
  data={[
    {
      fieldName: "`workflowId`",
      type: "`string`",
      required: "✅",
      description: "A unique identifier for the workflow. This is used to reference the workflow from other parts of the Arazzo description. May contain only alphanumeric characters, underscores, and dashes."
    },
    {
      fieldName: "`summary`",
      type: "`string`",
      required: "",
      description: "A short summary of what the workflow does."
    },
    {
      fieldName: "`description`",
      type: "`string`",
      required: "",
      description: "A longer description of the workflow. [CommonMark syntax](https://spec.commonmark.org/) may be used for rich text representation."
    },
    {
      fieldName: "`inputs`",
      type: "[JSON Schema](https://json-schema.org/)",
      required: "",
      description: "A schema defining the input parameters for the workflow."
    },
    {
      fieldName: "`dependsOn`",
      type: "[`string`]",
      required: "",
      description: "An array of workflow IDs that this workflow depends on. The workflows in the array must be executed before this workflow."
    },
    {
      fieldName: "`steps`",
      type: "[[Step Object](#step-object)]",
      required: "✅",
      description: "An ordered array of [step objects](#step-object) defining the steps of the workflow. The array must contain at least one step."
    },
    {
      fieldName: "`successActions`",
      type: "[[Success Action Object](#success-action-object) \\| [Reusable Object](#reusable-object)]",
      required: "",
      description: "An array of [success action objects](#success-action-object) and [reusable objects](#reusable-object) specifying actions to take for each step of this workflow that completes successfully. Individual steps may override the workflow object's success actions. Reusable objects must reference success actions defined in the [components/successActions](#components-object) of this Arazzo document."
    },
    {
      fieldName: "`failureActions`",
      type: "[[Failure Action Object](#failure-action-object) \\| [Reusable Object](#reusable-object)]",
      required: "",
      description: "An array of [failure action objects](#failure-action-object) and [reusable objects](#reusable-object) specifying actions to take for each step of this workflow that fails. Individual steps may override the workflow object's failure actions. Reusable objects must reference success actions defined in the [components/failureActions](#components-object) of this Arazzo document."
    },
    {
      fieldName: "`outputs`",
      type: "Map[`string`, \\{[Runtime Expression](#runtime-expressions)}]",
      required: "",
      description: "A map of output values produced by the workflow. The keys are the names of the outputs, and the values are [runtime expressions](#runtime-expressions) that extract the output values from the results of the workflow steps."
    },
    {
      fieldName: "`parameters`",
      type: "[[Parameter Object](#parameter-object) \\| [Reusable Object](#reusable-object)]",
      required: "",
      description: "An array of parameters applicable to all steps in this workflow. Individual steps may override the workflow object's parameters. A reusable object must reference an object in this document's [components/parameters](#components-object) of this Arazzo document."
    },
    {
      fieldName: "`x-*`",
      type: "[Extensions](#arazzo-specification-extensions)",
      required: "",
      description: "Any number of extension fields can be added to the workflow object that can be used by tooling and vendors."
    }
  ]}
  columns={[
    { key: "fieldName", header: "Field Name" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

Below is an example of a workflow object:

```yaml filename="arazzo.yaml"  
workflows:
  - workflowId: createDrink
    summary: Create a new drink in the bar's menu
    inputs:
      allOf:
        - $ref: "#/components/inputs/authenticate"
        - type: object
          properties:
            drink_name:
              type: string
            drink_type:
              type: string
            drink_price_usd_cent:
              type: integer
            ingredients:
              type: array
              items:
                type: string
    steps:
      - stepId: authenticate
        operationId: authenticate
        parameters:
          - reference: $components.parameters.username
          - reference: $components.parameters.password
      - stepId: createDrink
        operationId: createDrink
        parameters:
          - reference: $components.parameters.authorization
          - name: name
            in: query
            value: $inputs.drink_name
          - name: type
            in: query
            value: $inputs.drink_type
          - name: price
            in: query
            value: $inputs.drink_price_usd_cent
          - name: ingredients
            in: query
            value: $inputs.ingredients
  - workflowId: makeDrink
    summary: Order a drink and check the order status
    inputs:
      - name: orderType
        description: The type of order
        type: string
        required: true
      - name: productCode
        description: The product code of the drink
        type: string
        required: true
      - name: quantity
        description: The quantity of the drink
        type: integer
        required: true
    steps:
      - stepId: orderDrink
        operationId: createOrder
        parameters:
          - name: orderType
            in: body
            value: $inputs.orderType
          - name: productCode
            in: body
            value: $inputs.productCode
          - name: quantity
            in: body
            value: $inputs.quantity
      - stepId: checkStatus
        operationId: getOrder
        parameters:
          - name: orderNumber
            in: path
            value: $orderDrink.orderNumber
        successCriteria:
          - type: simple
            condition: $checkStatus.status == 'completed'
        onSuccess:
          - name: printReceipt
            type: goto
            workflowId: $sourceDescriptions.printsAndBeeps.printReceipt
            criteria:
              - type: simple
                condition: $checkStatus.status == 'completed'
        onFailure:
          - name: beepLoudly
            type: goto
            workflowId: $sourceDescriptions.printsAndBeeps.beepLoudly
            criteria:
              - type: simple
                condition: $checkStatus.status == 'failed'
  - workflowId: addIngredient
    summary: Add a new ingredient to the bar's inventory
    inputs:
      - name: username
        description: The username of the manager
        type: string
        required: true
      - name: password
        description: The password of the manager
        type: string
        required: true
      - name: ingredient_name
        description: The name of the ingredient
        type: string
        required: true
      - name: ingredient_type
        description: The type of the ingredient
        type: string
        required: true
      - name: ingredient_stock
        description: The stock of the ingredient
        type: integer
        required: true
      - name: productCode
        description: The product code of the ingredient
        type: string
        required: true
    steps:
      - stepId: authenticate
        operationId: authenticate
        parameters:
          - reference: $components.parameters.username
            value: admin
          - reference: $components.parameters.password
      - stepId: addIngredient
        operationId: createIngredient
        parameters:
          - reference: $components.parameters.authorization
          - name: name
            in: query
            value: $inputs.ingredient_name
          - name: type
            in: query
            value: $inputs.ingredient_type
          - name: stock
            in: query
            value: $inputs.ingredient_stock
          - name: productCode
            in: query
            value: $inputs.productCode
```

## Step Object

A step object defines a single operation to perform as part of a workflow.

<Table
  data={[
    {
      fieldName: "`stepId`",
      type: "`string`",
      required: "✅",
      description: "A unique identifier for the step within the workflow. Used to reference the step's outputs from other parts of the workflow. May contain only alphanumeric characters, underscores, and dashes."
    },
    {
      fieldName: "`description`",
      type: "`string`",
      required: "",
      description: "A description of what the step does. [CommonMark syntax](https://spec.commonmark.org/) may be used for rich text representation."
    },
    {
      fieldName: "`operationId`",
      type: "`string`",
      required: "",
      description: "The `operationId` of the operation to execute for this step. Must match an `operationId` in one of the `sourceDescriptions`. This field is mutually exclusive with `operationPath` and `workflowId`."
    },
    {
      fieldName: "`operationPath`",
      type: "`string`",
      required: "",
      description: "A JSON Pointer to the operation to execute for this step, relative to one of the `sourceDescriptions`. This field is mutually exclusive with `operationId` and `workflowId`."
    },
    {
      fieldName: "`workflowId`",
      type: "`string`",
      required: "",
      description: "The ID of a workflow in this document to execute as a sub-workflow. This field is mutually exclusive with `operationId` and `operationPath`."
    },
    {
      fieldName: "`parameters`",
      type: "[[Parameter Object](#parameter-object) \\| [Reusable Object](#reusable-object)]",
      required: "",
      description: "An array of parameters to pass to the operation for this step. Overrides any parameters defined at the workflow level."
    },
    {
      fieldName: "`requestBody`",
      type: "[Request Body Object](#request-body-object)",
      required: "",
      description: "The request body to send for the operation."
    },
    {
      fieldName: "`successCriteria`",
      type: "[[Criterion Object](#criterion-object)]",
      required: "",
      description: "An array of criteria for determining if the step succeeded. All criteria must be met for the step to be considered successful. Individual criteria are defined using [criterion objects](#criterion-object)."
    },
    {
      fieldName: "`onSuccess`",
      type: "[[Success Action Object](#success-action-object) \\| [Reusable Object](#reusable-object)]",
      required: "",
      description: "An array of actions to take if the step succeeds. Overrides any success actions defined at the workflow level. Individual actions are defined using [success action objects](#success-action-object)."
    },
    {
      fieldName: "`onFailure`",
      type: "[[Failure Action Object](#failure-action-object) \\| [Reusable Object](#reusable-object)]",
      required: "",
      description: "An array of actions to take if the step fails. Overrides any failure actions defined at the workflow level. Individual actions are defined using [failure action objects](#failure-action-object)."
    },
    {
      fieldName: "`outputs`",
      type: "Map[`string`, \\{[Runtime Expression](#runtime-expressions)}]",
      required: "",
      description: "A map of output values produced by the step. The keys are the names of the outputs, and the values are [runtime expressions](#runtime-expressions) that extract the output values from the result of the operation."
    },
    {
      fieldName: "`x-*`",
      type: "[Extensions](#arazzo-specification-extensions)",
      required: "",
      description: "Any number of extension fields can be added to the step object that can be used by tooling and vendors."
    }
  ]}
  columns={[
    { key: "fieldName", header: "Field Name" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

Below is an example of step objects in an Arazzo description document:

```yaml filename="arazzo.yaml"
steps:
      - stepId: orderDrink
        operationId: createOrder
        parameters:
          - name: orderType
            in: body
            value: $inputs.orderType
          - name: productCode
            in: body
            value: $inputs.productCode
          - name: quantity
            in: body
            value: $inputs.quantity
```

## Parameter Object

A parameter object defines a single parameter to pass to an operation in a workflow step.

<Table
  data={[
    {
      fieldName: "`name`",
      type: "`string`",
      required: "✅",
      description: "The name of the parameter."
    },
    {
      fieldName: "`in`",
      type: "`string`",
      required: "✅",
      description: "The location of the parameter. Possible values are `path`, `query`, `header`, `cookie`. Required for parameters passed to an operation. Must be omitted for parameters passed to a workflow, where the parameter is always passed in the workflow's `inputs` object. See [Parameter Location](#parameter-location)."
    },
    {
      fieldName: "`value`",
      type: "Any \\| \\{[Runtime Expression](#runtime-expressions)}",
      required: "",
      description: "The value of the parameter. Can be a literal value, or a [runtime expression](#runtime-expressions) that will be evaluated and passed to the operation or workflow."
    },
    {
      fieldName: "`x-*`",
      type: "[Extensions](#arazzo-specification-extensions)",
      required: "",
      description: "Any number of extension fields can be added to the parameter object that can be used by tooling and vendors."
    }
  ]}
  columns={[
    { key: "fieldName", header: "Field Name" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

### Parameter Location

For parameters passed to an operation, the `in` field specifies the location of the parameter. The possible values are:

- `path` - The parameter is part of the operation's URL path.
- `query` - The parameter is appended to the operation's URL as a query parameter.
- `header` - The parameter is sent in the request headers.
- `cookie` - The parameter is sent in a cookie.

For parameters passed to a workflow, the `in` field must be omitted. Workflow parameters are always passed in the workflow's `inputs` object.

### Arazzo Parameter Object Examples

```yaml filename="arazzo.yaml"
parameters:
  - reference: $components.parameters.authorization
  - name: name
    in: query
    value: $inputs.drink_name
  - name: type
    in: query
    value: $inputs.drink_type
  - name: price
    in: query
    value: $inputs.drink_price_usd_cent
  - name: ingredients
    in: query
    value: $inputs.ingredients
```

## Success Action Object

A success action object defines an action to take when a workflow step succeeds.

<Table
  data={[
    {
      fieldName: "`name`",
      type: "`string`",
      required: "✅",
      description: "The name of the action. Names are case-sensitive and must be unique within the `successActions` array of a step or workflow."
    },
    {
      fieldName: "`type`",
      type: "`string`",
      required: "✅",
      description: "The type of action to take. Possible values are:\n- `end` - End the workflow.\n- `goto` - Move to another step in the workflow. Requires either `stepId` or `workflowId` to be specified."
    },
    {
      fieldName: "`stepId`",
      type: "`string`",
      required: "",
      description: "The `stepId` of the step to execute next if `type` is `goto`. Mutually exclusive with `workflowId`."
    },
    {
      fieldName: "`workflowId`",
      type: "`string`",
      required: "",
      description: "The `workflowId` of the workflow to execute if `type` is `goto`. Mutually exclusive with `stepId`."
    },
    {
      fieldName: "`criteria`",
      type: "[[Criterion Object](#criterion-object)]",
      required: "",
      description: "An array of criteria that determine whether the action should be executed. All criteria must be met for the action to execute. If not provided, the action will always execute."
    },
    {
      fieldName: "`x-*`",
      type: "[Extensions](#arazzo-specification-extensions)",
      required: "",
      description: "Any number of extension fields can be added to the success action object that can be used by tooling and vendors."
    }
  ]}
  columns={[
    { key: "fieldName", header: "Field Name" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

Below is an example of a success action object:

```yaml filename="arazzo.yaml"
onSuccess:
  - name: printReceipt
    type: goto
    workflowId: $sourceDescriptions.printsAndBeeps.printReceipt
    criteria:
      - type: simple
        condition: $checkStatus.status == 'completed'
```

## Failure Action Object

A failure action object defines an action to take when a workflow step fails.

<Table
  data={[
    {
      fieldName: "`name`",
      type: "`string`",
      required: "✅",
      description: "The name of the action. Names are case-sensitive and must be unique within the `failureActions` array of a step or workflow."
    },
    {
      fieldName: "`type`",
      type: "`string`",
      required: "✅",
      description: "The type of action to take. Possible values are:\n- `end` - End the workflow, returning the specified `outputs` if provided.\n- `goto` - Move to another step in the workflow. Requires either `stepId` or `workflowId` to be specified.\n- `retry` - Retry the failed step. Requires `retryAfter` and optionally `retryLimit` to be specified."
    },
    {
      fieldName: "`stepId`",
      type: "`string`",
      required: "",
      description: "The `stepId` of the step to execute next if `type` is `goto`. Mutually exclusive with `workflowId`."
    },
    {
      fieldName: "`workflowId`",
      type: "`string`",
      required: "",
      description: "The `workflowId` of the workflow to execute if `type` is `goto`. Mutually exclusive with `stepId`."
    },
    {
      fieldName: "`retryAfter`",
      type: "Number",
      required: "",
      description: "The number of seconds to wait before retrying the failed step if `type` is `retry`. Must be a non-negative integer. The specification is ambiguous about whether this field also applies when `type` is `goto`."
    },
    {
      fieldName: "`retryLimit`",
      type: "Integer",
      required: "",
      description: "The maximum number of times to retry the failed step if `type` is `retry`. Must be a non-negative integer. If not provided, the step will be retried indefinitely until it succeeds or the workflow is canceled."
    },
    {
      fieldName: "`criteria`",
      type: "[[Criterion Object](#criterion-object)]",
      required: "",
      description: "An array of criteria that determine whether the action should be executed. All criteria must be met for the action to execute."
    },
    {
      fieldName: "`x-*`",
      type: "[Extensions](#arazzo-specification-extensions)",
      required: "",
      description: "Any number of extension fields can be added to the failure action object that can be used by tooling and vendors."
    }
  ]}
  columns={[
    { key: "fieldName", header: "Field Name" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

Below is an example of a failure action object:

```yaml filename="arazzo.yaml"
onFailure:
  - name: beepLoudly
    type: goto
    workflowId: $sourceDescriptions.printsAndBeeps.beepLoudly
    criteria:
      - type: simple
        condition: $checkStatus.status == 'failed'
```

## Components Object

The `components` object holds reusable objects that can be referenced from other parts of the Arazzo description.

<Table
  data={[
    {
      fieldName: "`inputs`",
      type: "Map[`string`, `JSON Schema`]",
      required: "",
      description: "An object containing reusable [JSON Schemas](https://json-schema.org/) that can be referenced from workflow `inputs`."
    },
    {
      fieldName: "`parameters`",
      type: "Map[`string`, [Parameter Object](#parameter-object)]",
      required: "",
      description: "An object containing reusable [parameter objects](#parameter-object)."
    },
    {
      fieldName: "`successActions`",
      type: "Map[`string`, [Success Action Object](#success-action-object)]",
      required: "",
      description: "An object containing reusable [success action objects](#success-action-object)."
    },
    {
      fieldName: "`failureActions`",
      type: "Map[`string`, [Failure Action Object](#failure-action-object)]",
      required: "",
      description: "An object containing reusable [failure action objects](#failure-action-object)."
    },
    {
      fieldName: "`x-*`",
      type: "[Extensions](#arazzo-specification-extensions)",
      required: "",
      description: "Any number of extension fields can be added to the components object that can be used by tooling and vendors."
    }
  ]}
  columns={[
    { key: "fieldName", header: "Field Name" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

The keys in the `components` object may only contain alphanumeric characters, underscores, and dashes.

### Arazzo Components Object Example

```yaml filename="arazzo.yaml"  
components:
  inputs:
    authenticate:
      type: object
      properties:
        username:
          type: string
        password:
          type: string
  parameters:
    authorization:
      name: Authorization
      in: header
      value: $authenticate.outputs.token
    username:
      name: username
      in: body
      value: $inputs.username
    password:
      name: password
      in: body
      value: $inputs.password
```

The components defined in an Arazzo description are scoped to that document. Components defined in one Arazzo description cannot be referenced from another Arazzo description.

## Reusable Object

A reusable object allows you to reference objects like success actions and failure actions defined in the `components` object from locations within steps or workflows.

<Table
  data={[
    {
      fieldName: "`reference`",
      type: "\\{[Runtime Expression](#runtime-expressions)}",
      required: "✅",
      description: "A [runtime expression](#runtime-expressions) used to reference the desired object from the `components` object."
    },
    {
      fieldName: "`value`",
      type: "string",
      required: "",
      description: "The value of the referenced parameter. Only used for parameters."
    }
  ]}
  columns={[
    { key: "fieldName", header: "Field Name" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

### Arazzo Reusable Object Example

```yaml filename="arazzo.yaml"
- reference: $components.parameters.username
  value: admin
- reference: $components.parameters.password
```

## Criterion Object

A criterion object is used to specify assertions in the `successCriteria` field of a [step object](#step-object), or the `criteria` field of a [success action object](#success-action-object) or [failure action object](#failure-action-object).

Criterion objects support three types of assertions:

- `simple` - Basic comparisons using literals, operators, and [runtime expressions](#runtime-expressions). This is the default if no `type` is specified.
- `regex` - Applies a regular expression pattern to a context defined by a [runtime expression](#runtime-expressions).
- `JSONPath` - Applies a [JSONPath](https://goessner.net/articles/JsonPath/) expression to a context defined by a [runtime expression](#runtime-expressions). The root node of the JSONPath is the context.

### Literals

Literals are constant values that can be used in `simple` conditions. The following data types are supported:

<Table
  data={[
    {
      type: "`boolean`",
      literalValue: "`true` or `false`"
    },
    {
      type: "`null`",
      literalValue: "`null`"
    },
    {
      type: "`number`",
      literalValue: "A number of type `int32`, `int64`, `float`, or `double`."
    },
    {
      type: "`string`",
      literalValue: "Strings must be enclosed in single quotes ('). To include a literal single quote, escape it with another single quote ('')."
    }
  ]}
  columns={[
    { key: "type", header: "Type" },
    { key: "literalValue", header: "Literal Value" }
  ]}
/>

### Operators

Simple conditions support the following operators:

<Table
  data={[
    {
      operator: "`<`",
      description: "Less than"
    },
    {
      operator: "`<=`",
      description: "Less than or equal"
    },
    {
      operator: "`>`",
      description: "Greater than"
    },
    {
      operator: "`>=`",
      description: "Greater than or equal"
    },
    {
      operator: "`==`",
      description: "Equal"
    },
    {
      operator: "`!=`",
      description: "Not equal"
    },
    {
      operator: "`!`",
      description: "Not"
    },
    {
      operator: "`&&`",
      description: "And"
    },
    {
      operator: "`||`",
      description: "Or"
    },
    {
      operator: "`()`",
      description: "Grouping"
    },
    {
      operator: "`[]`",
      description: "Array index (0-based)"
    },
    {
      operator: "`.`",
      description: "Property dereference"
    }
  ]}
  columns={[
    { key: "operator", header: "Operator" },
    { key: "description", header: "Description" }
  ]}
/>

String comparisons are case-insensitive.

A criterion object consists of the following fields:

<Table
  data={[
    {
      fieldName: "`context`",
      type: "\\{[Runtime Expression](#runtime-expressions)}",
      required: "",
      description: "A [runtime expression](#runtime-expressions) that defines the context for `regex` and `JSONPath` conditions. Must be provided if `type` is specified."
    },
    {
      fieldName: "`condition`",
      type: "`string`",
      required: "✅",
      description: "The assertion to evaluate. For `simple` conditions, combines literals, operators, and runtime expressions. For `regex` and `JSONPath` conditions, provides the expression to evaluate against the `context`."
    },
    {
      fieldName: "`type`",
      type: "`string`",
      required: "",
      description: "The type of assertion. Allowed values are `simple`, `regex`, or `JSONPath`. Defaults to `simple` if not provided."
    },
    {
      fieldName: "`x-*`",
      type: "[Extensions](#arazzo-specification-extensions)",
      required: "",
      description: "Any number of extension fields can be added to the criterion object that can be used by tooling and vendors."
    }
  ]}
  columns={[
    { key: "fieldName", header: "Field Name" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

### Arazzo Criterion Object Examples

**Simple Condition - Check if a drink was successfully created**

```yaml filename="arazzo.yaml"
- condition: $statusCode == 201
```

**Simple Condition - Check if the bar is open**

```yaml
- condition: $response.body#/isOpen == true
```

**Regex Condition - Check if the drink name matches a pattern**

```yaml filename="arazzo.yaml"
- context: $response.body#/drinkName
  condition: "^Sazerac"
  type: regex
```

**JSONPath Condition - Check if the ingredient list contains "whiskey"**

```yaml filename="arazzo.yaml"
- context: $response.body
  condition: $..ingredients[?(@.name == 'whiskey')]
  type: JSONPath
```

**Simple Condition - Check if the customer is over 21**

```yaml filename="arazzo.yaml"
- condition: $response.body#/customer/age >= 21
```

**JSONPath Condition - Check if there are any available tables**

```yaml filename="arazzo.yaml"
- context: $response.body
  condition: $[?length(@.tables[?(@.available == true)]) > 0]
  type: JSONPath
```

## Request Body Object

The request body object describes the payload and `Content-Type` to send with the request when executing an operation in a workflow step.

<Table
  data={[
    {
      fieldName: "`contentType`",
      type: "`string`",
      required: "",
      description: "The `Content-Type` header for the request payload. If omitted, defaults to the `Content-Type` of the referenced operation."
    },
    {
      fieldName: "`payload`",
      type: "Any",
      required: "",
      description: "The literal payload value to send in the request body. Can contain [runtime expressions](#runtime-expressions) which will be evaluated before sending the request."
    },
    {
      fieldName: "`replacements`",
      type: "[[Payload Replacement Object](#payload-replacement-object)]",
      required: "",
      description: "An array of [payload replacement objects](#payload-replacement-object) specifying values to insert into specific locations in the payload."
    },
    {
      fieldName: "`x-*`",
      type: "[Extensions](#arazzo-specification-extensions)",
      required: "",
      description: "Any number of extension fields can be added to the request body object that can be used by tooling and vendors."
    }
  ]}
  columns={[
    { key: "fieldName", header: "Field Name" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

### Request Body Object Examples

**JSON Payload (Template)**

```yaml filename="arazzo.yaml"
contentType: application/json
payload: |
  {
    "order": {
      "drinkId": "{$inputs.drink_id}",
      "customerId": "{$inputs.customer_id}",
      "quantity": {$inputs.quantity}
    }
  }
```

**JSON Payload (Object)**

```yaml filename="arazzo.yaml"
contentType: application/json
payload:
  order:
    drinkId: $inputs.drink_id
    customerId: $inputs.customer_id
    quantity: $inputs.quantity
```

**JSON Payload (Runtime Expression)**

```yaml filename="arazzo.yaml"
contentType: application/json
payload: $inputs.orderPayload
```

**XML Payload (Template)**

```yaml filename="arazzo.yaml"
contentType: application/xml
payload: |
  <order>
    <drinkId>{$inputs.drink_id}</drinkId>
    <customerId>{$inputs.customer_id}</customerId>
    <quantity>{$inputs.quantity}</quantity>
  </order>
```

**Form Data Payload (Object)**

```yaml filename="arazzo.yaml"
contentType: application/x-www-form-urlencoded
payload:
  drinkId: $inputs.drink_id
  customerId: $inputs.customer_id
  quantity: $inputs.quantity
```

**Form Data Payload (String)**

```yaml filename="arazzo.yaml"
contentType: application/x-www-form-urlencoded
payload: "drinkId={$inputs.drink_id}&customerId={$inputs.customer_id}&quantity={$inputs.quantity}"
```

## Payload Replacement Object

A payload replacement object specifies a location within the request payload and the value to insert at that location.

<Table
  data={[
    {
      fieldName: "`target`",
      type: "`string`",
      required: "✅",
      description: "A [JSON Pointer](https://tools.ietf.org/html/rfc6901) or [XPath](https://www.w3.org/TR/xpath-31/#id-expressions) expression that identifies the location in the payload to insert the `value`. For JSON payloads, use JSON Pointer. For XML payloads, use XPath."
    },
    {
      fieldName: "`value`",
      type: "Any",
      required: "✅",
      description: "The value to insert at the specified `target` location. Can be a literal or a [runtime expression](#runtime-expressions) that will be evaluated before sending the request."
    },
    {
      fieldName: "`x-*`",
      type: "[Extensions](#arazzo-specification-extensions)",
      required: "",
      description: "Any number of extension fields can be added to the payload replacement object that can be used by tooling and vendors."
    }
  ]}
  columns={[
    { key: "fieldName", header: "Field Name" },
    { key: "type", header: "Type" },
    { key: "required", header: "Required" },
    { key: "description", header: "Description" }
  ]}
/>

### Payload Replacement Object Examples

**Runtime Expression Value**

```yaml
target: /drinkId
value: $inputs.drink_id
```

**Literal Value**

```yaml
target: /quantity
value: 2
```

## Runtime Expressions

Runtime expressions allow you to reference values that will be available when a workflow is executed, such as values from the HTTP request or response, the event that triggered the workflow, or outputs from previous workflow steps.

The syntax for runtime expressions is `{expression}`, where `expression` is one of the following:

<Table
  data={[
    {
      expression: "`$url`",
      description: "The full URL of the request"
    },
    {
      expression: "`$method`",
      description: "The HTTP method of the request"
    },
    {
      expression: "`$statusCode`",
      description: "The HTTP status code of the response"
    },
    {
      expression: "`$request.header.{name}`",
      description: "The value of the specified request header"
    },
    {
      expression: "`$request.query.{name}`",
      description: "The value of the specified query parameter from the request URL"
    },
    {
      expression: "`$request.path.{name}`",
      description: "The value of the specified path parameter from the request URL"
    },
    {
      expression: "`$request.body`",
      description: "The entire request body"
    },
    {
      expression: "`$request.body#/path/to/property`",
      description: "The value of the specified JSON pointer path from the request body"
    },
    {
      expression: "`$response.header.{name}`",
      description: "The value of the specified response header"
    },
    {
      expression: "`$response.body`",
      description: "The entire response body"
    },
    {
      expression: "`$response.body#/path/to/property`",
      description: "The value of the specified JSON pointer path from the response body"
    },
    {
      expression: "`$inputs.{name}`",
      description: "The value of the specified workflow input"
    },
    {
      expression: "`$outputs.{name}`",
      description: "The value of the specified workflow output"
    },
    {
      expression: "`$steps.{stepId}.{outputName}`",
      description: "The value of the specified output from the step with ID `{stepId}`"
    },
    {
      expression: "`$workflows.{id}.{inputName}`",
      description: "The value of the specified input from the workflow with ID `{id}`"
    },
    {
      expression: "`$workflows.{id}.{outputName}`",
      description: "The value of the specified output from the workflow with ID `{id}`"
    }
  ]}
  columns={[
    { key: "expression", header: "Expression" },
    { key: "description", header: "Description" }
  ]}
/>

### Runtime Expression Examples

<Table
  data={[
    {
      expression: "`$request.header.Authorization`",
      exampleValue: "`Bearer abc123`"
    },
    {
      expression: "`$request.query.drinkId`",
      exampleValue: "`12345`"
    },
    {
      expression: "`$response.body#/drinks/0/name`",
      exampleValue: "`\"Negroni\"`"
    },
    {
      expression: "`$inputs.orderType`",
      exampleValue: "`\"pickup\"`"
    },
    {
      expression: "`$steps.submitOrder.outputs.orderId`",
      exampleValue: "`\"a8b9c6d4e5f001\"`"
    }
  ]}
  columns={[
    { key: "expression", header: "Expression" },
    { key: "exampleValue", header: "Example Value" }
  ]}
/>

## Arazzo Specification Extensions

The Arazzo Specification allows custom properties to be added at certain points using specification extensions.

Extension properties are always prefixed by `"x-"` and can have any valid JSON value.

For example:

```yaml
x-internal-id: abc123
x-vendor-parameter:
  vendorId: 123
  channelId: abc
```

The extensions defined by the Arazzo Specification are:

<Table
  data={[
    {
      context: "[Arazzo Description](#arazzo-description-structure)",
      description: "Applies to the entire Arazzo description document"
    },
    {
      context: "[Info Object](#info-object)",
      description: "Applies to the `info` object"
    },
    {
      context: "[Source Description Object](#source-description-object)",
      description: "Applies to all the source description objects"
    },
    {
      context: "[Workflow Object](#workflow-object)",
      description: "Applies to all workflow objects"
    },
    {
      context: "[Step Object](#step-object)",
      description: "Applies to all step objects"
    },
    {
      context: "[Parameter Object](#parameter-object)",
      description: "Applies to all parameter objects"
    },
    {
      context: "[Success Action Object](#success-action-object)",
      description: "Applies to all success action objects"
    },
    {
      context: "[Failure Action Object](#failure-action-object)",
      description: "Applies to all failure action objects"
    },
    {
      context: "[Criterion Object](#criterion-object)",
      description: "Applies to all criterion objects"
    },
    {
      context: "[Request Body Object](#request-body-object)",
      description: "Applies to all request body objects"
    },
    {
      context: "[Payload Replacement Object](#payload-replacement-object)",
      description: "Applies to all payload replacement objects"
    },
    {
      context: "[Reusable Object](#reusable-object)",
      description: "Applies to all reusable objects"
    },
    {
      context: "[Components Object](#components-object)",
      description: "Applies to the components object"
    }
  ]}
  columns={[
    { key: "context", header: "Context" },
    { key: "description", header: "Description" }
  ]}
/>

The specification extension key formats `^x-oai-` and `^x-oas-` are reserved for extensions defined by the [OpenAPI Initiative](https://www.openapis.org/).

Extension properties can be used to add additional features, metadata, or configuration options to the Arazzo description that are not directly supported by the current version of the specification. However, additional tooling may be required to process custom extensions.