2 creditsScreenshot API — pixel-accurate page captures
Full-page or viewport captures with retina scale, ad blocking and JS wait strategies.
The Screenshot API captures any public webpage as a PNG or JPEG in one REST call. Choose full-page or a fixed viewport, retina scale, ad blocking, element hiding and a wait strategy (load, networkidle, or a CSS selector) so JavaScript-heavy pages finish rendering before capture. The same SSRF guard as url-to-pdf refuses private and metadata addresses. Two credits per capture.
How does the Screenshot API work?
One HTTP request from any language. Every ASHDOCS endpoint uses the same X-API-Key header.
curl -X POST https://www.ashdocs.com/api/v1/tools/screenshot \
-H "X-API-Key: ash_live_..." \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com","options":{"viewport":{"width":1280,"height":800},"scale":2,"wait_for":"networkidle"}}'import requests
r = requests.post(
"https://www.ashdocs.com/api/v1/tools/screenshot",
headers={"X-API-Key": "ash_live_..."},
json={
"url": "https://example.com",
"options": {
"viewport": {
"width": 1280,
"height": 800
},
"scale": 2,
"wait_for": "networkidle"
}
},
)
job = r.json()
print(job["status"], job["output_files"][0]["url"])const res = await fetch("https://www.ashdocs.com/api/v1/tools/screenshot", {
method: "POST",
headers: { "X-API-Key": "ash_live_...", "Content-Type": "application/json" },
body: JSON.stringify({"url":"https://example.com","options":{"viewport":{"width":1280,"height":800},"scale":2,"wait_for":"networkidle"}}),
});
const job = await res.json();
console.log(job.status, job.output_files[0].url);using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "ash_live_...");
var body = new StringContent(
"{\"url\":\"https://example.com\",\"options\":{\"viewport\":{\"width\":1280,\"height\":800},\"scale\":2,\"wait_for\":\"networkidle\"}}",
Encoding.UTF8, "application/json");
var res = await client.PostAsync("https://www.ashdocs.com/api/v1/tools/screenshot", body);
var job = await res.Content.ReadAsStringAsync();
Console.WriteLine(job);import java.io.ByteArrayOutputStream;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
public class Sample {
public static void main(String[] args) throws Exception {
String json = "{\"url\":\"https://example.com\",\"options\":{\"viewport\":{\"width\":1280,\"height\":800},\"scale\":2,\"wait_for\":\"networkidle\"}}";
HttpRequest req = HttpRequest.newBuilder(URI.create("https://www.ashdocs.com/api/v1/tools/screenshot"))
.header("X-API-Key", "ash_live_...")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> res = HttpClient.newHttpClient().send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(res.body());
}
}#include <stdio.h>
#include <curl/curl.h>
int main(void) {
CURL *curl = curl_easy_init();
if (!curl) return 1;
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "X-API-Key: ash_live_...");
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "{\"url\":\"https://example.com\",\"options\":{\"viewport\":{\"width\":1280,\"height\":800},\"scale\":2,\"wait_for\":\"networkidle\"}}");
curl_easy_setopt(curl, CURLOPT_URL, "https://www.ashdocs.com/api/v1/tools/screenshot");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
CURLcode rc = curl_easy_perform(curl);
printf("\n");
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
return rc == CURLE_OK ? 0 : 1;
}Common use cases
- →Social cards from live pages
- →Visual archiving and monitoring
- →Thumbnails for link previews
Frequently asked questions
How do I screenshot a JavaScript-heavy page?+
Set options.wait_for to networkidle or to a CSS selector that appears when the page is ready, and add delay_ms for animations. The capture fires only after the condition is met.
Can I hide cookie banners and chat widgets?+
Yes — pass their CSS selectors in options.hide_selectors and they are removed before capture. block_ads strips common ad frames too.
Full page or viewport?+
options.full_page captures the entire scroll height; otherwise you get exactly the viewport you specify. Use scale 2 for retina-sharp output.
Can I screenshot internal or private URLs?+
No. The endpoint enforces the same SSRF protection as url-to-pdf — private ranges, loopback and cloud metadata addresses are refused with a 400 ssrf_blocked error.
networkidle, block ads, and archive pages exactly as they render.