Skip to content

Writing Routines

Garret Premo edited this page Apr 23, 2026 · 5 revisions

Writing Routines

Routines are YAML-based workflow definitions that chain CLI commands with variables, conditions, loops, assertions, and sub-routines. They live in ~/.<cli>/routines/ (or .apijack/routines/ in project mode).

Use routines to automate repetitive API workflows, set up test data, run integration tests, and build multi-step operations out of simple CLI commands.

On this page

Coming from a single big "Writing Routines" page? The content has been split into focused pages (Variables, Output, Conditions & Assertions, Loops, Error Handling, Sub-routines) — see Routine authoring topics below.

Basic structure

A routine needs a name and at least one step:

name: list-all-pets
description: List every pet in the system
steps:
  - name: get-pets
    command: pets list

Each step has a name (required) and a command that maps to a CLI command path. description: is optional but recommended.

Discovering commands

Use -o routine-step on any CLI command to get a copy-pasteable step definition:

petstore pets create-pet --name Buddy --species dog --age 3 -o routine-step

Outputs:

- name: create-pet
  command: pets create-pet
  args:
    --name: "Buddy"
    --species: "dog"
    --age: "3"
    # --status: "" # optional -- Pet status

This is the fastest way to build routines. See Command Discovery for more.

Running a step

Flags with args:

args: is a map of flags to values. Flags use the same --name format as the CLI:

- name: create-pet
  command: pets create-pet
  args:
    --name: "Buddy"
    --species: "dog"
    --age: 3
    --vaccinated: true

Values can be strings, numbers, or booleans.

Positional arguments with args-positional:

For commands that take positional arguments (typically resource IDs):

- name: get-pet
  command: pets get
  args-positional:
    - 1

This is equivalent to petstore pets get 1. args: and args-positional: can be combined:

- name: update-pet
  command: pets update
  args-positional:
    - "$pet.id"
  args:
    --name: "New Name"

Routine authoring topics

Rather than one monolithic page, the authoring guide is split by concept. Start anywhere:

Page When to read
Routine Variables Declaring variables, --set overrides, built-in resolvers ($_uuid, $_env, $_find, $_random_*)
Routine Output Capture output: aliases, nested $a.b.c field access, the .success boolean
Routine Conditions & Assertions Branching steps with condition:, validating results with assert:
Routine Loops forEach, range, shuffle, reverse — with six worked examples
Routine Error Handling continueOnError: on steps and loop blocks
Sub-Routines & Meta-Commands Calling routines from routines, wait-until, session refresh

For the full field-by-field reference, see Routine YAML Schema.

A full example

A multi-step Petstore routine that creates an owner, creates pets, adopts them all, verifies the adoptions, and cleans up — a concrete example that touches most of the features covered above.

name: full-lifecycle
description: Create owner and pets, adopt all pets, verify, then clean up
variables:
  owner_name: "Test Owner"
  owner_email: "test-$_timestamp@example.com"

steps:
  # Create an owner
  - name: create-owner
    command: owners create
    args:
      --name: "$owner_name"
      --email: "$owner_email"
    output: owner

  # Create pets using a range loop with distinct random species
  - name: create-pets
    range: [1, 3]
    as: "i"
    steps:
      - name: create-pet
        command: pets create-pet
        args:
          --name: "Pet-$i"
          --species: "$_random_distinct_from(dog,cat,bird)"
          --age: "$_random_int(1,10)"
        output: pet

  # List available pets
  - name: list-available
    command: pets list
    args:
      --status: "available"
    output: available_pets

  # Adopt all available pets
  - name: adopt-all
    forEach: "$available_pets"
    as: "pet"
    steps:
      - name: adopt-pet
        command: pets adopt-pet
        args-positional:
          - "$pet.id"
        args:
          --ownerId: "$owner.id"

  # Verify adoptions
  - name: verify-owner
    command: owners get
    args-positional:
      - "$owner.id"
    output: owner_detail

  - name: verify-pets-adopted
    forEach: "$owner_detail.pets"
    as: "adopted_pet"
    steps:
      - name: check-status
        command: pets get
        args-positional:
          - "$adopted_pet.id"
        assert: "$check-status.status == adopted"

  # Best-effort cleanup
  - name: cleanup-pets
    forEach: "$owner_detail.pets"
    as: "pet"
    continueOnError: true
    steps:
      - name: delete-pet
        command: pets delete
        args-positional:
          - "$pet.id"

  - name: cleanup-owner
    command: owners delete
    args-positional:
      - "$owner.id"
    continueOnError: true

Run it:

petstore routine run full-lifecycle

Override variables:

petstore routine run full-lifecycle --set owner_name="QA Owner"

Preview without executing:

petstore routine run full-lifecycle --dry-run

Running and validating routines

Command What it does
routine list Show available routines
routine list --tree Show the full tree (useful when sub-routines compose)
routine run <name> Execute a routine
routine run <name> --set key=value Override declared variables
routine run <name> --dry-run Print each step's resolved command without calling the API
routine validate <name> Check YAML structure before running
routine test <name> Run the routine's spec/test file — see Routine Testing

For the full CLI reference, see CLI Command Reference.

Clone this wiki locally