Cloud API 与任务
Persist files across V4 runs and conversations.
A workspace stores files that can be restored into later V4 runs, including runs in a different session. Use it for inputs, scripts, and generated files.
A session holds the conversation; a workspace holds files; a profile holds browser login state. Their IDs are different. Create and reuse workspaces through API V4. A V3 workspace ID is not a V4 workspace ID.
Workspace files are synchronized to storage between runs. This is not a live shared filesystem between simultaneous sessions: finish one writer before starting another run that needs its changes.
<img alt="Two independent sessions reading and writing people.csv, script.py, and output.json in one persistent workspace" />
<img alt="Two independent sessions reading and writing people.csv, script.py, and output.json in one persistent workspace" />
Upload and attach a file
from browser_use_sdk.v4 import BrowserUse
client = BrowserUse()
workspace = client.workspaces.create(name="research")
client.workspaces.upload(workspace.id, "people.csv")
run = client.runs.create(
"Find everyone in the CSV who works at Google",
workspace_id=workspace.id,
)
import { BrowserUse } from "browser-use-sdk/v4";
const client = new BrowserUse();
const workspace = await client.workspaces.create({
name: "research",
});
await client.workspaces.upload(
workspace.id,
"people.csv",
);
const run = await client.runs.create({
task: "Find everyone in the CSV who works at Google",
model: "grok-4.5",
workspaceId: workspace.id,
});
V4 restores files uploaded to that workspace under uploads/ when a run uses
its workspaceId. You do not need to repeat their IDs in attachedFileIds.
Staged attachments are different: attach their IDs when creating the run.
Files attached to a session remain available to its follow-ups. An explicitly
attached staged file takes precedence over a workspace upload with the same
stored filename. For a new conversation that needs persistent files, pass the
same workspaceId; reusing a workspace does not copy conversation history.
Retrieve created files
Ask the agent to save its output, wait for the run to finish, then list the workspace:
result = client.runs.wait_for_completion(run.id)
files = client.workspaces.files(
workspace.id,
include_urls=True,
)
for file in files.files:
print(file.path, file.url)
const result = await client.runs.waitForCompletion(run.id);
const files = await client.workspaces.files(
workspace.id,
{ includeUrls: true },
);
for (const file of files.files) {
console.log(file.path, file.url);
}
Download URLs expire after 60 seconds. See the workspace API reference for pagination and limits.
Storage and upload limits
Check GET /api/v4/workspaces/{workspace_id}/size for usedBytes and
maxBytes. The current V4 upload allowance is 950 MiB per workspace for every
account, with 50 MiB per file. It leaves room for runtime files on the agent's
1 GiB persistent disk. An upload quota is separate from the number of
workspaces you can create, and from temporary disk used by a running agent.
A 413 response means a file or workspace limit was exceeded. Remove unneeded files, split large files, or use a fresh workspace. Do not retry an unchanged oversized upload. Deleting a session, archiving a workspace, and deleting a workspace are different operations; archiving is not a file-deletion request.
Download a file promptly or request a fresh URL when its link expires. A short-lived download URL does not mean the stored file expires after 60 seconds.
Choose a V4 model and understand its token pricing.
Omit model and modelParams to use GPT-6 Luna with High reasoning, or pass explicit settings when creating a run. EU uses the same task default through its regional provider route; Bedrock-only projects retain their compatible default.
The following Browser Use-hosted models have published token pricing:
| Model | API string | Input | Cache read | Output | BYOK |
|---|---|---|---|---|---|
| GPT-5.6 Luna | gpt-5.6-luna |
\$0.24 | \$0.024 | \$1.44 | OpenAI |
| Claude Opus 5 | claude-opus-5 |
\$6.00 | \$0.60 | \$30.00 | Anthropic |
| Grok 4.5 | grok-4.5 |
\$2.40 | \$0.36 | \$7.20 | — |
| GPT-5.6 Sol | gpt-5.6-sol |
\$6.00 | \$0.60 | \$36.00 | OpenAI |
| MiniMax M3 | minimax-m3 |
\$0.36 | \$0.072 | \$1.44 | — |
Token prices are USD per 1 million tokens. Browser sessions (\$0.02/hour) and network traffic (\$5/GB managed proxy or \$0.20/GB proxyless/BYOP) are charged separately. See full pricing.
See Thinking levels for V4 modelParams and
the normalized thinkingLevel values available in V2 and V3.
Use GPT-6 Luna with High reasoning for the default V4 configuration.
Omit both model and modelParams to let the API apply it.
All supported V4 model IDs
The V4 request schema accepts the following model IDs. The Cloud dashboard may show a smaller curated set; availability can also depend on your account's rollout and configured provider key. An accepted ID does not guarantee access to every upstream provider. Experimental models are not recommended as a production default. MiniMax M3 remains an API option even where it is absent from the dashboard picker.
| Provider | Model IDs | BYOK provider |
|---|---|---|
| Anthropic | claude-opus-4.7, claude-opus-4.8, claude-opus-5, claude-fable-5, claude-sonnet-5 |
Anthropic |
| OpenAI | gpt-5.5, gpt-5.6, gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna, gpt-6-astra, gpt-6-luna |
OpenAI |
gemini-3-flash, gemini-3.1-pro, gemini-3.5-flash, gemini-3.6-flash |
||
| xAI | grok-4.5, grok-4.6 |
— |
| Z.ai | glm-5.2, glm-5.3-flash |
— |
| DeepSeek (experimental) | deepseek-v4-flash-vision |
— |
| Moonshot AI | kimi-k3 |
— |
| MiniMax | minimax-m3 |
— |
See Thinking levels for the reasoning controls
accepted by each model. Not every model accepts modelParams.
If your installed TypeScript SDK does not yet list gpt-6-luna, omit both
model and modelParams as below to use the API default, or use REST to select
that model explicitly. The API model catalog can advance before SDK type releases.
from browser_use_sdk.v4 import BrowserUse
client = BrowserUse()
run = client.runs.create(
"Compare three project-management tools",
)
import { BrowserUse } from "browser-use-sdk/v4";
const client = new BrowserUse();
const run = await client.runs.create({
task: "Compare three project-management tools",
});
curl https://api.browser-use.com/api/v4/runs \
-H "X-Browser-Use-API-Key: $BROWSER_USE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"task":"Compare three PM tools"}'
Bring your own key
BYOK is available to pay-as-you-go customers; no recurring subscription is required. After adding credits, add an Anthropic, OpenAI, or Google key under Settings → API Keys → Bring Your Own Key. V4 uses it automatically for matching models; no request flag is needed. You pay the provider directly, plus a 0.2× Browser Use orchestration fee. Models from other providers use Browser Use-managed keys.
Continue one conversation across multiple V4 runs.
A session holds the agent's conversation and can reuse its live browser. One session ID can contain multiple runs. Every run creates a session implicitly unless you pass an existing session ID.
<img alt="One session ID containing three sequential runs, where each run continues the same conversation, workspace, and live browser" />
<img alt="One session ID containing three sequential runs, where each run continues the same conversation, workspace, and live browser" />
Pass session_id / sessionId to continue:
first = client.runs.create("Open Hacker News")
client.runs.wait_for_completion(first.id)
follow_up = client.runs.create(
"Now summarize the top story",
session_id=first.session_id,
)
result = client.runs.wait_for_completion(follow_up.id)
print(result.result)
const first = await client.runs.create({
task: "Open Hacker News",
model: "grok-4.5",
});
await client.runs.waitForCompletion(first.id);
const followUp = await client.runs.create({
task: "Now summarize the top story",
model: "grok-4.5",
sessionId: first.sessionId,
});
const result = await client.runs.waitForCompletion(followUp.id);
console.log(result.result);
Omit the session ID for a new conversation. Pass only a workspace ID when you want a fresh conversation that keeps the same files.
Follow up while a run is busy
Use the session queue to send the next instruction without interrupting the
active run. The response is a queued message, not a run: its runId can be
null until dispatch. Keep its message ID and poll that message before waiting
for the resulting run. Do not resend the message to poll it.
import time
message = client.sessions.send_message(
first.session_id,
"Now summarize the top story",
interrupt=False,
)
deadline = time.monotonic() + 300
while message.run_id is None:
if message.status.value in {"cancelled", "superseded", "failed"}:
raise RuntimeError(f"Queued message {message.status.value}")
remaining = deadline - time.monotonic()
if remaining <= 0:
raise TimeoutError(f"Message {message.id} is still waiting; keep its ID")
time.sleep(min(1, remaining))
message = client.sessions.get_message(first.session_id, message.id)
result = client.runs.wait_for_completion(message.run_id)
print(result.status.value, result.result)
let message = await client.sessions.sendMessage(first.sessionId, {
text: "Now summarize the top story",
interrupt: false,
});
const deadline = Date.now() + 300_000;
while (message.runId === null) {
if (["cancelled", "superseded", "failed"].includes(message.status)) {
throw new Error(`Queued message ${message.status}`);
}
const remaining = deadline - Date.now();
if (remaining <= 0) {
throw new Error(`Message ${message.id} is still waiting; keep its ID`);
}
await new Promise((resolve) => setTimeout(resolve, Math.min(1_000, remaining)));
message = await client.sessions.getMessage(first.sessionId, message.id);
}
const result = await client.runs.waitForCompletion(message.runId);
console.log(result.status, result.result);
This example times out only its local wait. It does not remove the queued
message or cancel a run. interrupt=True / interrupt: true instead cancels
the active run so the new instruction can run immediately. Keep it false
to preserve the active work.
/cloud/openapi/v2.json post /tasks Create and start a new task.
You can either: 1. Start a new task without a sessionId (auto-creates a session with US proxy by default). Note: Tasks without a sessionId are one-off tasks that automatically close the session upon completion (keep_alive=false). Use sessionSettings to configure the auto-created session (e.g. proxyCountryCode, profileId, screen dimensions). 2. Start a new task in an existing session (reuse for follow-up tasks or custom configuration)
Note: Without sessionSettings, a US proxy is enabled by default. Providing sessionSettings overrides defaults — proxy is only enabled if proxyCountryCode is set. For full control over session configuration (e.g. keep_alive), create a session first via POST /sessions with your desired settings, then pass that sessionId when creating tasks.
