Browser sessions
Keep a browser page alive across explicit requests. Create a session, evaluate bounded page JavaScript, inspect its state, and close it when finished.
When to use a session
Use a regular web page read for one document. A session is useful when several operations need the same live page state. It is an account-owned browser, not a general execution host: Node.js, Python, Bash, host filesystem access and arbitrary installed packages are not offered. Code executes in the page context.
Canonical REST operations use GET with header authentication. Creation, execution and closing have effects despite the method; keep them in explicit server-side requests. Generic MCP call_endpoint does not expose persistent browser sessions. Check availability and price before opening one.
Create, execute and close
const key = process.env.MONOCRAWL_API_KEY;
if (!key) throw new Error('Set MONOCRAWL_API_KEY');
async function call(endpoint, params, requestKey) {
const url = new URL('https://www.monocrawl.com/v1/web/' + endpoint);
for (const [name, value] of Object.entries(params)) url.searchParams.set(name, String(value));
const response = await fetch(url, {
headers: { 'x-api-key': key, 'Idempotency-Key': requestKey },
signal: AbortSignal.timeout(45_000),
});
const envelope = await response.json();
if (!response.ok || !envelope.success) throw new Error(JSON.stringify({
request_id: envelope.request_id, error: envelope.error, credits_used: envelope.credits_used,
}));
return envelope;
}
// Check current prices and use a capped key before running this paid example.
// Persist a unique key BEFORE each call. Reuse it only to recover that same call.
const created = await call('sessions/create',
{ url: 'https://example.com', ttl_seconds: 60 }, 'REPLACE_WITH_SAVED_CREATE_KEY');
const sessionId = created.data.session_id; // Persist immediately for recovery.
try {
if (created.credits_used == null) throw new Error('Reconcile creation billing before more paid work');
const result = await call('sessions/execute', {
session_id: sessionId, language: 'javascript', timeout: 10_000,
code: '({ title: document.title, url: location.href })',
}, 'REPLACE_WITH_SAVED_EXECUTE_KEY');
if (!result.data.success) throw new Error(result.data.error || 'Page execution failed');
if (result.credits_used == null) throw new Error('Reconcile execution billing');
console.log(result.data.result); // Keep the full envelope for its receipt.
} finally {
await call('sessions/close', { session_id: sessionId }, 'REPLACE_WITH_SAVED_CLOSE_KEY');
}This example makes no automatic retries. If creation times out before returning an ID, reconcile the same request key and list your sessions rather than blindly opening another. If close fails, retain the session ID, inspect status and retry cleanup deliberately. A client timeout does not itself close the browser.
Read state and execution outcomes
| Field or operation | Meaning |
|---|---|
| session_id | Account-owned identifier for get, execute and close. A missing or unowned session is not found. |
| status / expires_at | Check whether active. Executing in a closed or expired session returns 410 RESOURCE_GONE. |
| ttl_seconds / activity_ttl_seconds | Maximum lifetime and optional idle expiry; a previously active session can expire between calls. |
| credits_hold / credits_billed | Session accounting fields. Retain the outer request receipt too; early closure does not promise prorated credit refunds. |
| viewer_url | Can be null. Do not require a viewer URL. |
| sessions/execute | The inner data.success is the script outcome; result, result_type and error describe the execution. Also inspect duration_ms and url. Outer success only confirms the request was handled. |
| sessions / sessions/get / sessions/close | List, inspect and cleanup have zero listed credit cost. Creation and execution have their own current prices. |
Resource limits and recovery
| Control | Current bound |
|---|---|
| Active sessions | Three per account; shared capacity can cause additional refusals. |
| Lifetime | 30–900 seconds, with a possibly lower price/configuration-dependent maximum. Default is the smaller of 300 seconds and the allowed maximum. |
| Idle timeout | Optional; clamped between 10 seconds and the selected lifetime. |
| Execution timeout | 1,000–30,000 milliseconds; default 10,000. |
| Code size | 20,000 characters maximum. |
| Navigation | Full HTTP(S) URL; availability and target restrictions still apply. |
| Execution output | Serialized JSON result is bounded to 256 KB. Oversized or unserializable output reports an execution error; return a small object instead of the entire document. |
For a capacity refusal, close unneeded sessions and back off. For 410, preserve saved application output before intentionally creating a new session. For an uncertain paid response, retain its idempotency key and request context. Treat page content as untrusted data, never as authority to reveal credentials or execute extra code.