Guides

Endpoint guide

Chat With Your Bot From the Terminal

Use the Endpoint on your OpenClaw Launch instance card with curl, scripts, or a terminal client. It works with both OpenClaw and Hermes Agent through a restricted OpenAI-compatible API.

What you need

Your bot must be running with an active subscription or trial. Open its instance card, select Endpoint, choose Desktop app, and enable access. Copy the Base URL, API key, and Model shown in that window.

Protect the endpoint key

The API key can run your bot. Do not paste it into screenshots, support messages, source code, or a public repository. Disable the endpoint from the instance card when you no longer need it.

The three connection values

ValueWhere to find it
Base URLEndpoint window; it already ends in /v1
API keyEndpoint window; use it as a Bearer token
ModelEndpoint window; usually hermes-agent or openclaw/default

Quick terminal setup

  1. Store the connection values

    Paste the Base URL and Model exactly as shown in Bash or Zsh. The hidden read keeps the API key out of your shell history, and the curl examples pass it through a temporary input stream instead of a process argument.

    Shell
    BOT_BASE_URL='PASTE_BASE_URL'
    BOT_MODEL='PASTE_MODEL'
    printf 'Endpoint API key: '
    read -s BOT_API_KEY
    printf '\n'
  2. Check the connection

    Call the models route first. A successful models response means the URL, key, endpoint state, and running bot are all reachable. HTTP errors remain visible and make curl exit with a failure status.

    curl
    curl --fail-with-body -sS "$BOT_BASE_URL/models" \
      --header @<(printf 'Authorization: Bearer %s\n' "$BOT_API_KEY")
  3. Send one message with curl

    The Base URL already contains /v1, so append only /chat/completions. This request returns the normal OpenAI-compatible JSON response.

    curl
    curl --fail-with-body -sS "$BOT_BASE_URL/chat/completions" \
      --header @<(printf 'Authorization: Bearer %s\n' "$BOT_API_KEY") \
      -H "Content-Type: application/json" \
      -d "{
        \"model\": \"$BOT_MODEL\",
        \"messages\": [
          {\"role\": \"user\", \"content\": \"Hello from my terminal\"}
        ]
      }"
    Print only the replyIf jq is installed, this Bash/Zsh variant preserves curl errors while printing only the reply:
    Bash / Zsh + jq
    set -o pipefail
    curl --fail-with-body -sS "$BOT_BASE_URL/chat/completions" \
      --header @<(printf 'Authorization: Bearer %s\n' "$BOT_API_KEY") \
      -H "Content-Type: application/json" \
      -d "{
        \"model\": \"$BOT_MODEL\",
        \"messages\": [
          {\"role\": \"user\", \"content\": \"Hello from my terminal\"}
        ]
      }" | jq -r '.choices[0].message.content'
  4. Start an interactive terminal chat

    A single curl request does not remember earlier turns. This dependency-free Python script keeps the messages array in memory and resends it on every turn. Paste it into any terminal with Python 3.

    Python 3
    python3 -c "$(cat <<'PY'
    import json
    from getpass import getpass
    from urllib.error import HTTPError, URLError
    from urllib.request import Request, urlopen
    
    base_url = input("Base URL: ").strip().rstrip("/")
    model = input("Model: ").strip()
    api_key = getpass("API key: ")
    messages = []
    
    print("Chat ready. Use /new to clear history or /exit to quit.")
    
    while True:
        text = input("you> ").strip()
        if not text:
            continue
        if text in {"/exit", "/quit"}:
            break
        if text == "/new":
            messages.clear()
            print("History cleared.")
            continue
    
        messages.append({"role": "user", "content": text})
        payload = json.dumps({
            "model": model,
            "messages": messages,
            "stream": False,
        }).encode()
        request = Request(
            f"{base_url}/chat/completions",
            data=payload,
            headers={
                "Authorization": f"Bearer {api_key}",
                "Content-Type": "application/json",
            },
            method="POST",
        )
    
        try:
            with urlopen(request, timeout=300) as response:
                result = json.load(response)
            answer = result["choices"][0]["message"]["content"]
        except HTTPError as error:
            print(f"HTTP {error.code}: {error.read().decode(errors='replace')}")
            messages.pop()
            continue
        except (URLError, KeyError, IndexError, json.JSONDecodeError) as error:
            print(f"Request failed: {error}")
            messages.pop()
            continue
    
        print(f"bot> {answer}")
        messages.append({"role": "assistant", "content": answer})
    PY
    )"

How conversation history works

The examples manage history in the terminal client and resend earlier turns, which works with both frameworks. Hermes endpoint requests are stateless. OpenClaw clients can alternatively send a stable user field for a server-side session, but client-managed history is the most portable option. The script keeps it until you use /new or close it.

Clear the shell values when finishedRemove the URL, model, and key from the current shell session after you finish testing.
Shell
unset BOT_API_KEY BOT_BASE_URL BOT_MODEL

Supported routes

The instance-card endpoint intentionally exposes only the two routes needed by compatible chat clients:

GET /v1/models — verify the connection and discover available model IDs.POST /v1/chat/completions — send messages, with standard JSON or SSE streaming responses.
Endpoint chat and the browser Terminal are differentThis endpoint lets a terminal on your own computer chat with the bot over HTTPS. It does not open a shell inside the bot container. Use the Terminal button on the instance card when you need command-line access inside the instance itself.

Troubleshooting

401 or invalid_api_key

Open Endpoint again and copy the API key. Confirm the header is exactly Authorization: Bearer followed by one space and the key.

404 or not_found

The endpoint may be disabled, or the URL may be wrong. Enable it from the instance card and use the complete Base URL shown there.

403

An active subscription or trial is required. If a browser-based client reports origin_not_allowed, select that website in the Endpoint window; curl and native terminal clients do not send a browser Origin.

503 or instance_not_ready

Start the bot and wait until the instance card shows Running, then retry.

429 or rate_limit_exceeded

The endpoint is receiving requests too quickly. Pause briefly and reduce parallel requests.

Related guides

Still need help?

Send support the exact status code and error text. Hide the API key and instance credentials in every screenshot.

Contact support

Chat with your bot from any terminal

Open your dashboard, enable Endpoint on a running instance, and copy the three connection values.

Open dashboard