DEV Community

Alex Spinov
Alex Spinov

Posted on

Windmill Has a Free API That Turns Scripts Into Internal Tools and Workflows

Windmill is the open-source platform that turns your scripts into internal tools, workflows, and scheduled jobs. Write TypeScript/Python/Go, get a UI and API automatically.

What Is Windmill?

Windmill takes your scripts and generates: auto-generated UIs, REST API endpoints, approval flows, scheduled jobs, and webhook handlers.

Quick Start

# Docker Compose
docker compose up -d
# Open http://localhost:8000
Enter fullscreen mode Exit fullscreen mode

Write a Script

// Windmill auto-generates a form UI from the function signature
export async function main(
  customer_id: string,
  start_date: string,
  end_date: string,
  include_refunds: boolean = false
) {
  const orders = await getOrders(customer_id, start_date, end_date)
  const filtered = include_refunds ? orders : orders.filter(o => o.status !== 'refunded')

  return {
    customer_id,
    total_orders: filtered.length,
    total_revenue: filtered.reduce((sum, o) => sum + o.amount, 0),
    orders: filtered,
  }
}
Enter fullscreen mode Exit fullscreen mode

This automatically gets a web form with inputs for each parameter, plus a REST API endpoint.

Workflows (DAG)

// Step 1: Fetch data
export async function fetchUsers() {
  const resp = await fetch('https://api.example.com/users')
  return resp.json()
}

// Step 2: Process (runs after step 1)
export async function processUsers(users: User[]) {
  return users.filter(u => u.active).map(u => ({ ...u, score: calculateScore(u) }))
}

// Step 3: Send notifications (runs after step 2)
export async function notifyUsers(processed: ProcessedUser[]) {
  for (const user of processed) {
    if (user.score > 80) {
      await sendEmail(user.email, 'You are a top user!')
    }
  }
  return { notified: processed.filter(u => u.score > 80).length }
}
Enter fullscreen mode Exit fullscreen mode

REST API

export WINDMILL_TOKEN="your-token"

# Run a script
curl -s -X POST 'http://localhost:8000/api/w/main/jobs/run_wait_result/p/f/scripts/my_script' \
  -H "Authorization: Bearer $WINDMILL_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"customer_id": "cust-123", "start_date": "2026-01-01", "end_date": "2026-03-30"}'

# Run a flow/workflow
curl -s -X POST 'http://localhost:8000/api/w/main/jobs/run_wait_result/p/f/flows/my_workflow' \
  -H "Authorization: Bearer $WINDMILL_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"trigger": "manual"}'

# Schedule a job (cron)
curl -s -X POST 'http://localhost:8000/api/w/main/schedules/create' \
  -H "Authorization: Bearer $WINDMILL_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"path": "f/scripts/daily_report", "schedule": "0 9 * * *", "timezone": "UTC"}'
Enter fullscreen mode Exit fullscreen mode

Supported Languages

  • TypeScript/JavaScript (Deno runtime)
  • Python 3
  • Go
  • Bash
  • SQL (direct database queries)
  • GraphQL

Free Tier (Self-Hosted)

Feature Community (Free) Pro
Workers Unlimited Unlimited
Scripts Unlimited Unlimited
Users 50 Unlimited
Audit logs No Yes
SAML/SSO No Yes

Windmill vs Alternatives

Feature Windmill n8n Retool
Code-first Yes No-code Low-code
Self-hosted Yes Yes Limited
Auto UI Yes No Manual
Workflows DAG Visual No
Languages TS/Py/Go/Bash JS JS
Open source Yes Fair-code No

Automate web scraping workflows? Scrapfly + Windmill = scheduled data extraction with auto UI. Email spinov001@gmail.com for custom solutions.

Top comments (0)