What is the Arazzo Specification?

Posted in

API calls rarely occur alone. It’s far more common for a programming function to require a series of API calls, otherwise known as an API workflow. To help describe these situations, the OpenAPI Initiative has released a new specification, Arazzo, specifically to address API workflows.

At the 2024 API Days in Helsinki, Frank Kilcommins of SmartBear announced Arazzo and how it describes groups of APIs and their relationships. We’ve looked into the specification and compiled a short guide and introduction to Arazzo to get you started with this new API standard.

Introduction to Arazzo Specification

Arazzo specification OpenAPI

The Arazzo Specification: A “tapestry” for deterministic API workflows.

The Arazzo Specification introduces a solution for adding a layer of abstraction to define a series of API calls. It also describes their dependencies, which can be linked together to produce a particular outcome. The Arazzo Specification is both machine-readable and human-readable. The fact that Arazzo is machine-readable enables a rich ecosystem of tools and features.

Arazzo is designed to make swapping APIs in a workflow fast and easy. It’s also meant to streamline large, unwieldy API documentation. As such, using Arazzo could improve both the user experience (UX) and the developer experience (DX).

Inside the Arazzo Specification

Arazzo isn’t that dissimilar to an API specification. An Arazzo specification file contains all the information about an API workflow in either JSON or YAML format. If you are trying out Arazzo for yourself, it’s considered best practice to name the file either arazzo.json or arazzo.yaml.

The core of the Arazzo Specification is the Arazzo Specification Object. Like the OpenAPI Specification, the Arazzo Specification Object defines what version of Arazzo is being used. It also contains metadata about the workflow that can be used by tooling. The sourceDescription field is a list of source descriptions, like OpenAPI descriptions, for example. This is followed by the workflows object, which lists all the workflows used by the specifications including inputs, dependencies, and individual steps. Finally, the components object contains the schema used by the Arazzo Description.

Here’s an example Arazzo Specification Object:

arazzo: 1.0.0
info:
  title: A pet purchasing workflow
  summary: This Arazzo Description showcases the workflow for how to purchase a pet through a sequence of API calls
  description: |
      This Arazzo Description walks you through the workflow and steps of `searching` for, `selecting`, and `purchasing` an available pet.
  version: 1.0.1
sourceDescriptions:
- name: petStoreDescription
  url: https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml
  type: openapi

workflows:
- workflowId: loginUserAndRetrievePet
  summary: Login User and then retrieve pets
  description: This workflow lays out the steps to login a user and then retrieve pets
  inputs:
      type: object
      properties:
          username:
              type: string
          password:
              type: string
  steps:
  - stepId: loginStep
    description: This step demonstrates the user login step
    operationId: loginUser
    parameters:
      # parameters to inject into the loginUser operation (parameter name must be resolvable at the referenced operation and the value is determined using {expression} syntax)
      - name: username
        in: query
        value: $inputs.username
      - name: password
        in: query
        value: $inputs.password
    successCriteria:
      # assertions to determine step was successful
      - condition: $statusCode == 200
    outputs:
      # outputs from this step
      tokenExpires: $response.header.X-Expires-After
      rateLimit: $response.header.X-Rate-Limit
      sessionToken: $response.body
  - stepId: getPetStep
    description: retrieve a pet by status from the GET pets endpoint
    operationPath: '{$sourceDescriptions.petstoreDescription.url}#/paths/~1pet~1findByStatus/get'
    parameters:
      - name: status
        in: query
        value: 'available'
      - name: Authorization
        in: header
        value: $steps.loginUser.outputs.sessionToken
    successCriteria:
      - condition: $statusCode == 200
    outputs:
      # outputs from this step
      availablePets: $response.body
  outputs:
      available: $steps.getPetStep.availablePets

Inside the Workflows Object

Let’s take a moment to consider the workflows object as it makes up the bulk of the Arazzo Specification. Let’s start by focusing solely on the workflows section of the specification.

