> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gravixlayer.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Browser Sessions

> Open, navigate, and manage browsers and tabs inside a runtime

A browser is a managed Chromium instance inside the runtime — real engine,
real rendering, real network stack. `open` starts one and returns a
`browser_id`; each browser owns one or more **targets** (tabs), and every page
operation takes a `browser_id` plus an optional `target_id` (empty means the
current tab).

CLI and cURL examples assume `$RT` holds a `browser-small` runtime id (see
[Overview](/documentation/agentruntime/browser-use/overview#requirements)). The
first browser opened in a runtime is `b1`.

## Endpoints

| Method | Path | Description |
| - | - | - |
| POST | `/v1/agents/runtime/{runtime_id}/browser/open` | Start a browser |
| GET | `/v1/agents/runtime/{runtime_id}/browser` | List browsers |
| GET | `/v1/agents/runtime/{runtime_id}/browser/{browser_id}/status` | Browser state + tabs |
| POST | `/v1/agents/runtime/{runtime_id}/browser/{browser_id}/close` | Stop a browser |
| POST | `/v1/agents/runtime/{runtime_id}/browser/{browser_id}/navigate` | Go to a URL |
| POST | `/v1/agents/runtime/{runtime_id}/browser/{browser_id}/back` | History back |
| POST | `/v1/agents/runtime/{runtime_id}/browser/{browser_id}/forward` | History forward |
| POST | `/v1/agents/runtime/{runtime_id}/browser/{browser_id}/reload` | Reload the page |
| POST | `/v1/agents/runtime/{runtime_id}/browser/{browser_id}/targets` | List tabs, or open a new one |
| POST | `/v1/agents/runtime/{runtime_id}/browser/{browser_id}/activate` | Make a tab the current tab |

## Open, list, status, close

`open` starts a browser — headed on the display when the display is enabled,
headless otherwise; pass `headless: true` to force headless. `status` returns
`{browser_id, state, targets}`; `list` returns every browser in the runtime
(`{browsers: [...]}` on the wire). `close` stops the browser.

```python Python theme={"dark"}
from gravixlayer import GravixLayer

client = GravixLayer()  # reads GRAVIXLAYER_API_KEY
sandbox = client.runtime.create(template="browser-small")

browser = sandbox.browser.open(url="https://example.com")   # b1
bid = browser["browser_id"]
print(sandbox.browser.status(bid)["state"])  # running

# A second, headless browser — then close it
other = sandbox.browser.open(headless=True)                  # b2
print([b["browser_id"] for b in sandbox.browser.list()["browsers"]])
sandbox.browser.close(other["browser_id"])
sandbox.kill()
```

```typescript TypeScript theme={"dark"}
import { GravixLayer } from 'gravixlayer';

const client = new GravixLayer(); // reads GRAVIXLAYER_API_KEY
const sandbox = await client.runtime.create({ template: 'browser-small' });

const browser = await sandbox.browser.open({ url: 'https://example.com' }); // b1
const bid = browser.browserId;
console.log((await sandbox.browser.status(bid)).state); // running

// A second, headless browser — then close it
const other = await sandbox.browser.open({ headless: true });               // b2
console.log((await sandbox.browser.list()).map((b) => b.browserId));
await sandbox.browser.close(other.browserId);
await sandbox.kill();
```

```bash CLI theme={"dark"}
gravixlayer runtime browser open "$RT" --url https://example.com   # b1
gravixlayer runtime browser status "$RT" --browser b1

gravixlayer runtime browser open "$RT" --headless                  # b2
gravixlayer runtime browser list "$RT"
gravixlayer runtime browser close "$RT" --browser b2
```

```bash cURL theme={"dark"}
API="https://api.gravixlayer.ai/v1"

curl -sS -X POST "$API/agents/runtime/$RT/browser/open" \
  -H "Authorization: Bearer $GRAVIXLAYER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com"}'

curl -sS "$API/agents/runtime/$RT/browser/b1/status" \
  -H "Authorization: Bearer $GRAVIXLAYER_API_KEY"

curl -sS -X POST "$API/agents/runtime/$RT/browser/open" \
  -H "Authorization: Bearer $GRAVIXLAYER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"headless":true}'

curl -sS "$API/agents/runtime/$RT/browser" \
  -H "Authorization: Bearer $GRAVIXLAYER_API_KEY"

curl -sS -X POST "$API/agents/runtime/$RT/browser/b2/close" \
  -H "Authorization: Bearer $GRAVIXLAYER_API_KEY"
```

The rest of this page, and the CLI and cURL examples on the following pages,
use the `b1` browser opened here.

**Open parameters**

| Parameter | Type | Required | Description |
| - | - | - | - |
| `url` | string | No | Initial URL — any scheme Chromium loads, including `data:` |
| `headless` | bool | No | Force headless (default `false`; headless anyway when the display is off) |
| `engine` | string | No | `chromium` (default and only engine — `firefox` returns `501`) |
| `profile_dir` | string | No | Guest path for the browser profile; reuse it across `open` calls to keep cookies and storage |
| `args` | array | No | Extra Chromium flags — `--remote-debugging-*` and `--remote-allow-origins` are rejected with `400` |

Returns a [`BrowserInfo`](/documentation/agentruntime/browser-use/overview#objects).
The CLI's `open` exposes `--url` and `--headless`.

## Navigate and history

`navigate` loads a URL in a tab (empty `target_id` = current tab) and waits
per `wait_until`. `back`, `forward`, and `reload` take the same optional
`target_id`.

```python Python theme={"dark"}
from gravixlayer import GravixLayer

client = GravixLayer()
sandbox = client.runtime.create(template="browser-small")
bid = sandbox.browser.open()["browser_id"]

r = sandbox.browser.navigate(bid, "https://example.com",
                             wait_until="load", timeout_ms=30_000)
print(r["url"], r["title"], r["status"], r["navigated"], r["settled"])

sandbox.browser.navigate(bid, "https://example.org")
sandbox.browser.back(bid)
sandbox.browser.forward(bid)
sandbox.browser.reload(bid)
sandbox.kill()
```

```typescript TypeScript theme={"dark"}
import { GravixLayer } from 'gravixlayer';

const client = new GravixLayer();
const sandbox = await client.runtime.create({ template: 'browser-small' });
const bid = (await sandbox.browser.open()).browserId;

const r = await sandbox.browser.navigate(bid, 'https://example.com', {
  waitUntil: 'load',
  timeoutMs: 30_000,
});
console.log(r.url, r.title, r.status, r.navigated, r.settled);

await sandbox.browser.navigate(bid, 'https://example.org');
await sandbox.browser.command(bid, 'back');
await sandbox.browser.command(bid, 'forward');
await sandbox.browser.command(bid, 'reload');
await sandbox.kill();
```

```bash CLI theme={"dark"}
gravixlayer runtime browser navigate "$RT" --browser b1 https://example.com \
  --wait-until load --timeout-ms 30000

gravixlayer runtime browser command "$RT" --browser b1 back
gravixlayer runtime browser command "$RT" --browser b1 forward
gravixlayer runtime browser command "$RT" --browser b1 reload
```

```bash cURL theme={"dark"}
API="https://api.gravixlayer.ai/v1"

curl -sS -X POST "$API/agents/runtime/$RT/browser/b1/navigate" \
  -H "Authorization: Bearer $GRAVIXLAYER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com","wait_until":"load","timeout_ms":30000}'

curl -sS -X POST "$API/agents/runtime/$RT/browser/b1/back" \
  -H "Authorization: Bearer $GRAVIXLAYER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"target_id":""}'
```

**Navigate parameters**

| Parameter | Type | Required | Description |
| - | - | - | - |
| `url` | string | Yes | Destination URL |
| `target_id` | string | No | Tab to navigate (empty = current tab) |
| `wait_until` | string | No | `load` (default), `domcontentloaded`, `networkidle`, or `commit` |
| `timeout_ms` | int | No | Navigation timeout (default 30000) |

Returns `{url, title, status, navigated, settled}` — `status` is the HTTP
status of the response. `back`, `forward`, `reload`, and `activate` return
the tab's `BrowserTargetInfo`.

## Tabs — targets and activate

`targets` lists a browser's tabs. Pass `url` to open a new tab — the response's
`target_id` is the new tab. A new tab does not become current on its own:
call `activate` to make it the default for calls without a `target_id`, or
pass `target_id` to any page call (snapshot, screenshot, actions, evaluate).

```python Python theme={"dark"}
from gravixlayer import GravixLayer

client = GravixLayer()
sandbox = client.runtime.create(template="browser-small")
bid = sandbox.browser.open(url="https://example.com")["browser_id"]

# Open a second tab — the low-level call accepts url
tab = client.runtime.browser.targets(sandbox.runtime_id, bid, url="https://example.org")
tid = tab["target_id"]

for t in sandbox.browser.targets(bid)["targets"]:
    print(t["target_id"], t["url"])

sandbox.browser.activate(bid, tid)            # tid is now the current tab
print(sandbox.browser.snapshot(bid)["url"])   # https://example.org/
sandbox.kill()
```

```typescript TypeScript theme={"dark"}
import { GravixLayer } from 'gravixlayer';

const client = new GravixLayer();
const sandbox = await client.runtime.create({ template: 'browser-small' });
const bid = (await sandbox.browser.open({ url: 'https://example.com' })).browserId;

// Open a second tab
const { targetId } = await sandbox.browser.targets(bid, { url: 'https://example.org' });

for (const t of (await sandbox.browser.targets(bid)).targets) {
  console.log(t.targetId, t.url);
}

await sandbox.browser.command(bid, 'activate', targetId); // now the current tab
console.log((await sandbox.browser.snapshot(bid)).url);   // https://example.org/
await sandbox.kill();
```

```bash CLI theme={"dark"}
gravixlayer runtime browser targets "$RT" --browser b1

TID=$(gravixlayer runtime browser targets "$RT" --browser b1 --output json \
  | jq -r '.targets[0].target_id')
gravixlayer runtime browser command "$RT" --browser b1 activate --target "$TID"
```

```bash cURL theme={"dark"}
API="https://api.gravixlayer.ai/v1"

# Open a new tab — omit "url" (send {}) to just list
TID=$(curl -sS -X POST "$API/agents/runtime/$RT/browser/b1/targets" \
  -H "Authorization: Bearer $GRAVIXLAYER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.org"}' | jq -r .target_id)

curl -sS -X POST "$API/agents/runtime/$RT/browser/b1/activate" \
  -H "Authorization: Bearer $GRAVIXLAYER_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"target_id\":\"$TID\"}"
```

`targets` returns `{target_id, targets}` — `target_id` is the tab just opened
(empty when listing). The CLI lists tabs; open new ones through an SDK or
cURL.

## Notes

* `sandbox.browser.goto(url)` is the fast path — it opens a browser on first
  use, navigates it, and reuses it on later calls. Use `open` when you need
  the id up front or a second browser.
* A `browser_id` stays valid until `close` or the runtime is killed. Each
  `open` starts a new instance with new tabs; without `profile_dir` it also
  starts from an empty profile.
* If the browser process dies, `status` reports `exited` and page calls
  return `400` — call `open` again rather than retrying.
* Headless browsers still produce snapshots, screenshots, PDFs, and
  downloads — everything except a window on the display.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.