This guide explains how to use the screenshot endpoint in the Studio Web API server to capture screenshots of the current browser page.
The screenshot endpoint captures a screenshot of the current browser viewport and returns it as base64-encoded PNG data along with metadata about the current page.
You must set one of the following API keys in your environment:
ANTHROPIC_API_KEY- For using Anthropic's Claude modelsOPENAI_API_KEY- For using OpenAI's models
PORT- Server port (default: 5553)
- Make sure you have the required environment variables set:
export ANTHROPIC_API_KEY="your-api-key-here"
# OR
export OPENAI_API_KEY="your-api-key-here"- Start the server:
npm start
# or
node dist/server.jsThe server will start on port 5553 by default.
GET /screenshot
None required. The endpoint accepts no query parameters or request body.
- The endpoint automatically starts a browser session if one isn't already running
- It waits for the page to be stable before taking the screenshot
- Default viewport size: 1500x800 pixels
{
"success": true,
"data": "iVBORw0KGgoAAAANSUhEUgAAA...", // Base64-encoded PNG data
"encoding": "base64",
"mimeType": "image/png",
"current_url": "https://example.com",
"current_title": "Example Page Title"
}{
"success": false,
"error": "Error message describing what went wrong",
"details": "Stack trace (in development mode)"
}curl -X GET http://localhost:5553/screenshotasync function takeScreenshot() {
try {
const response = await fetch('http://localhost:5553/screenshot');
const data = await response.json();
if (data.success) {
console.log('Current URL:', data.current_url);
console.log('Page Title:', data.current_title);
// Convert base64 to image file
const buffer = Buffer.from(data.data, 'base64');
require('fs').writeFileSync('screenshot.png', buffer);
console.log('Screenshot saved as screenshot.png');
} else {
console.error('Error:', data.error);
}
} catch (error) {
console.error('Request failed:', error);
}
}
takeScreenshot();import requests
import base64
def take_screenshot():
try:
response = requests.get('http://localhost:5553/screenshot')
data = response.json()
if data['success']:
print(f"Current URL: {data['current_url']}")
print(f"Page Title: {data['current_title']}")
# Save screenshot to file
image_data = base64.b64decode(data['data'])
with open('screenshot.png', 'wb') as f:
f.write(image_data)
print("Screenshot saved as screenshot.png")
else:
print(f"Error: {data['error']}")
except Exception as e:
print(f"Request failed: {e}")
take_screenshot()async function takeScreenshot() {
try {
const response = await fetch('http://localhost:5553/screenshot');
const data = await response.json();
if (data.success) {
// Display the screenshot in an img element
const img = document.createElement('img');
img.src = `data:${data.mimeType};${data.encoding},${data.data}`;
img.alt = `Screenshot of ${data.current_title}`;
document.body.appendChild(img);
console.log('Current URL:', data.current_url);
console.log('Page Title:', data.current_title);
} else {
console.error('Error:', data.error);
}
} catch (error) {
console.error('Request failed:', error);
}
}For real-time monitoring, you can poll the endpoint at regular intervals:
class ScreenshotStreamer {
constructor(intervalMs = 1000) {
this.intervalMs = intervalMs;
this.intervalId = null;
this.isStreaming = false;
}
async fetchScreenshot() {
try {
const response = await fetch('http://localhost:5553/screenshot');
const data = await response.json();
if (data.success) {
// Update your UI with the new screenshot
this.onScreenshotReceived(data);
}
} catch (error) {
console.error('Error fetching screenshot:', error);
}
}
startStreaming() {
if (this.isStreaming) return;
this.isStreaming = true;
this.fetchScreenshot(); // Initial fetch
this.intervalId = setInterval(() => {
this.fetchScreenshot();
}, this.intervalMs);
}
stopStreaming() {
if (this.intervalId) {
clearInterval(this.intervalId);
this.intervalId = null;
}
this.isStreaming = false;
}
onScreenshotReceived(data) {
// Override this method to handle screenshot updates
console.log('New screenshot received for:', data.current_url);
}
}
// Usage
const streamer = new ScreenshotStreamer(1000); // 1 second interval
streamer.onScreenshotReceived = (data) => {
// Update your image element
document.getElementById('screenshot').src =
`data:${data.mimeType};${data.encoding},${data.data}`;
};
streamer.startStreaming();The screenshot endpoint works well with other browser control endpoints:
// First navigate to a page
await fetch('http://localhost:5553/goto', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url: 'https://example.com' })
});
// Then take a screenshot
const screenshot = await fetch('http://localhost:5553/screenshot');// Perform an action
await fetch('http://localhost:5553/act', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
action: 'click the search button',
action_type: 'click'
})
});
// Take a screenshot to see the result
const screenshot = await fetch('http://localhost:5553/screenshot');The endpoint automatically saves screenshots to a local screenshots/ directory with randomly generated filenames. These files are saved asynchronously and won't affect the API response time.
The server provides a pre-built React component for streaming screenshots:
# Access the component code at:
curl http://localhost:5553/chrome-streamer-componentThis component includes:
- Start/stop streaming controls
- Click-to-interact functionality
- Real-time URL display
-
Browser fails to start
- Ensure you have the required API key environment variable set
- Check that Chrome/Chromium is installed on your system
-
Screenshot endpoint returns 500 error
- Check server logs for specific error messages
- Ensure the browser session is healthy by calling
/start_browserfirst
-
Long response times
- The endpoint waits for page stability before capturing
- Complex pages with ongoing animations may take longer
Before taking screenshots, you can verify the browser is running:
const healthCheck = await fetch('http://localhost:5553/start_browser', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
});- Screenshots are captured at CSS scale with animations disabled
- Viewport-only captures (not full page) for faster performance
- Network idle state waiting has a 5-second timeout
- Base64 encoding adds ~33% to the data size
- The endpoint doesn't require authentication by default
- Screenshots may contain sensitive information visible in the browser
- Consider implementing access controls for production use
- Local screenshot files are automatically cleaned up by other endpoints
- Explore the
/actendpoint for browser automation - Use
/gotofor navigation - Check
/start_browserfor browser configuration options - Review the React component for interactive screenshot streaming