Batch Screenshots
The batch endpoint lets you capture multiple screenshots in a single request, with support for both synchronous and asynchronous processing.
Endpoint
POST https://api.renderscreenshot.com/v1/batch
Authentication
Include your API key in the Authorization header:
Authorization: Bearer rs_live_xxxxx
Simple Batch Request
Apply the same options to all URLs:
{ "urls": [ "https://example1.com", "https://example2.com", "https://example3.com" ], "options": { "preset": "og_card", "block": { "ads": true } }, "concurrency": 3 }
| Parameter | Type | Required | Description |
|---|---|---|---|
urls |
array | Yes* | List of URLs to screenshot (*or use requests) |
options |
object | No | Options applied to all URLs |
concurrency |
integer | No | Parallel screenshots (default: 3, max varies by plan) |
Advanced Batch Request
Specify different options per URL:
{ "requests": [ { "url": "https://example1.com", "preset": "og_card" }, { "url": "https://example2.com", "preset": "full_page" }, { "url": "https://example3.com", "viewport": { "width": 1920 } } ], "webhook": { "url": "https://your-server.com/webhook" } }
| Parameter | Type | Required | Description |
|---|---|---|---|
requests |
array | Yes* | Array of request objects with individual options |
webhook |
object | No | Webhook configuration for async processing |
Sync vs Async Processing
Synchronous (≤10 URLs without webhook): - Request blocks until all screenshots complete - Returns full results in response
Asynchronous (>10 URLs or webhook specified):
- Returns immediately with job ID
- Poll GET /v1/batch/:id for status
- Or receive webhook on completion
Synchronous Response
{ "id": "batch_abc123", "status": "completed", "results": [ { "url": "https://example1.com", "status": "completed", "image": { "url": "https://cdn.renderscreenshot.com/abc.png", "width": 1200, "height": 630 } }, { "url": "https://example2.com", "status": "completed", "image": { "url": "https://cdn.renderscreenshot.com/def.png", "width": 1280, "height": 4500 } }, { "url": "https://example3.com", "status": "failed", "error": { "type": "target_error", "code": "timeout", "message": "Page failed to load within 30 seconds", "retryable": true } } ], "summary": { "total": 3, "completed": 2, "failed": 1 }, "usage": { "credits": 2, "remaining": 9997 } }
Asynchronous Response
Initial response:
{ "id": "batch_abc123", "status": "processing", "total": 50, "progress": 0 }
Poll for status:
GET /v1/batch/batch_abc123
Webhook Integration
When a webhook is configured, you'll receive a POST request on completion:
{ "event": "batch.completed", "batch_id": "batch_abc123", "status": "completed", "summary": { "total": 50, "completed": 48, "failed": 2 }, "results_url": "https://api.renderscreenshot.com/v1/batch/batch_abc123/results" }
See Webhooks for configuration details.
Examples
Simple Batch
curl
curl -X POST https://api.renderscreenshot.com/v1/batch \ -H "Authorization: Bearer rs_live_xxxxx" \ -H "Content-Type: application/json" \ -d '{ "urls": [ "https://github.com", "https://stripe.com", "https://linear.app" ], "options": { "preset": "og_card" } }'
Java
import com.renderscreenshot.sdk.Client; import com.renderscreenshot.sdk.TakeOptions; import com.renderscreenshot.sdk.model.BatchResponse; import com.renderscreenshot.sdk.model.BatchResult; import java.util.Arrays; Client client = new Client("rs_live_xxxxx"); BatchResponse results = client.batch( Arrays.asList("https://github.com", "https://stripe.com", "https://linear.app"), TakeOptions.url("").preset("og_card") ); System.out.println("Completed: " + results.getCompleted() + "/" + results.getTotal()); for (BatchResult item : results.getResults()) { String url = item.isSuccess() ? item.getResponse().getUrl() : "failed"; System.out.println(item.getUrl() + ": " + url); }
Node.js
import { Client, TakeOptions } from 'renderscreenshot'; const client = new Client('rs_live_xxxxx'); const results = await client.batch( ['https://github.com', 'https://stripe.com', 'https://linear.app'], TakeOptions.url('').preset('og_card') ); console.log(`Completed: ${results.completed}/${results.total}`); for (const item of results.results) { console.log(`${item.url}: ${item.success ? item.response?.url : 'failed'}`); }
PHP
use RenderScreenshot\Client; use RenderScreenshot\TakeOptions; $client = new Client('rs_live_xxxxx'); $results = $client->batch( ['https://github.com', 'https://stripe.com', 'https://linear.app'], TakeOptions::url('')->preset('og_card') ); echo "Completed: {$results['completed']}/{$results['total']}\n"; foreach ($results['results'] as $item) { $url = $item['success'] ? ($item['response']['url'] ?? 'failed') : 'failed'; echo "{$item['url']}: {$url}\n"; }
Python
from renderscreenshot import Client, TakeOptions client = Client('rs_live_xxxxx') results = client.batch( ['https://github.com', 'https://stripe.com', 'https://linear.app'], TakeOptions.url('').preset('og_card') ) print(f"Completed: {results['completed']}/{results['total']}") for item in results['results']: url = item.get('response', {}).get('url', 'failed') if item.get('success') else 'failed' print(f"{item['url']}: {url}")
Ruby
require 'net/http' require 'json' uri = URI('https://api.renderscreenshot.com/v1/batch') http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request['Authorization'] = 'Bearer rs_live_xxxxx' request['Content-Type'] = 'application/json' request.body = { urls: ['https://github.com', 'https://stripe.com', 'https://linear.app'], options: { preset: 'og_card' } }.to_json response = http.request(request) results = JSON.parse(response.body) puts "Completed: #{results['summary']['completed']}/#{results['summary']['total']}" results['results'].each do |item| url = item['status'] == 'completed' ? item['image']['url'] : 'failed' puts "#{item['url']}: #{url}" end
Advanced Batch with Per-URL Options
Java
import com.renderscreenshot.sdk.Client; import com.renderscreenshot.sdk.TakeOptions; import java.util.Arrays; Client client = new Client("rs_live_xxxxx"); BatchResponse results = client.batchAdvanced(Arrays.asList( new Client.BatchRequest("https://github.com", TakeOptions.url("https://github.com").preset("og_card")), new Client.BatchRequest("https://stripe.com", TakeOptions.url("https://stripe.com").fullPage()), new Client.BatchRequest("https://linear.app", TakeOptions.url("https://linear.app").width(1920).darkMode()) ));
Node.js
import { Client } from 'renderscreenshot'; const client = new Client('rs_live_xxxxx'); const results = await client.batch([ { url: 'https://github.com', options: { preset: 'og_card' } }, { url: 'https://stripe.com', options: { preset: 'full_page' } }, { url: 'https://linear.app', options: { width: 1920, darkMode: true } }, ]);
PHP
use RenderScreenshot\Client; $client = new Client('rs_live_xxxxx'); $results = $client->batchAdvanced([ ['url' => 'https://github.com', 'options' => ['preset' => 'og_card']], ['url' => 'https://stripe.com', 'options' => ['preset' => 'full_page']], ['url' => 'https://linear.app', 'options' => ['width' => 1920, 'dark_mode' => true]], ]);
Python
from renderscreenshot import Client client = Client('rs_live_xxxxx') results = client.batch([ {'url': 'https://github.com', 'options': {'preset': 'og_card'}}, {'url': 'https://stripe.com', 'options': {'preset': 'full_page'}}, {'url': 'https://linear.app', 'options': {'width': 1920, 'dark_mode': True}}, ])
Ruby
require 'net/http' require 'json' uri = URI('https://api.renderscreenshot.com/v1/batch') http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request['Authorization'] = 'Bearer rs_live_xxxxx' request['Content-Type'] = 'application/json' request.body = { requests: [ { url: 'https://github.com', preset: 'og_card' }, { url: 'https://stripe.com', preset: 'full_page' }, { url: 'https://linear.app', viewport: { width: 1920 } } ] }.to_json response = http.request(request) results = JSON.parse(response.body)
Polling Batch Status
Java
import com.renderscreenshot.sdk.Client; import com.renderscreenshot.sdk.model.BatchResponse; import java.util.Arrays; Client client = new Client("rs_live_xxxxx"); // Start a batch BatchResponse batch = client.batch( Arrays.asList("https://example1.com", "https://example2.com"), TakeOptions.url("").preset("og_card") ); // Poll for completion BatchResponse status = client.getBatch(batch.getId()); while ("processing".equals(status.getStatus())) { Thread.sleep(1000); status = client.getBatch(batch.getId()); System.out.println("Progress: " + status.getCompleted() + "/" + status.getTotal()); }
Node.js
import { Client } from 'renderscreenshot'; const client = new Client('rs_live_xxxxx'); // Start a batch const batch = await client.batch(['https://example1.com', 'https://example2.com']); // Poll for completion let status = await client.getBatch(batch.id); while (status.status === 'processing') { await new Promise(resolve => setTimeout(resolve, 1000)); status = await client.getBatch(batch.id); console.log(`Progress: ${status.completed}/${status.total}`); }
PHP
use RenderScreenshot\Client; $client = new Client('rs_live_xxxxx'); // Start a batch $batch = $client->batch(['https://example1.com', 'https://example2.com']); // Poll for completion $status = $client->getBatch($batch['id']); while ($status['status'] === 'processing') { sleep(1); $status = $client->getBatch($batch['id']); echo "Progress: {$status['completed']}/{$status['total']}\n"; }
Python
import time from renderscreenshot import Client client = Client('rs_live_xxxxx') # Start a batch batch = client.batch(['https://example1.com', 'https://example2.com']) # Poll for completion status = client.get_batch(batch['id']) while status['status'] == 'processing': time.sleep(1) status = client.get_batch(batch['id']) print(f"Progress: {status['completed']}/{status['total']}")
Ruby
require 'net/http' require 'json' base_uri = 'https://api.renderscreenshot.com/v1' # Start a batch uri = URI("#{base_uri}/batch") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request['Authorization'] = 'Bearer rs_live_xxxxx' request['Content-Type'] = 'application/json' request.body = { urls: ['https://example1.com', 'https://example2.com'] }.to_json response = http.request(request) batch = JSON.parse(response.body) # Poll for completion loop do status_uri = URI("#{base_uri}/batch/#{batch['id']}") status_request = Net::HTTP::Get.new(status_uri) status_request['Authorization'] = 'Bearer rs_live_xxxxx' status_response = http.request(status_request) status = JSON.parse(status_response.body) puts "Progress: #{status['summary']['completed']}/#{status['summary']['total']}" break unless status['status'] == 'processing' sleep(1) end
Rate Limits
Batch size limits vary by plan:
| Plan | Max batch size |
|---|---|
| Free | 5 |
| Starter | 20 |
| Growth | 50 |
| Scale | 100 |
See Rate Limits for more details.
See Also
- Webhooks - Receive notifications when batch jobs complete
- Storage Options - Upload batch screenshots to your own bucket
- Presets Reference - Use presets for consistent batch output
- Rate Limits - Batch size limits by plan