Session Replay
This guide covers how to enable Session Replay for your BQL sessions, view the recordings, and understand its limitations. It also explains how Session Replay differs from BaaS Screen Recording.
- A paid Browserless plan (Prototyping, Starter, Scale, or Enterprise) — Session Replay is not available on the free plan
- A Browserless API token from your account dashboard
What is Session Replay

Session Replay captures BQL sessions as interactive replays viewable in your Browserless dashboard. Using RRWeb technology, it records DOM mutations, mouse movements, clicks, scrolling, keyboard input, console logs, and network requests. The recordings are lightweight and can be played back at any speed.
This is different from Screen Recording (record=true), which captures WebM video files and is only available for BaaS connections, not BQL.
Use Session Replay for debugging BQL automation workflows, creating visual documentation, and troubleshooting mutations with recorded evidence.
What Gets Recorded
Session Replay captures DOM events (all visual changes to the page), user interactions (mouse movements, clicks, scrolling, keyboard input), console logs (all console output with timestamps), and network requests (HTTP requests and responses).
Recording a Session with BQL
Connection String Configuration
To enable session recording with BQL, add the replay=true parameter to your connection URL. Recording starts automatically when you connect.
https://production-sfo.browserless.io/chromium/bql?token=YOUR_API_TOKEN_HERE&replay=true
When you connect with replay=true, recording begins immediately. There is no need to call a start mutation. The recording continues until the BQL query completes or you explicitly stop it.
Basic Recording Example
- CURL
- JavaScript
- Python
curl --request POST \
--url 'https://production-sfo.browserless.io/chrome/bql?token=YOUR_API_TOKEN_HERE&replay=true' \
--header 'Content-Type: application/json' \
--data '{
"query": "mutation replay {\n goto(url: \"https://www.browserless.io\") {\n time\n }\n click(selector: \"a\") {\n time\n }\n waitForTimeout(time: 2000) {\n time\n }\n}",
"variables": {},
"operationName": "replay"
}'
import fetch from 'node-fetch';
const API_KEY = "YOUR_API_TOKEN_HERE";
const BQL_ENDPOINT = `https://production-sfo.browserless.io/chromium/bql?replay=true&token=${API_KEY}`;
const recordingQuery = `
mutation replay {
goto(url: "https://www.browserless.io") {
time
}
click(selector:"a"){
time
}
waitForTimeout(time:2000){
time
}
}`;
const recordSession = async () => {
const response = await fetch(BQL_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ query: recordingQuery,
"operationName":"replay" })
});
const result = await response.json();
console.log('Recording Result:', JSON.stringify(result, null, 2));
// Session recording automatically stops when the BQL query completes
console.log('Session recorded successfully');
};
recordSession().catch(console.error);
import requests
import json
API_KEY = "YOUR_API_TOKEN_HERE"
BQL_ENDPOINT = f"https://production-sfo.browserless.io/chromium/bql?replay=true&token={API_KEY}"
recording_query = """
mutation RecordSession {
goto(url: "https://www.example.com") {
status
time
}
click(selector: "button.example") {
time
x
y
}
type(selector: "input[name='search']", text: "browserless") {
time
}
waitForSelector(selector: ".search-results") {
time
}
}
"""
def record_session():
response = requests.post(
BQL_ENDPOINT,
headers={
'Content-Type': 'application/json'
},
json={'query': recording_query}
)
result = response.json()
print('Recording Result:', json.dumps(result, indent=2))
# Session recording automatically stops when the BQL query completes
print('Session recorded successfully')
if __name__ == "__main__":
record_session()
Stop Recording Manually
For long-running sessions or when you need precise control over when recording stops, use the stopSessionRecording mutation. This mutation stops the recording and uploads the captured data to your dashboard.
- CURL
- JavaScript
curl --request POST \
--url 'https://production-sfo.browserless.io/chrome/bql?token=YOUR_API_TOKEN_HERE&replay=true' \
--header 'Content-Type: application/json' \
--data '{
"query": "mutation StopRecording {\n goto(url: \"https://www.browserless.io\") {\n status\n time\n }\n waitForTimeout(time: 5000) {\n time\n }\n stopSessionRecording {\n success\n error\n }\n}",
"variables": {},
"operationName": "StopRecording"
}'
import fetch from 'node-fetch';
const API_KEY = "YOUR_API_TOKEN_HERE";
const BQL_ENDPOINT = `https://production-sfo.browserless.io/chromium/bql?replay=true&token=${API_KEY}`;
const recordingQuery = `
mutation StopRecording {
goto(url: "https://www.browserless.io") {
status
time
}
waitForTimeout(time: 5000) {
time
}
stopSessionRecording {
success
error
}
}`;
const recordSession = async () => {
const response = await fetch(BQL_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: recordingQuery,
operationName: "StopRecording"
})
});
const result = await response.json();
console.log('Recording Result:', JSON.stringify(result, null, 2));
if (result.data?.stopSessionRecording?.success) {
console.log('Session recording stopped and uploaded successfully');
}
};
recordSession().catch(console.error);
The stopSessionRecording mutation returns a response with success (boolean indicating if the recording was stopped successfully) and error (error message if the operation failed, null otherwise).
Viewing Replays
After your BQL query completes (or after calling stopSessionRecording), the replay is automatically uploaded and available in your Browserless dashboard. Navigate to the Session Replay section to find your recorded sessions. Each replay includes a timeline showing all captured events, console logs, and network activity.
Navigation Handling
Session Replay automatically handles page navigations within your BQL session. When mutations like goto navigate to a new page, the recording system reinjects the RRWeb recorder and continues capturing events. All data from multiple page navigations is aggregated into a single replay.
Limitations
- Cross-origin iframes may not be fully captured due to browser security restrictions.
- Very long sessions with high DOM activity may produce large replay files.
- WebGL or canvas content may not be perfectly reproduced in playback.
FAQ & Troubleshooting
My session replay is empty or not appearing in the dashboard
Ensure your BQL query completed successfully. If the browser session was terminated before the recording could upload, the replay won't appear. Check that your API token is on a paid plan (Prototyping, Starter, Scale, or Enterprise) — Session Replay isn't available on the free plan.
Can I use Session Replay with BaaS connections?
No. Session Replay is BQL-only. For BaaS connections, use Screen Recording instead, which captures WebM video files.