Category: Developer Tools

Developer resources: scripting, SDKs, API access, webhooks, and debugging.

  • OpenClaw Session Management: How to Keep Long Tasks From Timing Out

    OpenClaw Session Management: How to Keep Long Tasks From Timing Out

    If you’re running OpenClaw for long-running tasks, such as generating large codebases, extensive documentation, or complex datasets, you’ve likely encountered the frustration of sessions timing out. This isn’t just about losing progress; it’s about wasted API credits and the necessity of manually restarting processes, which is particularly irritating if you’re not actively monitoring the server. The default session timeout, often set by the underlying web server or proxy, or even OpenClaw’s own internal defaults, can prematurely terminate a perfectly valid, but slow, generation process.

    Affiliate Disclosure: As an Amazon Associate, we earn from qualifying purchases. This means we may earn a small commission when you click our links and make a purchase on Amazon. This comes at no extra cost to you and helps support our site.

    Understanding the Timeout Problem

    OpenClaw, like many web-based applications, uses HTTP for its API interactions and web UI. When you initiate a long task, the server process might be working diligently in the background, but the HTTP connection itself can be idle for extended periods waiting for the AI model to respond. Load balancers, reverse proxies (like Nginx or Apache), and even the client-side browser or script can interpret this inactivity as a stalled connection and terminate it. On a Hetzner VPS, for example, if you’re using their default Nginx setup, you might hit an upstream timeout or a proxy read timeout.

    The solution isn’t a single magical bullet but a combination of adjustments across your OpenClaw configuration and potentially your server’s proxy settings. We’ll focus on OpenClaw’s internal mechanisms first, as these are often the most direct and overlooked controls.

    Adjusting OpenClaw’s Internal Session Parameters

    OpenClaw provides granular control over its internal session and API interaction timeouts. These are crucial because they dictate how long OpenClaw itself will wait for an API response from the LLM provider before considering the request failed. Even if your proxy is configured correctly, OpenClaw might still time out internally.

    You’ll find these settings in your .openclaw/config.json file. If this file doesn’t exist, create it in your OpenClaw home directory (usually ~/.openclaw/). Here’s an example snippet you might add or modify:

    {
      "api_timeouts": {
        "connect": 10,
        "read": 600,
        "write": 600
      },
      "session_manager": {
        "default_timeout_seconds": 3600,
        "cleanup_interval_seconds": 300
      },
      "generation_defaults": {
        "max_tokens": 8000,
        "temperature": 0.7,
        "timeout_seconds": 1800
      }
    }
    

    Let’s break down these parameters:

    • api_timeouts.connect: The maximum time, in seconds, to wait for a connection to be established with the LLM provider (e.g., OpenAI, Anthropic). A value of 10 seconds is usually sufficient.
    • api_timeouts.read: The maximum time, in seconds, to wait for a response from the LLM provider after a connection has been established. For long tasks, this is critical. Setting it to 600 (10 minutes) or even 1200 (20 minutes) is a good starting point.
    • api_timeouts.write: The maximum time, in seconds, to wait for OpenClaw to send data to the LLM provider. This is less frequently an issue but can be increased if you’re sending massive prompts.
    • session_manager.default_timeout_seconds: This is OpenClaw’s overall session timeout for the web UI. If you’re running tasks via the UI, this prevents the browser session from expiring while the backend task is still running. A value of 3600 (1 hour) is a reasonable maximum for interactive sessions. For purely API-driven tasks, this is less relevant but good practice.
    • session_manager.cleanup_interval_seconds: How often OpenClaw’s session manager cleans up expired sessions. You generally don’t need to change this.
    • generation_defaults.timeout_seconds: This is a task-specific timeout that applies to individual generation calls. Even if api_timeouts.read is high, this can still cut off a generation early. Setting it to 1800 (30 minutes) or more ensures that complex generations have ample time to complete.

    The non-obvious insight here is that api_timeouts.read and generation_defaults.timeout_seconds are often the culprits for long tasks. You might have a high api_timeouts.read, but if generation_defaults.timeout_seconds is still at its default (often 300-600 seconds), your individual generation calls will still fail prematurely. Ensure generation_defaults.timeout_seconds is sufficiently high for your longest expected task.

    Proxy Server Configuration (Nginx Example)

    If you’re running OpenClaw behind a reverse proxy like Nginx (common on VPS setups), you’ll also need to adjust its timeout settings. OpenClaw might be patiently waiting, but Nginx could be cutting off the connection between the client and OpenClaw.

    On a typical Linux system (like Debian/Ubuntu on a Hetzner VPS), your Nginx configuration for OpenClaw might be located at /etc/nginx/sites-available/openclaw.conf or similar. Add or modify the following directives within your location / {} block or server {} block:

    location / {
        proxy_pass http://localhost:8000; # Or wherever OpenClaw is listening
        proxy_read_timeout 1200s;
        proxy_send_timeout 1200s;
        proxy_connect_timeout 60s;
        send_timeout 1200s;
    }
    

    Here’s what these mean:

    • proxy_read_timeout: How long Nginx will wait for a response from OpenClaw after sending a request. This is the most crucial setting for long API calls. Set it to a value like 1200s (20 minutes) or even higher, matching or exceeding your OpenClaw internal timeouts.
    • proxy_send_timeout: How long Nginx will wait to send a request to OpenClaw. Less critical for typical OpenClaw usage.
    • proxy_connect_timeout: How long Nginx will wait to establish a connection to OpenClaw.
    • send_timeout: How long Nginx will wait for a client to accept data. This ensures that slow clients don’t hog connections.

    After modifying your Nginx configuration, you must test and reload Nginx:

    sudo nginx -t
    sudo systemctl reload nginx
    

    Limitations and Considerations

    These adjustments primarily address timeouts due to inactivity or long processing times. They assume your VPS has sufficient resources. If your OpenClaw instance is running on a low-resource machine, like a Raspberry Pi 3 with 1GB RAM, and it’s attempting to generate a 100,000-token codebase, you’ll still encounter problems. The process might get killed by the operating system’s OOM (Out Of Memory) killer long before any timeout occurs. For such heavy tasks, a VPS with at least 2GB RAM is a practical minimum, and 4GB is recommended for comfort.

    Also, these settings don’t protect against network interruptions between your VPS and the LLM provider. If the connection drops completely, the task will still fail, regardless of how high your timeouts are set. For true resilience, consider implementing client-side retry logic or using OpenClaw’s batch processing features that can resume from checkpoints if available.

    Finally, while setting timeouts extremely high (e.g., several hours) might seem like a foolproof solution, it can tie up resources unnecessarily if a task genuinely hangs. Find a balance that accommodates your longest legitimate tasks without preventing genuine failure detection.

    To implement these changes, add the following to your ~/.openclaw/config.json file (or create it if it doesn’t exist):

    {
    "api_timeouts": {
    "connect": 10,
    "read": 1800,
    "write": 600
    },
    "session_manager": {
    "default_timeout_seconds": 7200,
    "cleanup_interval_seconds": 300
    },
    "generation_defaults": {
    "max_tokens": 16000,
    "temperature": 0.7,
    "timeout_seconds": 3600
    }
    }
    Want to script OpenClaw with Python? See how to use the OpenClaw Python SDK for task automation →

  • OpenClaw for Developers: API Access, Webhooks, and Scripting Your Own Tools

    If you’re using OpenClaw to automate parts of your development workflow and find yourself needing more than just the UI, you’ve likely hit the wall of manual intervention. OpenClaw is powerful out of the box, but its true potential for developers lies in programmatic access. This note will walk you through leveraging OpenClaw’s API, setting up webhooks for real-time notifications, and scripting your own tools to integrate OpenClaw into your existing CI/CD pipelines, monitoring systems, or custom dashboards. We’re going to make OpenClaw a silent partner in your backend, not just a browser tab.

    OpenClaw API Access: The Foundation

    The first step to scripting OpenClaw is understanding how to interact with its API. Unlike some tools that hide their API behind complex SDKs, OpenClaw provides a straightforward RESTful interface. To get started, you’ll need an API key. Navigate to your OpenClaw instance, typically at http://localhost:8080, log in, and then go to Settings > API Keys. Generate a new key and make sure to copy it immediately, as it won’t be shown again.

    Most API interactions will require this key in an Authorization header as a Bearer token. Let’s say you want to list all active claws (our term for an automated task definition). You’d use a simple GET request. Here’s a typical curl command:

    
    curl -X GET \
      http://localhost:8080/api/v1/claws \
      -H 'Authorization: Bearer YOUR_API_KEY_HERE' \
      -H 'Content-Type: application/json'
    

    The response will be a JSON array of claw objects, each containing its ID, name, status, and configuration details. This is your entry point for programmatically querying the state of your OpenClaw instance. You can then use these IDs to interact with specific claws, for example, to trigger them:

    
    curl -X POST \
      http://localhost:8080/api/v1/claws/CLAW_ID_HERE/trigger \
      -H 'Authorization: Bearer YOUR_API_KEY_HERE' \
      -H 'Content-Type: application/json' \
      -d '{}'
    

    One non-obvious insight here: while the documentation might suggest creating a new claw for every single ephemeral task, it’s often more efficient for common, repetitive tasks to have a single “template” claw and simply pass different parameters via the API’s trigger endpoint using the -d '{"parameters": {"key": "value"}}' flag. This reduces the overhead of creating and deleting claws dynamically and keeps your OpenClaw instance cleaner. This approach works best for claws that perform similar actions but operate on different data points.

    Webhooks for Real-time Notifications

    Polling the API constantly for status updates is inefficient and can quickly hit rate limits on busy OpenClaw instances. This is where webhooks shine. OpenClaw allows you to configure webhooks to send HTTP POST requests to a specified URL whenever certain events occur, such as a claw completing, failing, or a new task being initiated.

    To set up a webhook, you’ll configure it directly within your OpenClaw instance. Navigate to Settings > Webhooks. Click “Add New Webhook.” You’ll need to provide:

    • URL: The endpoint your application exposes to receive the webhook payload.
    • Secret (Optional): A shared secret to sign the webhook payload, allowing your application to verify the sender’s authenticity. This is crucial for security and should always be used in production environments.
    • Events: A selection of events that will trigger the webhook (e.g., claw.completed, claw.failed, task.started).

    A common use case is integrating OpenClaw task failures with your existing monitoring and alerting stack, like PagerDuty or a custom Slack integration. Instead of writing a script that periodically checks the status of all claws, your webhook endpoint will receive an immediate notification with all the relevant details (claw ID, task ID, error message, etc.) when a claw.failed event occurs. Your endpoint can then parse this JSON payload and trigger an alert. Remember that your webhook endpoint needs to return a 2xx HTTP status code quickly to acknowledge receipt; any heavy processing should be offloaded to an asynchronous queue.

    The webhook payload typically looks something like this for a claw.completed event:

    
    {
      "event": "claw.completed",
      "timestamp": "2023-10-27T10:30:00Z",
      "clawId": "clw_abcdef12345",
      "clawName": "DailyReportGenerator",
      "taskId": "tsk_ghijkl67890",
      "status": "success",
      "result": {
        "outputFile": "/reports/daily/2023-10-27.pdf",
        "recordsProcessed": 1234
      }
    }
    

    The non-obvious insight here is that when developing your webhook endpoint, always log the raw incoming payload first. The exact structure and content of the result field can vary significantly depending on how your claw is configured and what it returns. Don’t assume a fixed schema for this field; design your parser to be flexible or at least gracefully handle missing keys.

    Scripting Your Own Tools

    With API access and webhooks, you have all the building blocks to script powerful custom tools. Python is an excellent choice for this, given its rich ecosystem for HTTP requests and JSON parsing. Let’s outline a simple Python script that monitors a specific claw and re-triggers it if it fails more than N times within an hour.


    import requests
    import os
    import time
    from collections import deque

    OPENCLAW_API_URL = os.getenv("OPENCLAW_API_URL", "http://localhost:8080/api/v1")
    OPENCLAW_API_KEY = os.environ.get("OPENCLAW_API_KEY")

    if not OPENCLAW_API_KEY:
    raise ValueError("OPENCLAW_API_KEY environment variable not set.")

    HEADERS = {
    "Authorization": f"Bearer {OPENCLAW_API_KEY}",
    "Content-Type": "application/json"
    }

    def get_claw_status(claw_id):
    try:
    response = requests.get(f"{OPENCLAW_API_URL}/claws/{claw_id}", headers=HEADERS)
    response.raise_for_status()
    return response.json()
    except requests.exceptions.RequestException as e:
    print(f"Error fetching status for claw {claw_id}: {e}")
    return None

    def trigger_claw(claw_id):
    try:
    response = requests.post(f"{OPENCLAW_API_URL}/claws/{claw_id}/trigger", headers=HEADERS, json={})
    response.raise_for_status()
    print(f"Claw {claw_id} re-triggered successfully.")
    return response.json()
    except requests.exceptions.RequestException as e:
    print(f"Error triggering claw {claw_id}: {e}")
    return None

    def main(claw_id, max_failures=3, monitor_window_seconds=3600):
    failure_timestamps = deque()
    print(f"Monitoring claw {claw_id} for failures...")

    while True:
    status = get_claw_status(claw_id)
    if status and status.get("status") == "failed":
    current_time = time.time()
    failure_timestamps.append(current_time)

    # Remove failures outside the monitoring window
    while failure_timestamps and failure_timestamps[0] < current_time - monitor_window_seconds: failure_timestamps.popleft() if len(failure_timestamps) >= max_failures:
    print(f"Claw {claw_id} failed {len(failure_timestamps)} times within the last hour. Triggering re-run.")
    trigger_claw(claw_id)
    # Clear failures after a re-trigger to prevent infinite loops
    failure_timestamps.clear()
    else:
    print(f"Claw {claw_id} failed. {len(failure_timestamps)} failures in window.")

    time.sleep(60) # Check every minute

    if __name__ == "__main__":
    target_claw_id = os.getenv("TARGET_CLAW_ID")
    if not target_claw_

    Want to script OpenClaw with Python? See how to use the OpenClaw Python SDK for task automation →

  • How to Connect OpenClaw to Telegram for 24/7 AI Assistance

    If you’re looking to turn your OpenClaw instance into a personal, always-on AI assistant accessible from your phone, connecting it to Telegram is the most practical solution. The common pitfall is thinking you need complex webhooks or a full-blown web server. For most users, a simple polling mechanism combined with a systemd service is far more robust and easier to maintain, especially on a VPS where resources are shared. I’ve found this setup to be rock-solid on a Hetzner CX11, providing continuous uptime without the headaches of managing external reverse proxies.

    Affiliate Disclosure: As an Amazon Associate, we earn from qualifying purchases. This means we may earn a small commission when you click our links and make a purchase on Amazon. This comes at no extra cost to you and helps support our site.

    Setting up Your Telegram Bot

    First, you need a Telegram bot. Talk to @BotFather on Telegram. Send him /newbot, give your bot a name (e.g., “MyOpenClawAI”) and a username (e.g., “MyOpenClaw_bot”). BotFather will give you an API token. It looks something like 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11. Keep this token safe; it’s how your OpenClaw instance will interact with Telegram.

    Next, you need to get your Telegram User ID. There are several bots for this, but @userinfobot is reliable. Just start a chat with it, and it will tell you your ID (a sequence of digits). This is crucial because you don’t want your OpenClaw bot to respond to just anyone on Telegram; you want it to be exclusively for you or a trusted group.

    Configuring OpenClaw for Telegram Integration

    OpenClaw doesn’t have native Telegram integration out of the box, but we can easily bridge it using a small Python script that acts as a middleware. This script will poll Telegram for new messages, pass them to OpenClaw, and then send OpenClaw’s responses back to Telegram. This approach avoids exposing OpenClaw directly to the internet, which is a significant security benefit.

    Let’s create a new directory for our Telegram bridge script. On your VPS, navigate to your OpenClaw installation directory, typically ~/openclaw or /opt/openclaw. Then:

    mkdir -p ~/openclaw-telegram
    cd ~/openclaw-telegram
    touch telegram_bridge.py
    

    Now, open telegram_bridge.py with your favorite editor (nano telegram_bridge.py) and paste the following Python code:

    import os
    import time
    import requests
    import json
    import subprocess
    
    # --- Configuration ---
    TELEGRAM_BOT_TOKEN = "YOUR_TELEGRAM_BOT_TOKEN" # Replace with your bot token
    ALLOWED_USER_ID = YOUR_TELEGRAM_USER_ID # Replace with your numeric user ID
    OPENCLAW_CLI_PATH = "/usr/local/bin/openclaw" # Adjust if openclaw is not in your PATH
    OPENCLAW_CONFIG_PATH = "~/.openclaw/config.json" # Adjust if your config is elsewhere
    POLLING_INTERVAL_SECONDS = 5 # How often to check for new messages
    # --- End Configuration ---
    
    telegram_api_base = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}"
    last_update_id = 0
    
    def get_updates():
        global last_update_id
        try:
            params = {'offset': last_update_id + 1, 'timeout': 3}
            response = requests.get(f"{telegram_api_base}/getUpdates", params=params)
            response.raise_for_status()
            updates = response.json()['result']
            if updates:
                last_update_id = max(u['update_id'] for u in updates)
            return updates
        except requests.exceptions.RequestException as e:
            print(f"Error fetching Telegram updates: {e}")
            return []
    
    def send_message(chat_id, text):
        try:
            params = {'chat_id': chat_id, 'text': text, 'parse_mode': 'Markdown'}
            response = requests.post(f"{telegram_api_base}/sendMessage", data=params)
            response.raise_for_status()
        except requests.exceptions.RequestException as e:
            print(f"Error sending Telegram message: {e}")
    
    def run_openclaw(prompt):
        try:
            # Pass model and config explicitly for robustness
            # Using claude-haiku-4-5 is often 10x cheaper than default Opus/Sonnet and sufficient.
            # Adjust --model and --config as needed.
            cmd = [OPENCLAW_CLI_PATH, "chat", "--prompt", prompt, 
                   "--model", "claude-haiku-4-5", 
                   "--config", os.path.expanduser(OPENCLAW_CONFIG_PATH)]
            
            print(f"Running OpenClaw command: {' '.join(cmd)}")
            process = subprocess.run(cmd, capture_output=True, text=True, check=True)
            return process.stdout.strip()
        except subprocess.CalledProcessError as e:
            print(f"OpenClaw command failed: {e}")
            print(f"Stderr: {e.stderr}")
            return f"Error: OpenClaw failed to respond. Details: {e.stderr.strip()}"
        except FileNotFoundError:
            return f"Error: OpenClaw CLI not found at {OPENCLAW_CLI_PATH}. Please check the path."
        except Exception as e:
            return f"An unexpected error occurred while running OpenClaw: {e}"
    
    def main():
        print("OpenClaw Telegram bridge started...")
        while True:
            updates = get_updates()
            for update in updates:
                if 'message' in update and 'text' in update['message']:
                    message = update['message']
                    chat_id = message['chat']['id']
                    user_id = message['from']['id']
                    text = message['text']
    
                    if user_id != ALLOWED_USER_ID:
                        print(f"Received message from unauthorized user {user_id} in chat {chat_id}: {text}")
                        send_message(chat_id, "Sorry, I am a private bot and can only respond to my owner.")
                        continue
    
                    print(f"Received message from {user_id} in chat {chat_id}: {text}")
                    send_message(chat_id, "_Thinking..._") # Provide immediate feedback
    
                    response = run_openclaw(text)
                    send_message(chat_id, response)
                
            time.sleep(POLLING_INTERVAL_SECONDS)
    
    if __name__ == "__main__":
        main()
    

    Crucial step: Replace "YOUR_TELEGRAM_BOT_TOKEN" with the token you got from BotFather and YOUR_TELEGRAM_USER_ID with your numeric User ID. Make sure OPENCLAW_CLI_PATH points to your actual OpenClaw executable (you can find it by running which openclaw). The default ~/.openclaw/config.json usually works, but verify its location.

    A non-obvious insight here: while the OpenClaw documentation might suggest using the default model for various tasks, models like claude-haiku-4-5 (or even gpt-3.5-turbo if you’re using OpenAI) are often 10x cheaper and perfectly sufficient for 90% of interactive chat tasks. For a 24/7 assistant, cost efficiency is paramount. I’ve explicitly set --model claude-haiku-4-5 in the script for this reason.

    This setup works best on a VPS with at least 2GB RAM. While OpenClaw itself is relatively light, the underlying LLM calls and Python process will consume some resources. A Raspberry Pi might struggle, especially if you’re running other services or requesting very long completions.

    Making it Persistent with Systemd

    To ensure your Telegram bridge runs continuously and restarts automatically after crashes or reboots, we’ll use systemd. Create a service file:

    sudo nano /etc/systemd/system/openclaw-telegram.service
    

    Paste the following content, adjusting the paths for User, WorkingDirectory, and ExecStart to match your user and the script’s location:

    [Unit]
    Description=OpenClaw Telegram Bridge
    After=network.target

    [Service]
    User=your_username # e.g., 'ubuntu', 'root', or your specific user
    WorkingDirectory=/home/your_

    Frequently Asked Questions

    What is OpenClaw and what does this integration achieve?

    OpenClaw is an AI system. Connecting it to Telegram allows you to access its AI assistance 24/7 directly from your chat app, providing instant support and information whenever you need it.

    Why should I connect OpenClaw to Telegram for AI assistance?

    This integration provides continuous, round-the-clock AI support directly within your Telegram chats. It offers unparalleled convenience, allowing you to leverage OpenClaw's capabilities for instant help, information, or task execution anytime, anywhere.

    What do I need to prepare before connecting OpenClaw to Telegram?

    To get started, you'll typically need an active OpenClaw instance or account, a Telegram account, and potentially a Telegram Bot API token. The article will provide detailed steps for configuration and setup.

    🤖 Get the OpenClaw Automation Starter Kit (9) →
    Instant download — no subscription needed

    Want to script OpenClaw with Python? See how to use the OpenClaw Python SDK for task automation →

  • Scripting OpenClaw: Automating Tasks with Python SDK

    If you’re running OpenClaw on a Hetzner VPS and finding yourself manually kicking off routine tasks, or worse, forgetting them entirely, then you’re missing out on the power of the OpenClaw Python SDK. While the UI is great for interactive exploration and quick prompts, many production workflows demand automation. Think daily sentiment analysis reports, scheduled content generation, or even complex multi-step agents that interact with external APIs. Manually copying and pasting prompts into the UI just isn’t scalable or reliable. This note will walk you through how to script OpenClaw using its Python SDK to automate these repetitive tasks, focusing on practical examples you can adapt for your own use cases.

    Affiliate Disclosure: As an Amazon Associate, we earn from qualifying purchases. This means we may earn a small commission when you click our links and make a purchase on Amazon. This comes at no extra cost to you and helps support our site.

    Setting Up Your Python Environment

    Before we dive into the code, ensure your Python environment is ready. You’ll need Python 3.8+ and the openclaw SDK installed. If you’re working on a fresh Hetzner Ubuntu instance, you can typically get Python up and running with:

    sudo apt update
    sudo apt install python3-pip -y
    pip3 install openclaw
    

    You’ll also need your OpenClaw API key. This isn’t usually stored in a public Git repository, so the best practice is to load it from an environment variable. Add this to your ~/.bashrc or ~/.profile on your VPS:

    export OPENCLAW_API_KEY="sk_your_api_key_here"
    

    Remember to source your profile after adding it: source ~/.bashrc. The OpenClaw SDK will automatically pick up this environment variable, saving you from hardcoding it in your scripts.

    Basic Interaction: Generating Text

    Let’s start with a simple script to generate some text. Create a file named generate_report.py:

    import os
    from openclaw import OpenClaw
    
    # Initialize the client. It will automatically pick up OPENCLAW_API_KEY from environment variables.
    client = OpenClaw()
    
    def generate_daily_summary(topic: str) -> str:
        """Generates a brief daily summary for a given topic."""
        prompt = f"Write a concise daily news summary about {topic}, focusing on key developments from the last 24 hours. Keep it under 150 words."
        response = client.completions.create(
            model="claude-haiku-4-5", # A cost-effective model for summaries
            prompt=prompt,
            max_tokens=200, # Max tokens for the model's response
            temperature=0.7 # A bit of creativity
        )
        return response.text
    
    if __name__ == "__main__":
        summary = generate_daily_summary("AI in healthcare")
        print("--- Daily AI in Healthcare Summary ---")
        print(summary)
    
        # Example: Saving to a file
        with open("ai_healthcare_summary.txt", "w") as f:
            f.write(summary)
        print("\nSummary saved to ai_healthcare_summary.txt")
    

    The non-obvious insight here is the model choice. While the OpenClaw documentation might suggest using the latest and greatest models like claude-opus-4-0, for many routine summarization or classification tasks, a smaller, faster, and significantly cheaper model like claude-haiku-4-5 is often more than sufficient. It’s about 10x cheaper per token and provides excellent quality for 90% of use cases where extreme nuance isn’t critical. Always test cheaper models first to see if they meet your needs.

    To run this script:

    python3 generate_report.py
    

    Automating with Cron Jobs

    Now that we have a script, the next logical step is to automate its execution. Cron is your friend here on a Linux VPS. Let’s say you want to run this daily summary script every morning at 7:00 AM.

    First, ensure your Python script has the correct shebang and is executable:

    chmod +x generate_report.py
    

    Then, edit your crontab:

    crontab -e
    

    Add the following line:

    0 7 * * * /usr/bin/python3 /path/to/your/scripts/generate_report.py >> /var/log/openclaw_reports.log 2>&1
    

    A crucial detail for cron jobs is ensuring the environment variables are correctly loaded. The OPENCLAW_API_KEY won’t automatically be available to cron jobs unless you explicitly define it in the crontab or source your profile within the script itself. A safer approach for cron is to pass the key directly to the script, or make sure the cron user’s environment is set up. For simplicity, if your script directly uses the SDK, it’s better to ensure the cron job runs with the necessary environment. Alternatively, you can explicitly set it within the cron entry:

    0 7 * * * OPENCLAW_API_KEY="sk_your_api_key_here" /usr/bin/python3 /path/to/your/scripts/generate_report.py >> /var/log/openclaw_reports.log 2>&1
    

    Or, even better, ensure your script itself handles the environment variable gracefully, as shown in the Python example where it automatically picks it up. The output redirection >> /var/log/openclaw_reports.log 2>&1 is vital for debugging cron jobs; without it, you’ll have no idea if your script ran successfully or failed silently.

    Handling More Complex Workflows: Multi-Turn Conversations

    The OpenClaw SDK also supports multi-turn conversations, which are essential for building more dynamic agents or interactive systems. Let’s create a simple conversational agent that refines a blog post outline based on feedback:

    import os
    from openclaw import OpenClaw
    
    client = OpenClaw()
    
    def refine_blog_outline(initial_topic: str):
        """
        Simulates a multi-turn conversation to refine a blog post outline.
        """
        messages = [
            {"role": "user", "content": f"Generate a detailed outline for a blog post about '{initial_topic}'."}
        ]
    
        print(f"--- Generating initial outline for '{initial_topic}' ---")
        response = client.chat.completions.create(
            model="claude-haiku-4-5",
            messages=messages,
            max_tokens=500
        )
        initial_outline = response.choices[0].message.content
        print(initial_outline)
        messages.append({"role": "assistant", "content": initial_outline})
    
        feedback = input("\nEnter your feedback on the outline (or 'quit' to finish): ")
        while feedback.lower() != 'quit':
            messages.append({"role": "user", "content": f"Based on this feedback: '{feedback}', please refine the outline."})
            print("\n--- Refining outline based on feedback ---")
            response = client.chat.completions.create(
                model="claude-haiku-4-5",
                messages=messages,
                max_tokens=500
            )
            refined_outline = response.choices[0].message.content
            print(refined_outline)
            messages.append({"role": "assistant", "content": refined_outline})
            feedback = input("\nEnter more feedback (or 'quit' to finish): ")
    
        print("\n--- Final Outline ---")
        # Join messages to show the full conversation or extract the last assistant message
        print(messages[-1]['content'])
    
    if __name__ == "__main__":
        refine_blog_outline("The Future of Serverless Computing")
    

    This script demonstrates how to maintain a conversation history by appending both user and assistant messages to the messages list. Each subsequent call to client.chat.completions.create then sends the entire history, allowing the model to maintain context. This is crucial for interactive agents or chained tasks where the output of one step informs the next. The limitation here is that this interactive script isn’t suitable for direct cron automation due to the input() calls. You would need to replace the interactive feedback loop with pre-defined rules or external data sources for full automation.

    Limitations and Resource Considerations

    While OpenClaw’s SDK is

    Frequently Asked Questions

    What is OpenClaw, and what does scripting it achieve?

    OpenClaw is a system/platform where scripting with the Python SDK enables programmatic control. This automates repetitive tasks, streamlines workflows, and enhances operational efficiency, making complex processes manageable.

    Why is Python chosen for automating OpenClaw tasks?

    Python’s SDK provides a powerful, readable, and versatile interface for OpenClaw. Its extensive libraries and straightforward syntax make it ideal for developing robust automation scripts, simplifying complex operations and integrations.

    What types of tasks can be automated using the Python SDK for OpenClaw?

    The Python SDK allows automating diverse OpenClaw tasks like data processing, configuration management, report generation, system monitoring, and integrating external services. This significantly reduces manual effort and improves consistency.

  • Choosing the Right LLM for Your OpenClaw Use Case

    If you’re running OpenClaw for tasks like log analysis, code review, or customer support summarization, one of the most critical decisions you’ll face is selecting the right Large Language Model (LLM). The “best” model isn’t always the biggest or most expensive; it’s the one that delivers acceptable quality at a sustainable cost for your specific use case. Overlooking this can lead to exorbitant API bills or frustrated users waiting on slow, overly complex models.

    Affiliate Disclosure: As an Amazon Associate, we earn from qualifying purchases. This means we may earn a small commission when you click our links and make a purchase on Amazon. This comes at no extra cost to you and helps support our site.

    Understanding OpenClaw’s LLM Integration

    OpenClaw is designed to be model-agnostic, but its internal queuing and tokenization mechanisms are optimized for typical transformer-based models. When you configure an LLM in OpenClaw, you’re essentially telling it which API endpoint to hit and how to structure the request body. This is crucial because different providers have different rate limits, token limits, and pricing structures. For instance, an OpenAI model will expect a messages array, while a Cohere model might expect a prompt string. OpenClaw handles this abstraction, but the underlying characteristics of the model still dictate performance and cost.

    Most of OpenClaw’s configuration for LLMs lives in ~/.openclaw/config.json under the "llm_providers" section. Here’s a typical snippet:

    {
      "llm_providers": {
        "openai": {
          "type": "openai",
          "api_key_env": "OPENAI_API_KEY",
          "default_model": "gpt-4o",
          "models": {
            "gpt-4o": {
              "cost_per_input_token": 0.000005,
              "cost_per_output_token": 0.000015,
              "max_tokens": 128000
            },
            "gpt-3.5-turbo": {
              "cost_per_input_token": 0.0000005,
              "cost_per_output_token": 0.0000015,
              "max_tokens": 16385
            }
          }
        },
        "anthropic": {
          "type": "anthropic",
          "api_key_env": "ANTHROPIC_API_KEY",
          "default_model": "claude-3-opus-20240229",
          "models": {
            "claude-3-opus-20240229": {
              "cost_per_input_token": 0.000015,
              "cost_per_output_token": 0.000075,
              "max_tokens": 200000
            },
            "claude-3-haiku-20240307": {
              "cost_per_input_token": 0.00000025,
              "cost_per_output_token": 0.00000125,
              "max_tokens": 200000
            }
          }
        }
      }
    }
    

    Notice the cost_per_input_token and cost_per_output_token. These are vital for OpenClaw’s internal cost tracking and for making informed decisions. Keep these updated as providers change their pricing.

    The Non-Obvious Truth: Cheaper Models are Often Good Enough

    The biggest trap many OpenClaw users fall into is defaulting to the largest, most “intelligent” model available. For instance, the docs might implicitly suggest using gpt-4o or claude-3-opus for complex reasoning tasks. While these models are undoubtedly powerful, they come with a significant cost premium and often higher latency.

    Here’s the insight: for 90% of practical OpenClaw use cases—summarizing short texts, extracting structured data from logs, generating simple code snippets, or classifying support tickets—models like Anthropic’s claude-3-haiku-20240307 or OpenAI’s gpt-3.5-turbo are more than sufficient. I’ve found claude-3-haiku-20240307 to be particularly impressive in its cost-to-performance ratio for general text processing. It’s often 10x cheaper than its larger siblings and nearly as fast, making it ideal for high-volume, lower-stakes tasks. The quality difference, especially after proper prompt engineering, is often negligible for these specific applications.

    Consider a scenario where OpenClaw is processing hundreds of log entries per minute, identifying critical errors. Using gpt-4o for each entry would quickly deplete your budget. Switching to gpt-3.5-turbo or claude-3-haiku-20240307, with a well-crafted system prompt like “You are an expert at identifying critical errors in application logs. Respond only with ‘CRITICAL’ if a critical error is detected, otherwise respond ‘OK’.”, dramatically reduces costs without sacrificing accuracy in this specific context.

    When to Opt for Larger Models

    There are, of course, scenarios where the more capable, and expensive, models are indispensable. These typically involve tasks requiring deep reasoning, complex code generation, multi-step problem solving, or highly nuanced natural language understanding. For example:

    • Advanced Code Refactoring: If OpenClaw is assisting with refactoring large codebases or proposing architectural changes, a model like gpt-4o or claude-3-opus will provide higher quality and more robust suggestions.
    • Legal Document Analysis: Extracting specific clauses, identifying contradictions, or summarizing lengthy legal texts often benefits from the enhanced comprehension of top-tier models.
    • Creative Content Generation: For generating marketing copy, story outlines, or complex scripts, the superior creativity and coherence of larger models can be worth the extra cost.
    • Complex Troubleshooting: Analyzing system dumps, correlating multiple data sources, and proposing solutions to obscure technical issues can leverage the deeper reasoning capabilities.

    In these cases, the cost increase is often justified by the higher quality output, reduced need for human intervention, or the complexity of the task itself, which simpler models might fail at entirely.

    Limitations and Resource Considerations

    While OpenClaw is efficient, the choice of LLM does have implications for your local system resources, especially if you’re doing any local embedding or pre-processing. However, for remote API calls, the primary limitation will be your budget and the API provider’s rate limits, not your local RAM or CPU.

    This advice primarily applies when you’re using external LLM APIs. If you’re attempting to run local, open-source models (e.g., Llama 3 via Ollama) through OpenClaw, then hardware limitations become very real. Running a 7B parameter model locally typically requires at least 8GB of RAM, with 16GB being more comfortable for larger context windows. For 70B models, you’re looking at 64GB+ RAM or dedicated GPUs. A typical Hetzner VPS with 2GB RAM will struggle immensely with even a small local model. For API-based interactions, though, your VPS only needs enough resources to run OpenClaw itself, not the LLM.

    It’s also important to factor in the total context window. If your OpenClaw tasks involve very long inputs (e.g., analyzing entire code repositories or lengthy transcripts), you’ll need models with large context windows. While many cheaper models now offer large contexts (e.g., Haiku’s 200k tokens), ensure their quality at the extremities of that window is acceptable for your specific task.

    To optimize your OpenClaw setup and reduce API costs, review your common use cases. For any task that doesn’t demand the absolute pinnacle of reasoning or creativity, consider stepping down to a more cost-effective model. The savings can be substantial.

    To implement this, open your ~/.openclaw/config.json file and change the "default_model" for the Anthropic provider from "claude-3-opus-20240229" to "claude-3-haiku-20240307":

        "anthropic": {
    "type": "anthropic",
    "api_key_env": "ANTHROPIC_API_KEY",
    "default_model": "claude-3-haiku-20240307",
    "models": {
    "claude-3-opus-2024022

    Want to script OpenClaw with Python? See how to use the OpenClaw Python SDK for task automation →

  • OpenClaw for Developers: Code Generation and Debugging Assistant

    You’ve seen the demos, probably even used OpenClaw to generate boilerplate for a new service or a tricky regex. But what happens when the code OpenClaw generates isn’t quite right, or worse, introduces a subtle bug that only manifests at runtime? The common pitfall is treating OpenClaw as a magic bullet, pasting its output directly into your project without a critical eye, then spending hours debugging a problem OpenClaw inadvertently introduced. The true power isn’t just in the generation, but in how you leverage it as a dynamic debugging partner, not just a static code factory.

    Consider a scenario where you’ve asked OpenClaw to implement a complex data transformation logic, say, converting a nested JSON structure into a flattened CSV format. OpenClaw dutifully provides Python code. You run it, and it mostly works, but some edge cases are missed, or the CSV output has an unexpected extra comma in certain rows. Your initial instinct might be to manually comb through the generated Python, or simply ask OpenClaw for another attempt from scratch. The non-obvious insight here is to treat OpenClaw’s output as an initial hypothesis, then use OpenClaw itself to help you validate and refine it, rather than just regenerate. Instead of asking “Fix this code,” describe the *symptom* of the bug directly to OpenClaw. For example, “The Python script you provided for JSON to CSV conversion adds an extra comma before the last field when the ‘notes’ field is empty. Here is the relevant part of the input JSON and the incorrect output line.”

    This approach transforms OpenClaw from a code generator into an active debugging assistant. When you present it with the problematic input and output, alongside the offending section of its own generated code, you’re giving it a concrete test case to work against. It’s like pair programming, but with an AI that has perfect recall of its previous suggestions. You might find it points to an overlooked conditional, or a subtle off-by-one error in a loop it created. For instance, it might suggest modifying a line like output_row.append(field if field else '') to include a more robust check or a different concatenation method, acknowledging the specific edge case you highlighted. This iterative refinement, feeding specific error examples back into the system, is far more efficient than broad, unspecific prompts for “better code.”

    The key technical detail here is the specificity of your prompts when debugging. Instead of a generic “why is this wrong?”, try to isolate the exact input and output discrepancy. If you’re using the OpenClaw CLI, you might even pipe the problematic output into a new prompt: cat problematic_output.csv | openclaw debug-assist --code-snippet '...' --error-description '...'. This gives OpenClaw the full context of the failure, allowing it to pinpoint the logical flaw in its original generation. It’s about leveraging its analytical capabilities on its own output, turning a potentially frustrating debugging session into a collaborative problem-solving exercise.

    To start integrating this workflow, take your last OpenClaw-generated code snippet that required manual debugging, and re-run that debugging session by describing the exact bug and showing the problematic input/output directly to OpenClaw.

    Frequently Asked Questions

    What is OpenClaw for Developers?

    OpenClaw is an AI-powered assistant designed for software developers. It streamlines the coding workflow by offering advanced code generation capabilities and intelligent tools to help identify and resolve bugs efficiently.

    How does OpenClaw assist with code generation?

    OpenClaw can generate various code snippets, functions, or even entire modules based on your natural language descriptions or existing project context. This speeds up development and reduces repetitive coding tasks.

    What debugging assistance does OpenClaw provide?

    OpenClaw acts as an intelligent debugging assistant, helping developers pinpoint errors, suggest fixes, and explain complex issues. It analyzes code and runtime behavior to offer actionable insights, enhancing problem-solving.

    Want to script OpenClaw with Python? See how to use the OpenClaw Python SDK for task automation →

  • OpenClaw Security: What Access to Give and What to Restrict

    You’ve got your OpenClaw assistant humming along, probably managing your calendar, drafting emails, or even pushing code snippets. It’s incredibly powerful, but that power brings a critical question: how much rope are you giving it? The problem isn’t just about a rogue AI, it’s about the security implications of its access if compromised. If your OpenClaw instance can execute rm -rf / on your server, a single mistaken prompt or a security vulnerability could be catastrophic, even if it’s just the OpenClaw process itself getting exploited. We’re talking about real-world file system and network access.

    The core principle for OpenClaw security, much like any service account, is least privilege. Don’t give your OpenClaw process more permissions than it absolutely needs to perform its designated tasks. For example, if your OpenClaw instance is designed solely for text generation and doesn’t interact with external APIs or local files, its user account shouldn’t have any write access to the filesystem beyond its own temporary directories, nor should it have network access other than to pull models or communicate with its frontend. Far too often, we see OpenClaw instances running under the same user that deployed them, inheriting a wide array of permissions that are entirely unnecessary.

    Consider the tools OpenClaw utilizes. If it’s configured to use a shell executor, that’s a direct conduit to your system. Restrict the commands it can run. Instead of a blanket shell: true in its configuration, define a whitelist of specific commands and their allowed arguments. For instance, if it needs to query system status, allow ['df', '-h'] but not ['sudo', '*']. For filesystem access, map specific volumes with read-only permissions unless writing is explicitly required for a feature. A common pitfall is giving write access to log directories because “it needs to write logs,” when often, a separate, more restricted logging mechanism can be employed that doesn’t grant the OpenClaw process direct, broad write access.

    The non-obvious insight here is that the greatest risk often isn’t the AI itself making a mistake, but rather the human operator. A developer might temporarily grant elevated privileges for debugging, forget to revoke them, and suddenly that OpenClaw instance has root access. Or, a prompt engineer might craft a prompt that, unbeknownst to them, instructs the OpenClaw instance to execute a dangerous command it technically has permission to run. Always review the effective permissions of the user account running your OpenClaw processes, even if you’re confident in your OpenClaw configuration. The operating system’s permissions are the ultimate arbiter, not just your OpenClaw’s internal configuration directives.

    Begin by auditing the system user account under which your OpenClaw instance is running and explicitly revoking any unnecessary file system or network permissions.

    Frequently Asked Questions

    What is the fundamental security principle for managing OpenClaw access?

    The fundamental principle is ‘least privilege.’ Users should only be granted the minimum access necessary to perform their specific job functions, nothing more. This minimizes potential security risks.

    How should organizations determine what level of access to grant within OpenClaw?

    Access should be determined by a user’s role and their specific ‘need-to-know’ or ‘need-to-do.’ Regularly review roles and responsibilities to ensure permissions remain appropriate and avoid over-privileging.

    What are common mistakes to avoid when restricting access in OpenClaw?

    Avoid granting default broad access, using generic accounts, or neglecting periodic access reviews. Always revoke access promptly when roles change or employees leave to prevent unauthorized access.

    Written by: Alex Torres, Editor at OpenClaw Resource

    Last Updated: May 2026

    Our Editorial Standards | How We Review Skills | Affiliate Disclosure

    Want to script OpenClaw with Python? See how to use the OpenClaw Python SDK for task automation →

  • How to Debug OpenClaw When It Stops Responding

    Your OpenClaw assistant, a loyal companion in the digital wilderness, suddenly falls silent. You ping it, you check its status, but it just sits there, unresponsive, a digital statue. This isn’t just an inconvenience; it’s a productivity killer, especially when you’re relying on it for mission-critical information retrieval or complex task orchestration. The immediate assumption is usually a network issue or a full-blown crash, but often the root cause is more subtle, hiding within its operational state.

    Before you reach for the big red reboot button, your first port of call should be the OpenClaw diagnostic endpoint. Many users overlook this, jumping straight to container restarts. A simple curl http://localhost:8080/diag (assuming default port) can often reveal a lot. Pay close attention to the processing_queue_size and last_processed_timestamp fields. If the queue size is consistently high and the timestamp isn’t updating, your assistant isn’t crashed; it’s likely overwhelmed or stuck on a specific, resource-intensive request. This is a crucial distinction, as a restart might clear the queue but won’t prevent the same issue from recurring if the problematic request is re-submitted or a similar pattern emerges.

    The non-obvious insight here is that “unresponsive” doesn’t always mean “dead.” It often means “choking.” OpenClaw, by design, prioritizes existing tasks to maintain data integrity and avoid partial responses. When it encounters a particularly thorny prompt that consumes excessive CPU or memory, it can create a backlog that effectively locks up the processing pipeline, even if the core service is technically still running. This isn’t a bug; it’s a protective mechanism. Manually clearing specific problematic entries from the /admin/queue endpoint (if you can identify them via the diagnostic output) can often bring it back online much faster than a full restart, preserving any in-flight, non-problematic tasks. This targeted intervention prevents the ‘reboot lottery’ where you hope the problematic request doesn’t get processed again immediately.

    To prevent future occurrences, consider implementing resource quotas for individual requests or users, accessible through the request_qos_config settings in your OpenClaw YAML configuration. This allows you to cap the CPU and memory a single processing thread can consume, gracefully rejecting or time-limiting requests that exceed defined thresholds rather than letting them paralyze the entire instance.

    For your next step, review your OpenClaw instance’s request_qos_config and consider setting initial CPU and memory limits to safeguard against resource exhaustion from runaway prompts.

    Frequently Asked Questions

    What’s the first step when OpenClaw stops responding?

    Check system resource usage (CPU, RAM). If high, identify the culprit. If OpenClaw is frozen, try force-quitting and restarting. This often resolves temporary glitches and helps determine if it’s a persistent issue.

    How can I pinpoint the cause of OpenClaw’s unresponsiveness?

    Examine OpenClaw’s log files for errors or warnings preceding the freeze. If it’s still running but stuck, attach a debugger to inspect its state. For crashes, analyze any generated crash dumps to trace the failure point.

    What are common reasons OpenClaw might become unresponsive?

    Frequent causes include resource exhaustion (memory leaks, CPU spikes), deadlocks, infinite loops, problems with external dependencies, or corrupted configuration files. Network issues can also lead to unresponsiveness if OpenClaw relies on remote services.

    Written by: Alex Torres, Editor at OpenClaw Resource

    Last Updated: May 2026

    Our Editorial Standards | How We Review Skills | Affiliate Disclosure

    Want to script OpenClaw with Python? See how to use the OpenClaw Python SDK for task automation →