DEV Community

Alex Spinov
Alex Spinov

Posted on

Windmill Has a Free API: Open-Source Alternative to Retool and Zapier for Developer Workflows

What is Windmill?

Windmill is an open-source developer platform that combines internal tools (like Retool), workflow automation (like Zapier/n8n), and job scheduling — all powered by scripts in TypeScript, Python, Go, Bash, or SQL.

Self-host for free. Unlimited users, unlimited executions.

Quick Start

docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Or use the CLI:

pip install windmill-cli
wmill init
Enter fullscreen mode Exit fullscreen mode

Scripts (Building Blocks)

// TypeScript script
export async function main(name: string, count: number = 5) {
  const results = [];
  for (let i = 0; i < count; i++) {
    const res = await fetch(`https://api.example.com/data?name=${name}&page=${i}`);
    results.push(await res.json());
  }
  return results;
}
Enter fullscreen mode Exit fullscreen mode
# Python script
def main(url: str, timeout: int = 30):
    import requests
    response = requests.get(url, timeout=timeout)
    return {"status": response.status_code, "data": response.json()}
Enter fullscreen mode Exit fullscreen mode

Every script is an API endpoint:

curl -X POST "https://your-windmill.com/api/w/workspace/jobs/run/p/f/folder/script" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"name": "test", "count": 3}'
Enter fullscreen mode Exit fullscreen mode

Flows (Workflows)

summary: "Process New Orders"
value:
  modules:
    - id: fetch_orders
      value:
        type: script
        path: f/orders/fetch_new
    - id: process
      value:
        type: forloopflow
        iterator:
          type: javascript
          expr: results.fetch_orders
        modules:
          - id: validate
            value:
              type: script
              path: f/orders/validate
          - id: notify
            value:
              type: script
              path: f/notifications/send_slack
              input_transforms:
                message:
                  type: javascript
                  expr: "`Order ${flow_input.iter.value.id} processed`"
Enter fullscreen mode Exit fullscreen mode

The REST API

export WM_URL="https://your-windmill.com/api"
export WM_TOKEN="your-token"
Enter fullscreen mode Exit fullscreen mode

Run Scripts

# Run script and get result
curl -X POST "$WM_URL/w/workspace/jobs/run_wait_result/p/f/my/script" \
  -H "Authorization: Bearer $WM_TOKEN" \
  -d '{"param1": "value1"}'

# Run async
curl -X POST "$WM_URL/w/workspace/jobs/run/p/f/my/script" \
  -H "Authorization: Bearer $WM_TOKEN" \
  -d '{"param1": "value1"}'
# Returns job UUID

# Check job status
curl "$WM_URL/w/workspace/jobs/get/JOB_UUID" \
  -H "Authorization: Bearer $WM_TOKEN" | jq '{type, success}'

# Get job result
curl "$WM_URL/w/workspace/jobs/completed/get_result/JOB_UUID" \
  -H "Authorization: Bearer $WM_TOKEN"
Enter fullscreen mode Exit fullscreen mode

Schedules

# Create cron schedule
curl -X POST "$WM_URL/w/workspace/schedules/create" \
  -H "Authorization: Bearer $WM_TOKEN" \
  -d '{
    "path": "f/my/script",
    "schedule": "0 */6 * * *",
    "args": {"param1": "value1"},
    "enabled": true
  }'
Enter fullscreen mode Exit fullscreen mode

App Builder (Internal Tools)

Build UIs that connect to your scripts:

{
  "type": "table",
  "data": {
    "type": "runnableByPath",
    "path": "f/data/get_users"
  },
  "columns": [
    {"key": "name", "header": "Name"},
    {"key": "email", "header": "Email"},
    {"key": "plan", "header": "Plan"}
  ]
}
Enter fullscreen mode Exit fullscreen mode

Drag-and-drop tables, forms, charts — connected to your scripts and flows.

Windmill vs Alternatives

Feature Windmill Retool n8n Zapier
Open source Yes No Yes No
Code-first Yes Low-code Low-code No-code
Languages TS/Py/Go/SQL JS JS None
Self-host Yes Enterprise Yes No
Free (self) Unlimited N/A Unlimited N/A

Need workflow automation or internal tools?

📧 spinov001@gmail.com
🔧 My tools on Apify Store

Code-first or no-code for automation? Share your take!

Top comments (0)