Java SDK
The official Java SDK for RenderScreenshot. For Java 21 examples with virtual threads and Spring Boot, see the Java screenshot API guide.
Installation
Maven
Add the JitPack repository:
<repositories> <repository> <id>jitpack.io</id> <url>https://jitpack.io</url> </repository> </repositories>
Add the dependency:
<dependency> <groupId>com.github.Render-Screenshot</groupId> <artifactId>rs-java</artifactId> <version>v2.0.2</version> </dependency>
Gradle
Add the JitPack repository:
repositories { maven { url 'https://jitpack.io' } }
Add the dependency:
implementation 'com.github.Render-Screenshot:rs-java:v2.0.2'
Requirements
- Java 11 or higher
Quick Start
import com.renderscreenshot.sdk.Client; import com.renderscreenshot.sdk.TakeOptions; import java.nio.file.Files; import java.nio.file.Path; Client client = new Client("rs_live_xxxxx"); // Take a screenshot byte[] image = client.take( TakeOptions.url("https://example.com").preset("og_card") ); Files.write(Path.of("screenshot.png"), image);
Client
Constructor
import com.renderscreenshot.sdk.Client; Client client = new Client(apiKey); Client client = new Client(apiKey, baseUrl); Client client = new Client(apiKey, baseUrl, timeout); Client client = new Client(apiKey, baseUrl, timeout, signingKey, publicKeyId);
| Parameter | Type | Description |
|---|---|---|
apiKey |
String | Your live API key (rs_live_*) |
baseUrl |
String | API base URL (null = https://api.renderscreenshot.com) |
timeout |
Duration | Request timeout (null = 30 seconds) |
signingKey |
String | Secret key (rs_secret_*). Only generateUrl() uses it |
publicKeyId |
String | Public key ID (rs_pub_*). Only generateUrl() uses it |
Methods
take(options)
Take a screenshot and return binary data. The SDK sends the options to POST /v1/screenshot as nested JSON (for example viewport.width, capture.mode, output.format).
byte[] image = client.take( TakeOptions.url("https://example.com").preset("og_card") ); // Save to file Files.write(Path.of("screenshot.png"), image);
Returns: byte[]
takeJson(options)
Take a screenshot and return JSON metadata. The SDK sends the same request with an Accept: application/json header.
ScreenshotResponse response = client.takeJson( TakeOptions.url("https://example.com").preset("og_card") ); System.out.println(response.getId()); // "req_..." System.out.println(response.getStatus()); // "completed" System.out.println(response.getImage().getUrl()); // CDN URL (shortcut: response.getUrl()) System.out.println(response.getImage().getWidth()); // 1200 System.out.println(response.getImage().getHeight());// 630 System.out.println(response.getCache().isHit()); // true/false (shortcut: response.isCached()) System.out.println(response.getUsage().getRemaining()); // credits left
The response has id, status, image (url, width, height, size, format), metadata, cache (hit, key, url, expires_at) and usage (credits, remaining). getImage(), getCache() and getUsage() return null when the API leaves that section out.
Returns: ScreenshotResponse
generateUrl(options, expiresAt)
Generate a signed URL for public embedding. Signed URLs work only for the GET render endpoint (GET /v1/screenshot). They need your public key ID (rs_pub_*) and your secret signing key (rs_secret_*). Your live API key does not sign URLs. Keep the secret key on your server.
import java.time.Duration; import java.time.Instant; Client client = new Client( "rs_live_xxxxx", // API key for take(), batch(), etc. null, // default base URL null, // default timeout "rs_secret_xxxxx", // signing key "rs_pub_xxxxx" // public key ID ); String signedUrl = client.generateUrl( TakeOptions.url("https://example.com").preset("og_card"), Instant.now().plus(Duration.ofHours(24)) // 24 hours (maximum 30 days) ); // Or pass the credentials for one call: String otherUrl = client.generateUrl( TakeOptions.url("https://example.com").width(1200).height(630), Instant.now().plus(Duration.ofHours(1)), "rs_secret_xxxxx", "rs_pub_xxxxx" ); // Use in HTML: <img src="${signedUrl}" />
The URL contains key_id, expires, the flat GET parameters and a signature. Only options that the GET endpoint reads are included (for example width, fullPage(), element(), blockAds(), blockCookieBanners(), darkMode(), cacheTtl() and the PDF options). POST-only options, such as waitForSelector() or blockTrackers(), are left out.
Returns: String
Throws: RenderScreenshotException with code invalid_request if the signing key or the public key ID is missing.
batch(urls, options) / batchAdvanced(requests)
Process multiple screenshots in a batch.
import java.util.Arrays; import java.util.List; // Simple batch List<String> urls = Arrays.asList( "https://example1.com", "https://example2.com" ); BatchResponse results = client.batch(urls, TakeOptions.url("").preset("og_card") ); // Advanced batch with per-URL options List<Client.BatchRequest> requests = Arrays.asList( new Client.BatchRequest("https://example1.com", TakeOptions.url("https://example1.com").preset("og_card")), new Client.BatchRequest("https://example2.com", TakeOptions.url("https://example2.com").width(1920)) ); BatchResponse results = client.batchAdvanced(requests);
Returns: BatchResponse
getBatch(batchId)
Get the status of a batch job.
BatchResponse status = client.getBatch("batch_abc123"); System.out.println(status.getCompleted() + "/" + status.getTotal());
Returns: BatchResponse
presets() / preset(id)
Get available presets.
List<Preset> presets = client.presets(); Preset ogCard = client.preset("og_card");
devices()
Get available device presets.
List<Device> devices = client.devices();
TakeOptions
Fluent builder for screenshot options.
Creating Options
import com.renderscreenshot.sdk.TakeOptions; // From URL TakeOptions options = TakeOptions.url("https://example.com"); // From HTML TakeOptions options = TakeOptions.html("<h1>Hello World</h1>");
Viewport Options
TakeOptions.url("...") .width(1200) // Viewport width .height(630) // Viewport height .scale(2.0) // Device scale factor (1-3) .mobile(); // Enable mobile emulation
Capture Options
TakeOptions.url("...") .fullPage() // Capture full scrollable page .element(".hero") // Capture specific element .format("png") // png, jpeg, webp, pdf .quality(90); // JPEG/WebP quality (1-100)
Wait Options
TakeOptions.url("...") .waitFor("networkidle") // load, networkidle, domcontentloaded .delay(2000) // Additional delay (ms) .waitForSelector(".loaded") // Wait for selector .waitForTimeout(30); // Max wait time (s, 1-60)
Presets & Devices
TakeOptions.url("...") .preset("og_card") // Use a preset .device("iphone_14_pro"); // Emulate a device
Content Blocking
TakeOptions.url("...") .blockAds() // Block ad networks .blockTrackers() // Block analytics .blockCookieBanners() // Auto-dismiss cookie popups .blockChatWidgets() // Block chat widgets .blockUrls(Arrays.asList("*.ads.com/*")) // Block URL patterns .blockResources(Arrays.asList("font")); // Block resource types
Browser Emulation
TakeOptions.url("...") .darkMode() // Enable dark mode .reducedMotion() // Prefer reduced motion .mediaType("print") // screen or print .userAgent("Custom UA") // Custom user agent .timezone("America/New_York") .locale("en-US") .geolocation(40.7128, -74.006);
Network Options
import java.util.Map; import java.util.HashMap; Map<String, String> headers = new HashMap<>(); headers.put("X-Custom", "value"); TakeOptions.url("...") .headers(headers) .authBasic("user", "pass") .authBearer("token") .bypassCsp();
Cache Options
TakeOptions.url("...") .cacheTtl(86400) // Cache TTL in seconds .cacheAvailable() // Reuse an identical render inside the TTL (0 credits) .cacheRefresh(); // Force refresh
PDF Options
TakeOptions.url("...") .format("pdf") .pdfPaperSize("a4") // a4, letter, legal, etc. .pdfLandscape() .pdfMargin("1in") .pdfPrintBackground() .pdfHeader("<div>Header</div>") .pdfFooter("<div>Page <span class=\"pageNumber\"></span></div>");
Storage Options (BYOS)
TakeOptions.url("...") .storageEnabled() .storagePath("{year}/{month}/{hash}.{ext}") .storageAcl("public-read");
Cache Management
// Get cached screenshot byte[] image = client.cache.get("cache_xyz789"); // Delete single entry client.cache.delete("cache_xyz789"); // Bulk purge by keys CacheManager.PurgeResponse result = client.cache.purge( Arrays.asList("cache_abc", "cache_def") ); System.out.println("Purged: " + result.getPurged()); // Purge by URL pattern client.cache.purgeUrl("https://mysite.com/blog/*"); // Purge by storage path pattern client.cache.purgePattern("screenshots/2024/*"); // Purge by date client.cache.purgeBefore(Instant.parse("2024-01-01T00:00:00Z"));
Webhook Helpers
import com.renderscreenshot.sdk.Webhook; import com.renderscreenshot.sdk.Webhook.WebhookEvent; // Verify signature boolean isValid = Webhook.verify(payload, signature, timestamp, secret); // Parse event WebhookEvent event = Webhook.parse(payload); if ("screenshot.completed".equals(event.getEvent())) { System.out.println("Screenshot completed: " + event.getData()); } // Extract headers (case-insensitive) String[] headers = Webhook.extractHeaders(requestHeaders); String signature = headers[0]; String timestamp = headers[1];
Error Handling
import com.renderscreenshot.sdk.RenderScreenshotException; try { byte[] image = client.take(TakeOptions.url("...")); } catch (RenderScreenshotException e) { System.out.println(e.getHttpStatus()); // 400, 429, etc. System.out.println(e.getCode()); // "invalid_url", "rate_limited" System.out.println(e.getMessage()); // Human-readable message System.out.println(e.isRetryable()); // true/false if (e.isRetryable() && e.getRetryAfter() != null) { Thread.sleep(e.getRetryAfter() * 1000L); // Retry the request... } }
Error Codes
| Code | HTTP | Retryable | Description |
|---|---|---|---|
invalid_request |
400 | No | Malformed request |
invalid_url |
400 | No | Invalid URL provided |
unauthorized |
401 | No | Invalid API key |
forbidden |
403 | No | Access denied |
not_found |
404 | No | Resource not found |
rate_limited |
429 | Yes | Rate limit exceeded |
timeout |
408 | Yes | Screenshot timed out |
render_failed |
500 | Yes | Browser rendering failed |
internal_error |
500 | Yes | Internal server error |