Skip to content
Browsa
  1. Guides
  2. Models

Models

An agent task needs a model to decide each step. Pick one of Browsa's hosted tiers and send no key, or bring your own key from Anthropic, OpenAI, Google or any OpenAI-compatible server. The choice is one field, llm.

One field
llm
Hosted tiers
browsa, browsa-fast, browsa-smart
Your own key
Anthropic, OpenAI, Google or any OpenAI-compatible server

Hosted tiers

Set llm to a tier name and leave out llm_api_key. Browsa runs the model and bills it in credits, so there is no separate model bill and no provider account to set up. Each tier names a first model and the models it moves to if that one fails.

"browsa"5 credits per task

Use it for: The default. A good first choice for most tasks.

Runs
Claude Opus 4.8
Falls back to
Claude Sonnet 4.6
Reasoning
Low
"browsa-fast"5 credits per task

Use it for: The fastest and lightest tier, for short and simple tasks.

Runs
Gemini 3.1 Flash Lite
Falls back to
Claude Sonnet 4.6, then Claude Opus 4.8
Reasoning
The model has no such setting
"browsa-smart"5 credits per task

Use it for: Harder tasks that need more thought per step.

Runs
Claude Opus 4.8
Falls back to
Claude Sonnet 4.6
Reasoning
High

The credits on each card are added once per task, on top of the normal task credits (browser time, 1 base credit and 1 credit per 5 steps: see pricing). They are a server setting and can change for each tier. The cards show today's values; GET /v1/models always returns the live ones.

from browsa import Client

c = Client(api_key="agt_live_...")
job = c.run_task(
    task="Go to example.com and report the H1.",
    llm="browsa-fast",   # or "browsa", "browsa-smart"
)
print(job.final_result)

When a hosted model fails

If the model a tier is running fails during a task, the run switches to the next model in that tier's list and carries on from where it was. Steps that were lost to the model failing are given back, so you do not pay step credits for them. A job that moved to another model carries the signal llm_fallback_used (see Outcome and signals). The credits per task stay those of the tier you asked for.

List the tiers: GET /v1/models

Read-only and free. It returns each hosted tier with the model it runs, its fallback models, its default reasoning level and its credits per task, and the providers you can use with your own key. Read the credits from here instead of writing them into your code.

from browsa import Client

c = Client(api_key="agt_live_...")
models = c.models()
for tier in models.hosted:
    print(tier.id, tier.model, tier.credits_per_task)
JSON
{
  "hosted": [
    { "id": "browsa", "model": "claude-opus-4-8", "fallback_models": ["claude-sonnet-4-6"],
      "reasoning": "low", "credits_per_task": 5, "default": true },
    { "id": "browsa-fast", "model": "gemini-3.1-flash-lite", "fallback_models": ["claude-sonnet-4-6", "claude-opus-4-8"],
      "reasoning": null, "credits_per_task": 5 },
    { "id": "browsa-smart", "model": "claude-opus-4-8", "fallback_models": ["claude-sonnet-4-6"],
      "reasoning": "high", "credits_per_task": 5 }
  ],
  "own_key": {
    "providers": ["anthropic", "openai", "google", "openai_compatible"],
    "default_models": { "anthropic": "...", "openai": "...", "google": "..." }
  }
}

reasoning is the level a tier uses when the task does not set one; null means the tier's model has no such setting. default_models is the model used when a task relies on a saved key and names no model.

Your own provider key

Use any model your Anthropic, OpenAI or Google account can call. Your provider bills you for the tokens. Browsa adds no markup and no hosted charge: the task costs its normal task credits only. There are two ways to hand over the key.

  • Per task. Send llm_api_key with the task. It is held encrypted for the run and deleted when the run ends.
  • Saved once. Save the key in your workspace. A task then names it with llm_key_id, or sends no key at all and uses your default saved key for the model's provider. The API never returns a saved key.
from browsa import Client

c = Client(api_key="agt_live_...")

# A key for this task only
job = c.run_task(
    task="Go to news.ycombinator.com and return the top story title.",
    llm="anthropic:claude-sonnet-5-5",
    llm_api_key="sk-ant-...",
)

# A key saved in the workspace, by id
job = c.run_task(
    task="Go to news.ycombinator.com and return the top story title.",
    llm="anthropic:claude-sonnet-5-5",
    llm_key_id="3f6c2a1e-8b4d-4c1f-9a7e-2d5b6c7e8f90",
)

If you send a key and no llm, Browsa picks a default model for that key's provider. Which key wins when several apply, the default model for each provider and the errors a key can return are in the docs: Use a saved key in tasks and How Browsa handles your LLM keys.

OpenAI-compatible servers

