Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/_data/guides.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ categories:
long_name: OpenAPI specification guides and tutorials
description: Learn how to use OpenAPI to build HTTP APIs that humans and machines can interact with conveniently.

- name: Arazzo
long_name: Arazzo specification guides and tutorials
description: Learn how to use Arazzo to document, test, and execute API workflows that orchestrate multiple operations into meaningful tasks.

- name: AsyncAPI
long_name: AsyncAPI specification guides and tutorials
description: Learn how to use AsyncAPI to build event-driven APIs that humans and machines can interact with conveniently.
Expand Down
1 change: 1 addition & 0 deletions src/_data/navbar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ left_links:
- {title: "Product Updates", link: "/product-updates"}
- {title: "Guides", link: "/guides"}
- {title: "OpenAPI Specification", link: "/guides/openapi/specification/v3.2/introduction/what-is-openapi"}
- {title: "Arazzo Specification", link: "/guides/arazzo/specification/v1.0/introduction/what-is-arazzo"}
right_links:
- {title: "API Reference", link: "https://developers.bump.sh"}
- {title: "Bump.sh", link: "https://bump.sh"}
38 changes: 38 additions & 0 deletions src/_data/sidebars/guides/arazzo/v1-0.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
collection_name: guides
root: /guides/arazzo/specification/v1.0
resources:
- type: category
label: Introduction to Arazzo
items:
- label: What is Arazzo?
link: /introduction/what-is-arazzo/
- label: History and Evolution of Arazzo
link: /introduction/history/
- label: Benefits of Using Arazzo
link: /introduction/benefits/

- type: category
label: Understanding Arazzo Structure
items:
- label: Basic Structure
link: /understanding-structure/basic-structure/
- label: Defining Sources
link: /understanding-structure/defining-sources/
- label: Workflows
link: /understanding-structure/workflows/
- label: Steps, Inputs, and Outputs
link: /understanding-structure/steps-inputs-outputs/
- label: Success and Failure
link: /understanding-structure/success-and-failure/
- label: Components & References
link: /understanding-structure/components-and-references/

- type: category
label: Working with Arazzo
items:
- label: Runtime Expressions
link: /working-with-arazzo/runtime-expressions/
- label: Workflow Documentation
link: /working-with-arazzo/workflow-documentation/
- label: API Testing
link: /working-with-arazzo/api-testing/
9 changes: 9 additions & 0 deletions src/_guides/arazzo/_defaults.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
layout: documentation
page_class: documentation
sidebar_title: Arazzo Specification
skip_listing: true
display_authors: true
display_pagination: true
display_cta: true
exclude_from_pagination: true
slug: arazzo-specification
9 changes: 9 additions & 0 deletions src/_guides/arazzo/specification/_defaults.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
layout: documentation
page_class: documentation
sidebar_title: Arazzo Specification
skip_listing: true
display_authors: true
display_pagination: true
display_cta: true
exclude_from_pagination: true
slug: arazzo-specification
2 changes: 2 additions & 0 deletions src/_guides/arazzo/specification/v1.0/_defaults.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
sidebar_version: "v1.0"
sidebar_name: arazzo_v1-0
246 changes: 246 additions & 0 deletions src/_guides/arazzo/specification/v1.0/introduction/benefits.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
---
title: Benefits of Using Arazzo
authors: phil
excerpt: Discover the advantages of adopting the Arazzo Specification for documenting, testing, and managing API workflows to benefit humans and agentic-AI.
date: 2025-01-26
---

- TOC
{:toc}

HTTP/REST APIs generally are not just data stores, they usually act more like state machines moving users/clients through various workflows. Despite this, most APIs are designed, documented, and tested as if every request is independent of everything else.

REST APIs specifically attempted to solve this problem through HATEOAS (Hypermedia As The Engine Of Application State) being a core principle allowing clients to navigate through application states via links provided in responses. The trend never really caught on at large, but the problem of helping clients navigate through APIs has never been fully solved. This has lead to API clients generally stumbling around in the dark, hoping there is some manually maintained documentation explaining how to move from one state to another, with the occasional code sample thrown in to help. Some of this might even be up-to-date.

