The Challenge of Automated Website Screenshots
In the modern digital landscape, the ability to capture high-quality, accurate visual representations of web pages is essential. Whether you are building a portfolio, monitoring website changes, or creating social media previews, manual screenshots are simply not scalable. Developers need a reliable Website Screenshot API that can handle the complexities of modern web design, including JavaScript-heavy Single Page Applications (SPAs) and lazy-loaded content.
Many existing services on the market come with heavy baggage: mandatory signups, monthly subscriptions, restrictive API keys, and intrusive watermarks. This is where Webshot changes the game. Webshot is a 100% free, anonymous website screenshot tool that requires no login, no credit card, and no API key. In this guide, we will explore how to integrate the Webshot API into your workflow using Python, Node.js, and PHP.
Understanding the Webshot Engine
Before we dive into the code, it is important to understand what makes Webshot different. Built by Tuxxin, the platform utilizes a robust technology stack consisting of PHP, TiCore, and Node.js. At its core, it leverages Puppeteer paired with the puppeteer-extra-plugin-stealth.
Handling Modern Web Tech
Traditional screenshot tools often fail when encountering modern websites. Because Webshot uses headless Chrome, it can perfectly render:
- JavaScript-heavy SPAs: Frameworks like React, Vue, and Angular are fully executed before the capture.
- Lazy-loaded content: Images and elements that only appear on scroll or after a delay are captured accurately.
- Bot Detection: The stealth plugin ensures that the headless browser remains undetected, allowing for clean captures of public URLs.
The system is designed for transparency and privacy. There is no data retention and no tracking beyond standard GA4 analytics. You can learn more about the implementation on the Webshot blog.
The Webshot API Endpoint
The Webshot API docs describe a simple, single-endpoint architecture. To capture a screenshot, you send a POST request to the following URL:
POST https://webshot.site/api/captureThe request body must be a JSON object containing the target URL and an optional format (JPG, PNG, or WebP). The API returns the binary image data directly with the appropriate Content-Type header, making it incredibly easy to pipe into a file or display on a webpage.
Basic Usage with Curl
The simplest way to test the API is using a standard curl command. This command captures a PNG of example.com and saves it locally:
curl -X POST https://webshot.site/api/capture -H "Content-Type: application/json" -d '{"url":"https://example.com","format":"png"}' --output screenshot.pngAutomating Captures with Python
Python is the go-to language for automation and data science. Using the requests library, you can trigger a capture and save the image in just a few lines of code.
Python Implementation Example
First, ensure you have the requests library installed via pip. Then, use the following script:
import requests
def capture_screenshot(target_url, output_file):
api_url = "https://webshot.site/api/capture"
payload = {
"url": target_url,
"format": "png"
}
response = requests.post(api_url, json=payload)
if response.status_code == 200:
with open(output_file, 'wb') as f:
f.write(response.content)
print(f"Screenshot saved to {output_file}")
elif response.status_code == 429:
print(f"Rate limit exceeded. Retry after {response.headers.get('Retry-After')} seconds.")
else:
print(f"Error: {response.status_code}")
capture_screenshot("https://example.com", "python_screenshot.png")This script handles the binary response and includes basic logic to check for rate limits, which we will discuss in detail later.
Automating Captures with Node.js
Since Webshot's engine is built with Node.js and Puppeteer, it is a natural fit for Node.js developers. You can use the axios library to handle the POST request and the built-in fs module to save the image.
Node.js Implementation Example
const axios = require('axios');
const fs = require('fs');
async function takeScreenshot(url, filename) {
try {
const response = await axios.post('https://webshot.site/api/capture', {
url: url,
format: 'webp'
}, {
responseType: 'arraybuffer'
});
fs.writeFileSync(filename, response.data);
console.log('Capture successful: ' + filename);
} catch (error) {
if (error.response && error.response.status === 429) {
console.error('Rate limit hit. Wait ' + error.response.headers['retry-after'] + 's');
} else {
console.error('Capture failed:', error.message);
}
}
}
takeScreenshot('https://example.com', 'node_screenshot.webp');Note the use of responseType: 'arraybuffer'. This is crucial for correctly handling the binary image data returned by the Webshot API.
Automating Captures with PHP
Webshot itself is built with PHP and the TiCore framework, making PHP integration seamless. Using curl, you can easily fetch screenshots from your server-side scripts.
PHP Implementation Example
<?php
function get_webshot($url, $save_path) {
$ch = curl_init('https://webshot.site/api/capture');
$data = json_encode(['url' => $url, 'format' => 'jpg']);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($data)
]);
$result = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code == 200) {
file_put_contents($save_path, $result);
echo "Screenshot captured!";
} else {
echo "Failed with status: " . $http_code;
}
curl_close($ch);
}
get_webshot('https://example.com', 'php_screenshot.jpg');
?>Managing Rate Limits and Headers
To ensure fair usage for everyone, Webshot implements a rate limit of 5 captures per 15-minute window per IP address. This uses a token bucket algorithm, meaning the bucket refills continuously over time.
Response Headers
Every response from the API includes headers to help you manage your limits efficiently:
X-RateLimit-Limit: Your total allowed captures per window.X-RateLimit-Remaining: How many captures you have left.X-RateLimit-Reset: When the limit will fully reset.Retry-After: If you hit a 429 error, this tells you exactly how many seconds to wait before trying again.
If you require higher limits for a commercial project, you can contact Tuxxin at [email protected] or use the form located on the Webshot API docs page.
Security and Error Handling
Webshot takes security seriously. To prevent Server-Side Request Forgery (SSRF), the API blocks requests to private IP addresses and internal networks. If you attempt to capture a restricted target or provide an invalid URL, the API will return a 400 Bad Request status.
Other possible status codes include:
- 429 Too Many Requests: You have exceeded the rate limit. Check the
Retry-Afterheader. - 500 Internal Server Error: The capture failed due to an engine error or a website that could not be rendered.
Because Webshot is anonymous and requires no signup, developers can integrate it into open-source tools and scripts without worrying about exposing sensitive API keys.
Full-Page Screenshots and Formats
One of the standout features of Webshot is its ability to capture the entire length of a page, not just the visible viewport. This is handled automatically by the headless Chrome engine. Additionally, you can choose the format that best suits your needs:
- PNG: Lossless quality, best for text-heavy sites.
- JPG: Great for general use and smaller file sizes.
- WebP: Modern format offering superior compression for web use.
If no format is specified in your JSON payload, the API defaults to JPG.
Frequently Asked Questions
Is the Webshot API really free?
Yes, Webshot is 100% free to use. There are no hidden fees, no subscriptions, and no credit card requirements. Both the Webshot homepage and the API use the same engine and are subject to the same generous free rate limits.
Do I need an API key to start?
No. Webshot is designed for anonymity and ease of use. You can start sending POST requests to the API immediately without any signup or authentication process.
What happens if I hit the rate limit?
If you exceed 5 captures in a 15-minute window, the API will return a 429 status code. You can check the Retry-After header to see when you can resume capturing. For higher volume needs, reach out to [email protected].
Can I use Webshot for private websites?
Webshot can only capture publicly accessible URLs. Private IP addresses and local networks are blocked for security reasons to prevent SSRF attacks.
Conclusion
Automating website screenshots doesn't have to be expensive or complicated. By leveraging the Webshot API, developers can access a powerful, Puppeteer-driven engine that handles modern web technologies with ease. Whether you are using Python, Node.js, or PHP, the integration is straightforward and requires zero configuration.
Ready to start capturing? Head over to the Webshot homepage to try it out manually, or dive into the API documentation to build your next automation tool today.