To run a task on a gateway such as OpenRouter or LiteLLM, or on a model you serve yourself, add llm_base_url. Browsa sends the model requests to that address with your key. The same field accepts an Anthropic-compatible endpoint.

  • The address must be a public https URL.
  • It needs your own key: llm_api_key on the task, or a saved key of the provider openai_compatible, which stores its address with the key. A hosted tier always uses Browsa's own endpoint.
  • Set llm to a model name your server accepts. There is no default model for a compatible server.
  • The model must support tool calling (also called function calling). Agents act through tool calls, and this is checked before a browser starts.
from browsa import Client

c = Client(api_key="agt_live_...")
job = c.run_task(
    task="Go to example.com and report the H1.",
    llm="openai:my-model",
    llm_api_key="sk-...",
    llm_base_url="https://llm.example.com/v1",
)
print(job.final_result)

Model names

With your own key, llm is the provider's model name. Three forms are accepted and mean the same thing.

FormExampleNotes
Bare name
"claude-sonnet-5-5"
The provider is read from the name: claude- names go to Anthropic. Fine for well-known model families.
provider:model
"anthropic:claude-sonnet-5-5"
Says which provider to call. The clearest form, and the one these docs use.
provider/model
"anthropic/claude-sonnet-5-5"
The same, in the slash style many gateways and tools use.

The provider part is removed before the request is sent, so your provider sees the plain model name. The three tier names browsa, browsa-fast and browsa-smart are not provider models: they select a hosted tier.

Reasoning

reasoning is an optional field that asks the model to think less or more before each step. It takes "low", "medium" or "high", and it works on a task, on a session message and on a schedule.

You sendWhat happens
Nothing
A hosted tier uses its own level (the Reasoning line of each tier above). With your own key, the provider's default applies.
"low", "medium" or "high"
That level is used for the run, on a hosted tier or on your own key.
A level, on a model that has no such setting
The field is ignored, the task runs, and result.warnings says so.
Any other value
400 BAD_REQUEST. Nothing is started or charged.
from browsa import Client

c = Client(api_key="agt_live_...")
job = c.run_task(
    task="Compare the three cheapest plans on example.com/pricing and say which fits a team of 5.",
    llm="browsa-smart",
    reasoning="medium",
)
print(job.final_result)

A higher level makes the model produce more tokens per step. On your own key that is more on your provider's bill. On a hosted tier the credits per task do not change with the level.

Usage and cost

A finished task reports what the model used. The fields are in the job's result, from GET /v1/jobs/{id}. All of them are optional: jobs that ran before these fields existed have none, so read them defensively.

FieldWhat it holds
usage
Token counts for the whole run: input_tokens, output_tokens, cache_read_tokens, cache_write_tokens, and requests, the number of calls made to the model.
llm_cost_usd
An estimate of what the model cost in US dollars, worked out from the provider's public list prices. null when the price of the model is not known, and always null on a hosted tier, which is paid in credits.
llm_tier
The hosted tier the run used. Present on hosted runs only.
reasoning
The reasoning level that was applied.
JSON
{
  "status": "completed",
  "credits_charged": 4,
  "result": {
    "final_result": "Top story: ...",
    "usage": {
      "input_tokens": 48210,
      "output_tokens": 1904,
      "cache_read_tokens": 31500,
      "cache_write_tokens": 6200,
      "requests": 9
    },
    "llm_cost_usd": 0.0612,
    "reasoning": "medium"
  }
}

The cost is an estimate. It uses list prices, so a negotiated rate, a gateway's own pricing or a batch discount will not show in it. Your provider's invoice is the real figure.

Checks before a browser starts

Before Browsa opens a browser for a task, it makes one small call to the model to see that the task can run on it. If that call fails, the job ends at once with a code that says why. No browser was opened, so nothing is charged.

Job codeWhat is wrongWhat to do
LLM_KEY_REJECTED
The provider refuses your key: it is invalid, revoked, out of credit, or belongs to another provider than the model.
Check the key in your provider's console and that it matches the model. A saved key is marked invalid until you rotate it.
MODEL_NO_TOOL_USE
The model answers without a tool call. Agents need tool calling.
Use a model, and an endpoint, that support tool or function calling.
MODEL_RATE_LIMITED
The model is rate limited on every try. On a hosted tier this means every model in the tier is busy.
Run the task again in a few minutes. With your own key, raise the limit with your provider. On a hosted tier you can also switch to your own key.

A problem with the request itself is caught earlier still, when you submit the task: a missing key returns 400 LLM_KEY_REQUIRED, and a reasoning value outside the three levels returns 400. The full list is in Job failure codes and LLM key errors.

Next steps

Run a task on a hosted tier.

100 free credits. No card, no model key.