DEV Community

Alex Spinov
Alex Spinov

Posted on

Windmill Has a Free API — Here's How to Build Internal Tools and Workflows 10x Faster

An ops engineer told me: 'We had 200 internal scripts scattered across cron jobs, Lambda functions, and random VMs. Nobody knew which ones were still running or who owned them.' Windmill solved this — all scripts in one place with a UI, scheduling, and approvals.

What Windmill Offers for Free

Windmill self-hosted (free forever):

  • Unlimited users, scripts, and executions
  • Script editor — TypeScript, Python, Go, Bash, SQL, GraphQL
  • Workflow builder — visual DAG editor
  • App builder — drag-and-drop internal tools
  • Scheduling — cron with retry and error handling
  • Approval flows — human-in-the-loop workflows
  • REST API — manage everything programmatically
  • Auto-generated UIs — scripts become forms automatically

Windmill Cloud free tier: 1,000 executions/month.

Quick Start

# Self-hosted via Docker
git clone https://github.com/windmill-labs/windmill.git
cd windmill/docker
docker compose up -d
# Access at http://localhost:8000
Enter fullscreen mode Exit fullscreen mode

Write a Script (Auto-Gets a UI)

# main.py — This becomes an internal tool automatically!
# Windmill generates a form UI from the type annotations

def main(
    customer_email: str,
    discount_percent: int = 10,
    reason: str = "loyalty",
    notify_slack: bool = True
):
    """Apply a discount to a customer's next invoice."""

    # Apply discount in Stripe
    import stripe
    stripe.api_key = os.environ["STRIPE_API_KEY"]

    customer = stripe.Customer.list(email=customer_email).data[0]
    coupon = stripe.Coupon.create(percent_off=discount_percent, duration="once")
    stripe.Customer.modify(customer.id, coupon=coupon.id)

    if notify_slack:
        # Post to Slack
        requests.post(os.environ["SLACK_WEBHOOK"], json={
            "text": f"Applied {discount_percent}% discount to {customer_email} ({reason})"
        })

    return {"customer": customer_email, "discount": f"{discount_percent}%", "status": "applied"}
Enter fullscreen mode Exit fullscreen mode

REST API

# Run a script
curl -X POST 'http://localhost:8000/api/w/workspace/jobs/run/p/f/folder/script_name' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"customer_email": "alice@example.com", "discount_percent": 15}'

# Get job result
curl 'http://localhost:8000/api/w/workspace/jobs/completed/get/JOB_ID' \
  -H 'Authorization: Bearer YOUR_TOKEN'

# List scripts
curl 'http://localhost:8000/api/w/workspace/scripts/list' \
  -H 'Authorization: Bearer YOUR_TOKEN'

# Create a schedule
curl -X POST 'http://localhost:8000/api/w/workspace/schedules/create' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "path": "f/ops/daily_report",
    "schedule": "0 9 * * *",
    "args": {"channel": "#reports"}
  }'
Enter fullscreen mode Exit fullscreen mode

Approval Flows

# Workflow step that pauses for human approval
import wmill

def main(amount: float, vendor: str):
    if amount > 1000:
        # Pause workflow — sends approval request to manager
        wmill.set_resume(
            "Approve purchase of ${amount} from {vendor}?",
            approvers=["manager@company.com"]
        )
        # Workflow pauses here until approved

    # Continue with purchase order...
    return {"po_number": "PO-2026-001", "amount": amount}
Enter fullscreen mode Exit fullscreen mode

Build Internal Tools (No Frontend Code)

Windmill's app builder creates UIs from your scripts:

  • Tables with filtering, sorting, pagination
  • Forms that map to script inputs
  • Charts and dashboards
  • Buttons that trigger workflows
  • Conditional visibility

Windmill vs Retool / n8n

Windmill Retool n8n
Code-first UI-first Visual-first
Auto-generated UI Build UI manually No UI builder
Free self-hosted $10/user/month Free self-hosted
TypeScript/Python/Go JS only Visual + JS
Approval flows Enterprise only No approvals

Need to automate data collection? Check out my web scraping actors on Apify — connect to Windmill for end-to-end automation.

Need custom internal tools? Email me at spinov001@gmail.com.

Top comments (0)