NewIntroducing semantic snapshotsPair every capture with structured DOM data →

For teams that document a product

Keep the screenshots in your docs as current as the product

Regenerate every screenshot in your help centre from the live app on each release, cropped to the part the article is about.

The problem

The billing page was redesigned in March and the help article still shows the old one. Retaking forty screenshots by hand, at the right size, in the right account, with nobody's real name in them, is the job that always slips to the next sprint.

How domscout handles it

Send the session cookie or authorization header of a demo account with the request, and the page loads signed in. Headers are sent only to the page's own origin, and sensitive header values and cookies are kept out of diagnostics and saved captures. captureSelector crops the image to one element, the panel the article is about; hideSelectors hides anything personal; deviceScaleFactor: 2 gives sharp images on high-density screens. On Pro, render.colorScheme takes a dark-mode copy of the same view. The app has to be reachable from the public internet: private and internal addresses are refused.

Where it shows up

  • Help-centre screenshots regenerated by the release pipeline.
  • Light and dark versions of the same view for docs that offer both.
  • Walkthroughs built on images that are never out of date.

The request

POST /screenshot. Available on every plan, including the free Hobby plan, at 1 credit an image. Use a demo account with sample data, never a real customer's session.

cURL
curl -X POST https://api.domscout.io/screenshot \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://app.example.com/settings/billing",
    "cookies": [
      {
        "name": "session",
        "value": "YOUR_DEMO_SESSION",
        "domain": "app.example.com"
      }
    ],
    "captureSelector": "[data-docs='\''billing-panel'\'']",
    "hideSelectors": ["[data-docs-hide]"],
    "deviceScaleFactor": 2,
    "format": "png",
    "responseType": "binary"
  }' \
  -o billing-panel.png
Node.js
import { writeFile } from "node:fs/promises";

const response = await fetch("https://api.domscout.io/screenshot", {
  method: "POST",
  headers: { "Content-Type": "application/json", "x-api-key": "YOUR_API_KEY" },
  body: JSON.stringify({
    url: "https://app.example.com/settings/billing",
    cookies: [
      {
        name: "session",
        value: "YOUR_DEMO_SESSION",
        domain: "app.example.com"
      }
    ],
    captureSelector: "[data-docs='billing-panel']",
    hideSelectors: ["[data-docs-hide]"],
    deviceScaleFactor: 2,
    format: "png",
    responseType: "binary"
  }),
});
await writeFile("billing-panel.png", Buffer.from(await response.arrayBuffer()));
Python
import requests

response = requests.post(
    "https://api.domscout.io/screenshot",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "url": "https://app.example.com/settings/billing",
        "cookies": [
            {
                "name": "session",
                "value": "YOUR_DEMO_SESSION",
                "domain": "app.example.com"
            }
        ],
        "captureSelector": "[data-docs='billing-panel']",
        "hideSelectors": ["[data-docs-hide]"],
        "deviceScaleFactor": 2,
        "format": "png",
        "responseType": "binary"
    },
)
with open("billing-panel.png", "wb") as f:
    f.write(response.content)
Go
package main

import (
	"bytes"
	"encoding/json"
	"io"
	"net/http"
	"os"
)

func main() {
	body, _ := json.Marshal(map[string]any{
		"url": "https://app.example.com/settings/billing",
		"cookies": []any{
			map[string]any{
				"name": "session",
				"value": "YOUR_DEMO_SESSION",
				"domain": "app.example.com",
			},
		},
		"captureSelector": "[data-docs='billing-panel']",
		"hideSelectors": []any{"[data-docs-hide]"},
		"deviceScaleFactor": 2,
		"format": "png",
		"responseType": "binary",
	})
	req, _ := http.NewRequest("POST", "https://api.domscout.io/screenshot", bytes.NewReader(body))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("x-api-key", "YOUR_API_KEY")

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	out, _ := os.Create("billing-panel.png")
	defer out.Close()
	io.Copy(out, res.Body)
}
PHP
<?php
$ch = curl_init('https://api.domscout.io/screenshot');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'x-api-key: YOUR_API_KEY'],
    CURLOPT_POSTFIELDS => json_encode([
        'url' => 'https://app.example.com/settings/billing',
        'cookies' => [
            [
                'name' => 'session',
                'value' => 'YOUR_DEMO_SESSION',
                'domain' => 'app.example.com'
            ]
        ],
        'captureSelector' => '[data-docs=\'billing-panel\']',
        'hideSelectors' => ['[data-docs-hide]'],
        'deviceScaleFactor' => 2,
        'format' => 'png',
        'responseType' => 'binary'
    ]),
]);
$response = curl_exec($ch);
if ($response === false) {
    throw new RuntimeException(curl_error($ch));
}
file_put_contents('billing-panel.png', $response);
Ruby
require "json"
require "net/http"

response = Net::HTTP.post(
  URI("https://api.domscout.io/screenshot"),
  {
    url: "https://app.example.com/settings/billing",
    cookies: [
      {
        name: "session",
        value: "YOUR_DEMO_SESSION",
        domain: "app.example.com"
      }
    ],
    captureSelector: "[data-docs='billing-panel']",
    hideSelectors: ["[data-docs-hide]"],
    deviceScaleFactor: 2,
    format: "png",
    responseType: "binary"
  }.to_json,
  "Content-Type" => "application/json",
  "x-api-key" => "YOUR_API_KEY"
)
File.binwrite("billing-panel.png", response.body)
Java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;

public class Capture {
    public static void main(String[] args) throws Exception {
        String body = """
            {
                "url": "https://app.example.com/settings/billing",
                "cookies": [
                    {
                        "name": "session",
                        "value": "YOUR_DEMO_SESSION",
                        "domain": "app.example.com"
                    }
                ],
                "captureSelector": "[data-docs='billing-panel']",
                "hideSelectors": ["[data-docs-hide]"],
                "deviceScaleFactor": 2,
                "format": "png",
                "responseType": "binary"
            }
            """;
        HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.domscout.io/screenshot"))
            .header("Content-Type", "application/json")
            .header("x-api-key", "YOUR_API_KEY")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();
        HttpResponse<Path> response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofFile(Path.of("billing-panel.png")));
        System.out.println("Saved " + response.body());
    }
}
C#
using System.Net.Http.Json;

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY");

var response = await client.PostAsJsonAsync("https://api.domscout.io/screenshot", new {
    url = "https://app.example.com/settings/billing",
    cookies = new[] {
        new {
            name = "session",
            value = "YOUR_DEMO_SESSION",
            domain = "app.example.com"
        }
    },
    captureSelector = "[data-docs='billing-panel']",
    hideSelectors = new[] { "[data-docs-hide]" },
    deviceScaleFactor = 2,
    format = "png",
    responseType = "binary"
});
await File.WriteAllBytesAsync("billing-panel.png", await response.Content.ReadAsByteArrayAsync());

Go further

More in Screenshots, images and PDFs: Thumbnails and link previews · PDFs from your own HTML · HTML to image · Web page to PDF · Screenshots of a list of URLs · Dashboard screenshots to chat · Monthly reports for clients · Email template previews · Full-page captures for review tools · All use cases

Give your product a browser.

Get clean web content and visual proof into your workflow in minutes.