Sessions
Manage browser sessions for multi-step workflows with WebUplink.
Sessions
Sessions are short-lived browser contexts that let your agent navigate multi-page workflows. Within a session, cookies, auth state, and navigation history carry across calls; sessions are ephemeral and expire on the timeouts below.
Creating a Session
A new session is created automatically when you browse a URL:
const page = await client.browse('https://stackoverflow.com');
const sessionId = page.session_id; // Use for follow-up calls within this taskMulti-Step Workflow
Scope session reuse to a single short task — open, do the steps, close:
// Step 1: Open the site
const page = await client.browse('https://stackoverflow.com');
// Step 2: Search
const results = await client.browse({
session_id: page.session_id,
tool: 'search_questions',
params: { q: 'rust lifetimes' },
});
// Step 3: Open a result
const question = await client.browse({
session_id: page.session_id,
tool: 'navigate_to_question',
params: { url: 'https://stackoverflow.com/questions/11227809' },
});
// Step 4: Clean up
await client.closeSession(page.session_id);Sessions are ephemeral — don't hold a session_id across tasks or persist it anywhere. A follow-up call can return SESSION_NOT_FOUND (404) or SESSION_EXPIRED (410) at any time; handle either by starting a fresh session, not by retrying the old one.
Session lifetime & re-authentication
| Timeout | Duration | Behavior |
|---|---|---|
| Idle | ~5 minutes | Auto-expires after no requests |
| Hard cap | ~15 minutes | Auto-expires regardless of activity |
Every response carries expires_at (ISO 8601) — the exact instant the session expires if you make no further request. It moves forward with each call as the idle window refreshes, and stops moving once the hard cap becomes the nearer bound, so you never have to infer the deadline from the durations above:
const page = await client.browse('https://example.com');
page.expires_at; // "2026-08-11T23:19:50.087Z"Both caps are flat across all plans, and when a session expires its cookies and auth state are destroyed with it. The recommended pattern:
- Complete one task within one session — log in if the task needs it, do the steps, read the result.
- Close the session when the task is done.
- Start a fresh session for the next task — and execute the login tool again if that task needs auth. See the Authentication guide.
Don't poll or ping a session to keep it alive. Every /v1/browse call — including an observe-only call with a session_id — bills at least one action, so a keepalive loop burns quota and never lifts the ~15-minute cap anyway.
Concurrent Sessions
An agent can hold multiple sessions simultaneously:
// Two independent browser sessions
const github = await client.browse('https://github.com');
const docs = await client.browse('https://docs.example.com');
// Each has its own cookies, auth state, and historyConcurrency is plan-limited: 1 session on Free, 15 on Builder (and the trial), 30 on Pro. At the limit, new sessions return CONCURRENCY_EXCEEDED (503, retryable) until a slot frees up — close sessions you're done with, or see pricing for higher limits.
Closing Sessions
Always close sessions when done to free browser resources:
await client.closeSession(sessionId);Sessions auto-expire on idle timeout, but explicit cleanup releases resources immediately and is especially important during batch workflows.