arazzo-writer
Arazzo Workflow Authoring Skill
Overview
Arazzo describes end-to-end API workflows: ordered steps, shared data, assertions, and branching. Use this skill for API testing scenarios, integration guides, or automation flows as reusable YAML documents that complement OpenAPI specs.
SUCCESS CRITERIA (MANDATORY)
An Arazzo file is ONLY considered complete when ALL three checks pass. Do not mark the task as done until all three succeed.
Check 1: File Exists
# Verify the .arazzo.yaml file was created
ls -la path/to/workflow.arazzo.yaml # Linux/macOS
dir path\to\workflow.arazzo.yaml # Windows
PASS: File exists with content (size > 0 bytes) FAIL: File not found or empty - create/write the file first
Check 2: YAML Syntax Valid
# Python (preferred)
python -c "import yaml; yaml.safe_load(open('path/to/workflow.arazzo.yaml'))"
# Node.js alternative
node -e "require('js-yaml').load(require('fs').readFileSync('path/to/workflow.arazzo.yaml', 'utf8'))"
PASS: No output (silent success, exit code 0) FAIL: YAML syntax error - fix indentation, quotes, colons, or structure
Check 3: OpenAPI Arazzo CLI Validation
# Validate with the openapi CLI
openapi arazzo validate path/to/workflow.arazzo.yaml
PASS: Exit code 0, no error messages printed FAIL: Fix ALL reported errors and re-run until it passes
Validation Workflow Summary
1. Create/edit the .arazzo.yaml file
2. Run file exists check (ls/dir)
3. Run YAML syntax check (python/node)
4. Run: openapi arazzo validate <file>
5. If any check fails, fix and re-run from that check
6. ONLY mark task complete when check 3 passes with ZERO errors
Reference Files
For detailed syntax and error solutions:
- Runtime expressions - all
$prefixes, JSONPath, outputs - Validation + tooling - CLI install, error fixes
Document Structure
arazzo: 1.0.1
info:
title: My Workflow Suite
version: 0.1.0
sourceDescriptions:
- name: myApi
url: ./openapi.yaml # or http://localhost:3000/swagger.json
type: openapi
workflows:
- workflowId: myWorkflow
steps: [...]
outputs:
result: $steps.lastStep.outputs.value
Quick Reference
Workflow Fields
workflowId (required, unique), summary, inputs (JSON Schema), steps (required), outputs, dependsOn, parameters, successActions, failureActions
Step Fields
| Field | Notes |
|---|---|
stepId |
Required, unique per workflow |
operationId / operationPath / workflowId |
Exactly ONE required |
parameters |
Must include in for API calls |
requestBody |
contentType, payload, replacements |
successCriteria |
Assertions (ANDed together) |
outputs |
Runtime expressions only (must start with $) |
Critical Syntax Rules
operationPath Format
"{$sourceDescriptions.<name>.url}#/paths/~1<escaped-path>/<method>"
Path Escaping: / becomes ~1, ~ becomes ~0
# /api/users -> POST
operationPath: "{$sourceDescriptions.myApi.url}#/paths/~1api~1users/post"
# /articles/{slug} -> GET
operationPath: "{$sourceDescriptions.myApi.url}#/paths/~1articles~1{slug}/get"
parameters:
- name: slug
in: path
value: $steps.create.outputs.slug
Common operationPath Errors:
# WRONG - missing json pointer
operationPath: "{$sourceDescriptions.api.url}/users"
# WRONG - using .name instead of .url
operationPath: "{$sourceDescriptions.api.name}#/paths/~1users/get"
# CORRECT
operationPath: "{$sourceDescriptions.api.url}#/paths/~1users/get"
JSONPath Syntax (RFC 9535)
Filter expressions must use: $[?(@.field op value)]
# WRONG - will cause validation errors
condition: $.user != null
condition: @.user != null
condition: $[?@.user != null]
# CORRECT
condition: $[?(@.user != null)]
condition: $[?(@.count >= 1)]
condition: $[?(@.status == 'active')]
condition: $[?(@.slug == $steps.create.outputs.slug)]
Output Values
Outputs must be runtime expressions starting with $. No literals allowed.
# WRONG - will fail validation
outputs:
success: true
valid: $statusCode == 200
message: "completed"
# CORRECT
outputs:
userId: $response.body#/user/id
status: $statusCode
location: $response.header.Location
Common Patterns
Success Criteria
successCriteria:
- condition: $statusCode == 200
- context: $response.body
type: jsonpath
condition: $[?(@.user != null)]
Failure Actions (Retry)
failureActions:
- name: retryOnRateLimit
type: retry
retryAfter: 5
retryLimit: 3
criteria:
- condition: $statusCode == 429
Request Body
requestBody:
contentType: application/json
payload:
user:
email: "{$inputs.email}"
# Or use replacements:
replacements:
- target: /user/id
value: $steps.create.outputs.userId
Data Flow Between Steps
# Step A exposes data
- stepId: createUser
outputs:
userId: $response.body#/id
# Step B consumes it
- stepId: getUser
parameters:
- name: id
in: path
value: $steps.createUser.outputs.userId
Reusable Components
components:
parameters:
authHeader:
name: Authorization
in: header
value: "Bearer {$inputs.token}"
# Reference in steps:
parameters:
- reference: $components.parameters.authHeader
Common Validation Errors
| Error | Fix |
|---|---|
operationPath must contain a json pointer |
Use #/paths/~1<path>/<method> format |
operationPath must reference the url |
Use .url not .name |
invalid jsonpath expression |
Use $[?(@.field op value)] format |
expression must begin with $ |
Outputs can't be literals like true |
parameter missing 'in' |
Add in: path/query/header/cookie |
exactly one of operationId, operationPath, workflowId |
Use only ONE per step |
missing required property: info |
Add info.title and info.version |
reference could not be resolved |
Check operationId/workflowId spelling |
Writing Process
- Define
sourceDescriptionspointing to OpenAPI spec(s) - Create workflow with
workflowIdandinputsschema - Add steps with
operationPathoroperationId - Define
successCriteriaassertions per step - Wire data via
outputsand$steps.X.outputs.Y - Add error handling with
failureActions - Run Check 1: Verify file exists
- Run Check 2: YAML syntax validation
- Run Check 3:
openapi arazzo validate - Fix any errors and repeat checks until all pass
Working Without an OpenAPI Spec
# Option 1: Minimal local spec
sourceDescriptions:
- name: myApi
url: ./minimal-api.openapi.yaml
type: openapi
# Option 2: Runtime swagger endpoint
sourceDescriptions:
- name: myApi
url: http://localhost:3000/swagger.json
type: openapi
References
- Runtime expressions - full syntax reference
- Validation guide - CLI setup, error solutions
- Official spec
- Examples