In a world where agentic-AI is becoming more prevalent, this problem is only getting worse. Instead of human developers stumbling around in the dark, we now have AI agents fumbling around trying to figure out how to use APIs to accomplish tasks on behalf of users. These agents need clear, unambiguous instructions on how to navigate through API workflows, including handling errors and edge cases.

Defining these workflows outside of the API itself helps provide clarity to this classic problem, avoiding confusing the client by shoving state controls into the runtime data models and headers. Instead they can be defined in a separate document that references the API definitions, describing how to use them together to accomplish real-world tasks.

The Arazzo Specification provides a standardized way to define these API workflows, making them machine-readable and executable, and the way it extends OpenAPI means the schemas are right there for humans and agents to work with, with the schema and validation rules helping to cut down on hallucinations.

Using Arazzo not only solves the documentation problem, but also drastically improves the process of design, governance, end to end testing, chaos testing, and all sorts of operational challenges like monitoring and health checks.

## Documentation Benefits

An API client needs to do a thing: book a ticket, onboard a user, move an order from "draft" to "paid", or recover when something fails halfway through.

There probably is not a `POST /moveOrderFromDraftToPaid` endpoint (and if there is there shouldn't be). Instead there are a series of steps that need to be taken in order, with data flowing from one step to the next, and various failure modes that need to be handled along the way.

Arazzo can be used to capture the journey step-by-step, with the same kind of clarity OpenAPI brought to individual operations. When you write a workflow with good descriptions and sensible outputs, you've effectively created a living "how to use this API" guide that tools can render, validate, and even execute.

Here's what that kind of story looks like, at a high level:

```mermaid
sequenceDiagram
autonumber
participant Client
participant API

Client->>API: Search trips
API-->>Client: trips[] (includes tripId)
Client->>API: Create booking (tripId)
API-->>Client: bookingId
Client->>API: Pay for booking (bookingId)
API-->>Client: confirmation + ticket
```

And here's the same idea expressed as an Arazzo workflow snippet. Ignore the syntax of some of the runtime expressions for now, the key part is how the steps flow together with outputs from one step being used as inputs to the next:

```yaml
workflows:
- workflowId: complete-booking-flow
summary: Test the full booking process
steps:
- stepId: search
operationId: search-trips
successCriteria:
- condition: $statusCode == 200
- condition: $response.body.trips.length > 0
outputs:
tripId: $response.body#/trips/0/id

- stepId: book
operationId: create-booking
requestBody:
payload:
tripId: $steps.search.outputs.tripId
successCriteria:
- condition: $statusCode == 201
- condition: $response.body.status == 'confirmed'
```

If you've ever maintained getting started documentation, you'll know the pain: they're the first thing users read and the first thing that goes stale. Arazzo helps because you can treat workflows as the canonical version of those journeys, then generate docs and examples from the same source.

Common workflows could involve:

- log in
- getting a user id number
- using that user id to find resources
- creating new resources
- knowing if that worked or failed

It seems like it should be pretty standard stuff, but every API is different and these journeys are often surprisingly confusing to navigate without clear documentation that's definitely up-to-date.

## Testing Benefits

Once workflows are written down in a machine-readable format, testing stops being a separate project. The workflow itself becomes the test: run it against staging in CI, run it as a smoke test before deploy, or run it periodically as monitoring.

Where Arazzo gets especially interesting is state. Many APIs behave like state machines, but they're documented as if every request is independent. Arazzo gives you a place to express state transitions as something deliberate and testable.

Here's the idea in the abstract:

```mermaid
stateDiagram-v2
[*] --> draft
draft --> submitted: submit
submitted --> processing: pay
processing --> shipped: ship
shipped --> delivered: confirmDelivery
delivered --> [*]

draft --> cancelled: cancel
submitted --> cancelled: cancel
processing --> cancelled: cancel
```

And here's what that looks like when you're checking the transitions with actual API calls:

```yaml
workflows:
- workflowId: order-lifecycle
summary: Complete lifecycle of an order from draft to delivered

steps:
- stepId: createDraft
description: Create order in draft state
operationId: createOrder
successCriteria:
- condition: $response.body.state == 'draft'

- stepId: submitOrder
description: Transition from draft to submitted
operationId: submitOrder
parameters:
- name: orderId
value: $steps.createDraft.outputs.orderId
successCriteria:
- condition: $response.body.state == 'submitted'

- stepId: processPayment
description: Process payment, moving to processing state
operationId: processPayment
successCriteria:
- condition: $response.body.state == 'processing'
- condition: $response.body.paymentStatus == 'paid'

- stepId: ship
description: Ship the order
operationId: shipOrder
successCriteria:
- condition: $response.body.state == 'shipped'

- stepId: confirmDelivery
description: Final state transition to delivered
operationId: confirmDelivery
successCriteria:
- condition: $response.body.state == 'delivered'
```

Instead of being locked away in some cloud testing environment or hidden QA repository for only a select few to see, the criteria for success and failure become easily visible and knowable to everyone.

New team members can read the workflow and understand the valid transitions. QA can execute the same workflow as an end-to-end test. When a rule is changed (say you add a "refunded" state), you update one workflow and let tooling catch the places that no longer match. This can be done along with the code changes in a single pull request, making reviews and validation much simpler.

You can also handle real-world edge cases without turning your docs into a wall of prose. For example: "cancel is allowed in three states, but if it's already shipped you need to start a refund flow instead".

```yaml
- stepId: cancelOrder
description: Cancel order - allowed from draft, submitted, or processing states
operationId: cancelOrder
successCriteria:
- condition: $statusCode == 200
- condition: $response.body.state == 'cancelled'

# This step can be reached from multiple prior states
dependsOn:
- createDraft
- submitOrder
- processPayment

# Only execute if certain conditions are met
onFailure:
- name: orderAlreadyShipped
type: goto
stepId: refundProcess
criteria:
- condition: $response.body.reason == 'ORDER_SHIPPED'
```

## Design, Governance, and Operations

Once you've got a handful of core workflows, they naturally become a contract for how the API should be used. That helps during design reviews. Can a customer actually complete checkout with this API? Did a recent change break a critical journey?

Operationally, workflows are useful as smoke tests and as synthetic monitoring. This is different from a classic "is the service up?" health check: you're not trying to prove the database is reachable, you're trying to prove the product still works.

If the "signup → create resource → view resource" journey is broken, the API might still be returning 200s all day long, but users are stuck. Arazzo lets you encode that journey once and run it on a schedule (either on a testing environment, sandbox, or production if you're careful).

Here's a compact example of a synthetic canary workflow you might run in CI or periodically in a monitoring job:

```yaml
workflows:
- workflowId: canary-happy-path
summary: Validate a critical user journey end-to-end
steps:
- stepId: authenticate
operationId: getToken
- stepId: createResource
operationId: createItem
- stepId: readBack
operationId: getItem
- stepId: cleanup
operationId: deleteItem
```

Even if you never generate a fancy visualization as documentation, the day-to-day payoff is simple: onboarding is faster when people can run the workflow and watch it work; integration is smoother when the happy path is explicit; and breakages are easier to spot because failures show up as a specific step, with a specific condition that didn't match.

## Cross-API Orchestration

While OpenAPI describes a single API, Arazzo can orchestrate across multiple APIs by referencing multiple source descriptions. This is especially useful for documenting and testing business processes that span different APIs or services.

```yaml
sourceDescriptions:
- name: paymentApi
url: ./payment-api.yaml
- name: inventoryApi
url: ./inventory-api.yaml
- name: shippingApi
url: ./shipping-api.yaml

workflows:
- workflowId: complete-order
steps:
- stepId: reserveInventory
operationId: $sourceDescriptions.inventoryApi.reserve

- stepId: processPayment
operationId: $sourceDescriptions.paymentApi.charge

- stepId: scheduleShipping
operationId: $sourceDescriptions.shippingApi.schedule
onFailure:
- name: releaseInventory
type: goto
stepId: rollbackInventory
```

Notice the difference in `operationId` syntax. Instead of referencing just the `operationId` (e.g.; `reserve`), a longer runtime expression is used which references the API in the context of its source: `$sourceDescriptions.inventoryApi.reserve`.

This is where Arazzo starts to feel more like CI/CD workflows, but for business journeys. Stitching together operations that live in different services, passing data between them, and defining what "success" means for the whole sequence in a single source of truth.

## Business Value

Beyond making sure an API ecosystem is actually functioning properly (with fewer partial sources of truth to disagree with each other) most of the business value is second-order effects.

- Properly documented flows lead to fewer support requests from confused client developers struggling to integrate.
- Reduced chances of AI agents flailing around hallucinating incorrect API usage.
- More confidence when you ship changes because you can run the same workflows as regression tests.
- All of that saves time and money.
57 changes: 57 additions & 0 deletions src/_guides/arazzo/specification/v1.0/introduction/history.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: History and Evolution of Arazzo
authors: phil
excerpt: Learn about the origins of Arazzo, from early workflow experiments to becoming an official OpenAPI Initiative standard for API workflow descriptions.
date: 2025-01-24
---

- TOC
{:toc}

The Arazzo Specification represents years of evolution in API workflow documentation, emerging from real-world needs and community collaboration to become an official standard under the OpenAPI Initiative.

## The Birth of Arazzo

The first time Arazzo came up was on an OpenAPI community call somewhere in late 2021 where a bunch of the usual OpenAPI contributors were discussing the Special Interest Groups that could be formed under the OpenAPI Initiative. Along with groups for Overlays, Security, Travel, etc. one of the groups was Workflows. The idea was to explore how to standardize the way API workflows were defined.

There had been some loose atempts to do this with OpenAPI's `Links` where one operation can point to next potential steps, but this was not being utilized much and seemed problematic for trying to document complex workflows across multiple APIs.

Popular open-source tools like [Strest](https://github.com/eykrehbein/strest) immediately jumped to mind for many of us, and there was more inspiration pulled from all sorts of similar concepts:

- GitHub Actions and other CI/CD workflow formats (steps, conditions, outputs).
- State machine concepts from computer science.
- Real-world API integration patterns observed in the field.

Generally the folks involved were well used to working with these sorts of tools, building and maintaining these sorts of tools, and had seen the pain points of trying to document workflows in written guides or sample codebases that quickly became outdated, so everyone got some good ideas into the mix.

In 2022 a formal proposal was drafted and presented to the OpenAPI Initiative, and a working group was formed to develop the specification further. This group included API designers, technical writers, tool developers, and other stakeholders who contributed their expertise to shape the emerging standard.

The specification was initially called "OpenAPI Workflows" but was later renamed to **Arazzo** to give it a distinct identity while maintaining its connection to the OpenAPI ecosystem. The name "Arazzo" (Italian for "tapestry") reflects how workflows weave together multiple API calls into a cohesive pattern.

### Version 1.0 Release (2024)

After extensive community review, tooling experiments, and real-world testing, Arazzo 1.0.0 was officially released in 2024 as a standard under the OpenAPI Initiative. This first version includes:

- **Core workflow structure** - Documents, workflows, and steps
- **Source descriptions** - Referencing OpenAPI and other API definitions
- **Runtime expressions** - Passing data between steps
- **Success and failure criteria** - Defining what constitutes success or failure
- **Parameters and request bodies** - Overriding or supplementing source definitions
- **Components and reusability** - Reducing duplication through references
- **Outputs** - Capturing and passing results between steps

## Adoption and Ecosystem

Arazzo has seen growing interest across the API community with most tooling vendors busily working on adding support, with the first two being Spectral and Speakeasy. The list of Arazzo-compatible tools continues to grow, and for the most up-to-date list check [OpenAPI.Tools: Arazzo](https://openapi.tools/collections/arazzo).

## The Future

Arazzo 1.1 is already underway with non-breaking improvements potentially including:

- Support for JSONPath as well as JSON Pointer and XPath.
- Supporting AsyncAPI for event-driven workflows.
- Allow workflow inputs to be passed in success and failure actions.

These iterative improvements aim to bring more flexibility and power to the specification while maintaining backward compatibility, whilst larger improvements are already being planned for a longer term Arazzo 2.0 release.

If you're interested in contributing or learning more, check out the [Arazzo GitHub repository](https://github.com/OAI/Arazzo-Specification/).
Loading
Loading