workflows:
- workflowId: loginUserAndRetrievePet
  summary: Login User and then retrieve pets
  description: This workflow lays out the steps to login a user and then retrieve pets
  inputs:
      type: object
      properties:
          username:
              type: string
          password:
              type: string
  steps:
  - stepId: loginStep
    description: This step demonstrates the user login step
    operationId: loginUser
    parameters:
      # parameters to inject into the loginUser operation (parameter name must be resolvable at the referenced operation and the value is determined using {expression} syntax)
      - name: username
        in: query
        value: $inputs.username
      - name: password
        in: query
        value: $inputs.password
    successCriteria:
      # assertions to determine step was successful
      - condition: $statusCode == 200
    outputs:
      # outputs from this step
      tokenExpires: $response.header.X-Expires-After
      rateLimit: $response.header.X-Rate-Limit
      sessionToken: $response.body
  - stepId: getPetStep
    description: retrieve a pet by status from the GET pets endpoint
    operationPath: '{$sourceDescriptions.petstoreDescription.url}#/paths/~1pet~1findByStatus/get'
    parameters:
      - name: status
        in: query
        value: 'available'
      - name: Authorization
        in: header
        value: $steps.loginUser.outputs.sessionToken
    successCriteria:
      - condition: $statusCode == 200
    outputs:
      # outputs from this step
      availablePets: $response.body
  outputs:
      available: $steps.getPetStep.availablePets

To start, we see that this workflow is named loginUserAndRetrievePet. This is followed by a short summary and meta-description explaining the workflow’s function. The inputs are the next item on the specification. The inputs object lets the user know what data to expect as well as its format. The Pet Store Arazzo Specification accepts username and password, for example, accepting string data for both.

The steps segment comprises the bulk of the workflows object. Each step contains a meta description and a summary, like the inputs. It also contains a section for parameters, and details for when the parameters are successful or not. Finally, once a step is successful, the workflows object concludes with the outputs object, which specifies what happens when a parameter is completed successfully.

The steps object isn’t only useful for authenticating successes, however. Workflow output variables can be passed on even if they fall outside the parameters. These variables can also be passed onto additional workflows or monitored and tracked using your logging platform, for example.

How Arazzo Improves Developer Experience

As APIs get more complicated, API documentation can become prohibitively dense and challenging to understand. It can also make an API brittle, with dependencies upon different calls to fulfill a particular goal. Much of this behavior was completely undocumented before the release of Arazzo.

There’s often a disconnect between API producers and consumers. API developers often pass along raw API specifications to API consumers as part of the onboarding process, which are often messy and hard to understand. Official API documentation tends to go stale very quickly once it’s written. The Arazzo Specification will solve both of these issues simultaneously, empowering interactive workflow documentation as well as API documentation automation.

Arazzo’s first benefit for developers is the fact that they’ll likely be familiar with the format. The Arazzo Specification is very similar to the OpenAPI Specification for individual APIs. In fact, they’re often stored side-by-side which you can see if you look at the GitHub Repository for Arazzo examples.

The Arazzo Specification also allows developers to create their own components using the sourceDescriptions function. This feature alone makes API workflows much less brittle and unwieldy. The ability to define API workflows also makes Arazzo excellent for implementing authorization workflows. The specification can detail every step of a workflow, complete with its own HTTP status code. It also helps consumers understand what the API producer intends, a major boost for DX.

Arazzo’s main DX benefit is for large language models (LLMs), though. Having a specification that details what each API call is doing makes it much more understandable for LLMs like ChatGPT. As Frank Kilcommins recently mentioned to an interviewer, at the moment, generative AIs like LLMs have a roughly 80-90% success rate for creating or consuming APIs. The rest has a troubling tendency to be hallucinations, which makes it difficult to trust the LLM’s output. Adding documentation to API workflows to accompany existing API documentation promises to significantly improve accuracy. It also allows an API to be generated from the specification using custom GPTs.

Final Thoughts On The Arazzo Specification

The Arazzo Specification is an essential missing link between an API being both machine-readable and human-readable. It promises to be an important component in helping developers describe an API function using natural language and having an AI like ChatGPT create the API from scratch.

Arazzo also has the potential to make APIs far less brittle and much more modular and versatile, which will become increasingly crucial as APIs continue to become more complex. Last but not least, Arazzo promises to open up a whole new world of powerful new tools that will benefit how developers work with APIs.