Engineering

The Workflow DSL Explained: task, assert, if, loop, parallel

Michael Rodriguez||6 min
+Z

You want an agent that plans, retries, and branches. Browser forms, terminal commands, and desktop apps change every day. Hard-coded selectors break. Write a versioned workflow as a JSON DSL instead. The server runs the workflow against a real machine, calling /v1/runs for each task step and handling retries, parallelism, and human approval for you.

How the workflow DSL works

POST /v1/workflows creates a workflow. The payload is a versioned JSON object. Each step is an object with a type field and step-specific fields. The DSL controls flow, state, and error handling. The server executes steps in order unless a condition or loop redirects flow. Parallel steps run concurrently. Each task step is billed $0.05. The workflow can include budget_cents, max_iterations, and deadline_seconds as hard guards.

bash
curl -X POST https://coasty.ai/v1/workflows \
  -H "Authorization: Bearer $COASTY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "version": "1.0",
    "steps": [
      {
        "type": "task",
        "id": "open_browser",
        "task": "Open Chrome and navigate to https://example.com",
        "max_steps": 10
      },
      {
        "type": "assert",
        "id": "title_check",
        "assert_type": "text",
        "selector": "title",
        "expected": "Example Domain",
        "timeout_ms": 5000
      },
      {
        "type": "if",
        "id": "check_available",
        "condition": {
          "field": "available",
          "operator": "==",
          "value": true
        },
        "then": [
          {
            "type": "task",
            "id": "book_ticket",
            "task": "Click Book and confirm",
            "max_steps": 15
          }
        ],
        "else": [
          {
            "type": "task",
            "id": "notify_unavailable",
            "task": "Notify user that the item is unavailable",
            "max_steps": 5
          }
        ]
      },
      {
        "type": "loop",
        "id": "fetch_updates",
        "condition": {
          "field": "iterations",
          "operator": "<",
          "value": 5
        },
        "steps": [
          {
            "type": "task",
            "id": "refresh_page",
            "task": "Refresh the page",
            "max_steps": 8
          },
          {
            "type": "assert",
            "id": "new_price",
            "assert_type": "text",
            "selector": "price",
            "expected": "< 100"
          }
        ]
      },
      {
        "type": "parallel",
        "id": "parallel_actions",
        "steps": [
          {
            "type": "task",
            "id": "download_report",
            "task": "Download the PDF report",
            "max_steps": 12
          },
          {
            "type": "task",
            "id": "send_email",
            "task": "Send the report to the team",
            "max_steps": 10
          }
        ]
      }
    ],
    "budget_cents": 500,
    "max_iterations": 20,
    "deadline_seconds": 600
  }'

Step types and fields

  • task: Executes a human-like action. Required fields include id, task, and max_steps. The server calls /v1/runs for each task step. Billed $0.05 per step.
  • assert: Validates state. Assert types include text, exists, and attribute. Fields: id, assert_type, selector, expected, timeout_ms. Fails the workflow if the assertion does not hold.
  • if: Conditionally branches. Condition is an object with field, operator, and value. Then and else contain step arrays. Flow continues to the next sibling after the if block.
  • loop: Repeats steps while a condition holds. Condition uses iterations or a field comparison. Steps array can include task and assert steps. Loop ends when condition is false or max_iterations is reached.
  • parallel: Runs multiple steps concurrently. Each step can be task or assert. The server waits for all parallel branches to complete before continuing.

Each task step is billed $0.05. Use budget_cents and max_iterations as hard guards to prevent runaway costs.

Where this beats brittle automation

Traditional automation relies on stable selectors and API endpoints. UI changes, layout shifts, and dynamic content break scripts. Coasty's workflow DSL uses a computer use agent that sees the screen and acts like a human. It can navigate, fill forms, and adapt to unexpected states. Parallel steps let you speed up multi-step workflows. If blocks and loops let you handle conditional logic and retries without rewriting code. The runtime manages state, retries, and human approval so you focus on the DSL.

Start building stateful, branching workflows with the Coasty workflow DSL. Define tasks, asserts, if, loop, and parallel steps in JSON. The server handles execution, retries, and parallelism against real machines. Get a key at https://coasty.ai/developers and try the example above.

Want to see this in action?

View Case Studies
Try Coasty Free