Skip to content

OpenHands

Connect OpenHands to Tokens as an OpenAI-compatible endpoint, in the web UI or the CLI, with the right model string for ids that already contain a slash.

Works withOpenHandsTerminal
On this page

OpenHands is an open-source AI software engineer that edits code, runs commands and browses inside a sandbox. It calls models through LiteLLM, so Tokens is added as an OpenAI-compatible endpoint: a model string starting with openai/, a Base URL of https://tokens.bd/v1, and your Tokens key. Requests are OpenAI Chat Completions.

Checked against the documentation

Based on the OpenHands documentation on docs.openhands.dev (the OpenAI, local LLM, LLM overview and CLI pages), checked October 2026. The pages do not state a CLI version; the install page we read pins agent server image 1.26.0-python. We have not run OpenHands against Tokens end to end.

What you need#

  • A Tokens key. Create one only for OpenHands, with a monthly spend cap (API keys).
  • The model id from /models. The examples use deepseek/deepseek-v4.1-flash.
  • OpenHands installed. The CLI and the local web UI both need Python 3.12 and uv, or you can use the binary or Docker. The web UI also needs Docker running. On Windows, OpenHands says to run everything inside WSL (Ubuntu).
  • A model that supports tool calling. OpenHands says it needs a powerful model, and that open-weight models vary in how reliably they call tools.

Which model string to type#

LiteLLM chooses the provider from the text before the first slash. For a custom OpenAI-compatible endpoint that text must be openai/, and OpenHands says the prefix is required in Custom Model. Tokens ids already contain a slash (provider/model), so the value you type has two:

text
openai/deepseek/deepseek-v4.1-flash

The pattern is openai/<Tokens model id>. OpenHands documents the same shape for proxies that have their own routing prefix (openai/<proxy-prefix>/<model-name>), and its local LLM page uses openai/qwen/qwen3.6-35b-a3b for an LM Studio model whose id contains a slash. Neither OpenHands nor LiteLLM documents which part is sent to the endpoint. These examples rely on LiteLLM using the first openai/ only to pick the provider and sending the rest, here deepseek/deepseek-v4.1-flash, which is the id Tokens expects. That is our reading of the examples, not a documented guarantee. If requests come back as model_not_found, see the troubleshooting section below.

Set it up in the web UI#

Start the UI:

bash
uv tool install openhands --python 3.12
openhands serve

Open http://localhost:3000. Then:

  1. Select the Settings button (gear icon), then the LLM tab.
  2. Turn on the Advanced toggle.
  3. Set Custom Model to openai/deepseek/deepseek-v4.1-flash.
  4. Set Base URL to https://tokens.bd/v1.
  5. Set API Key to your Tokens key.
  6. Save the settings.

OpenHands keeps its state in ~/.openhands on your machine. Treat that folder as secret and never commit it, because it holds your settings and may hold the key.

Set it up in the CLI#

On first start the CLI asks for an LLM provider and API key and saves them under ~/.openhands/. The pages we read do not list a Base URL or Custom Model prompt in that first-run dialog, so use environment variables for Tokens:

bash
export LLM_API_KEY="tok_live_your_key"
export LLM_MODEL="openai/deepseek/deepseek-v4.1-flash"
export LLM_BASE_URL="https://tokens.bd/v1"
openhands --override-with-envs

Environment variables are ignored without the flag

OpenHands ignores LLM_* variables unless you start the CLI with --override-with-envs. The override is not saved: a plain openhands the next day goes back to whatever is stored in ~/.openhands/. Put the four lines in a small shell script or alias if you use Tokens every time.

To change the stored model later, press Ctrl+P in the CLI and choose Settings, or edit the model field in ~/.openhands/agent_settings.json. The CLI docs name both settings.json and agent_settings.json for the stored LLM settings, so look in the folder to see which your version uses. We could not confirm from the documentation whether the CLI's Settings screen has a Base URL field, which is why the steps above use the environment variables.

On Windows, run these commands in the WSL shell, not in PowerShell.

Check that it works#

First rule out OpenHands, with the id as Tokens expects it (no openai/ prefix):

bash
curl https://tokens.bd/v1/chat/completions \
  -H "Authorization: Bearer $LLM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "deepseek/deepseek-v4.1-flash", "max_tokens": 16, "messages": [{"role": "user", "content": "Reply with OK"}]}'

Then, in OpenHands, ask for something small ("List the files in the workspace and tell me what the project does"). The agent should reply and run a command, and the request should show up in usage analytics on your dashboard. A reply with no actions at all usually means the model is not calling tools.

Choosing a model#

OpenHands works in long loops of tool calls, so pick a model with strong tool calling and a long context. Choosing a model compares them, and /models shows each model's context and output limits. OpenHands' own advice is to use the strongest model you can afford for long or high-stakes tasks.

The pages we read do not mention a field for the context window or maximum output. If the model has a native tool calling switch under model customization, OpenHands says it can be toggled there. If you see malformed JSON errors or poor output, OpenHands suggests a stronger model or a larger context window before anything else.

Limits and what to know#

  • Spend. OpenHands retries failed calls (LLM_NUM_RETRIES, default 4) and loops until a task is done. A single task can send hundreds of requests, each carrying a growing conversation. Use a spend-capped key (API keys) and watch the dashboard. OpenHands itself warns to set spending limits.
  • LiteLLM costs. Any cost OpenHands shows is an estimate from LiteLLM's own price table, which may not list Tokens ids. Your real spend is in the dashboard.
  • Other LLM settings. A few options (LLM_API_VERSION, LLM_DROP_PARAMS, LLM_DISABLE_VISION, LLM_CACHING_PROMPT) are environment variables or config.toml entries only, not UI fields.
  • Version changes. OpenHands changed its settings format at version 1.0.0. If you upgrade from an older install, redo the setup.

Troubleshooting#

404 model_not_found. The model string reached Tokens with the wrong shape. The Custom Model value must be openai/ followed by the exact Tokens id (openai/deepseek/deepseek-v4.1-flash). Without the openai/ prefix, LiteLLM can treat the first part of the id as a provider name. If the prefix is there and it still fails, run the curl above with the id from /models to confirm the id itself is right.

LiteLLM says the provider is not provided or not recognized. The Custom Model value has no openai/ prefix. Add it.

401 missing_api_key or invalid_api_key. The API Key field or LLM_API_KEY is empty or holds a different provider's key. A Tokens key starts with tok_live_.

404 on every request. The Base URL must be https://tokens.bd/v1 and nothing more. LiteLLM adds the path itself, so do not append /chat/completions.

The CLI ignores my settings. LLM_* variables need --override-with-envs. Without it the stored settings win.

403 monthly_spend_cap_exceeded, 402 insufficient_credits, or 429 rate_limited. The key's cap, your balance or your rate limit stopped the agent. Raise the cap or top up in billing, or wait for Retry-After. The OpenHands retry loop makes 429 more likely during busy sessions.

From the web UI container, the endpoint is unreachable. Tokens is a public address, so this is usually a Docker network or proxy problem on your side. Run the curl from the same machine first.

For all codes, see Errors; for other problems, Troubleshooting.

Was this page helpful?

Still stuck? Open a support ticket

Need help configuring your agent?

Test your connection with the connection tester, or create an API key.