> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beta.b3os.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Screenshots

Capture a page, the full page or one element from a warm browser and compose it with a background and window frame, as JSON with signed URLs or as image bytes.

`POST /v1/render/screenshots` loads a URL (or renders HTML you send) in a warm browser, captures it, composes it with a style and encodes it, in one call.

## Take a styled screenshot

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/render/screenshots \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"url": "https://example.com", "viewport": {"width": 1600, "height": 900},
           "style": {"background": "midnight", "frame": "browser-dark"}, "format": "webp"}'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const shot = await b3os.render.createScreenshot({
      url: "https://example.com",
      viewport: { width: 1600, height: 900 },
      style: { background: "midnight", frame: "browser-dark" },
      format: "webp",
    });
    console.log(shot.artifacts[0].url);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    shot = b3os.render.create_screenshot({
        "url": "https://example.com",
        "viewport": {"width": 1600, "height": 900},
        "style": {"background": "midnight", "frame": "browser-dark"},
        "format": "webp",
    })
    print(shot["artifacts"][0]["url"])
    ```
  **MCP**

```text
    Take a screenshot of https://example.com at 1600x900 in a dark browser frame and give me the link.
    ```

    The agent calls `render_screenshot` with the URL, size and frame, and gets back the signed URL of the image (the local MCP server also returns the image itself).

The JSON response lists the `artifacts`, primary image first, each with a signed `url`, its size and `expires_at`, plus `timing` with the phases of the call, such as `navigate`, `capture`, `compose` and `encode`. Preset names such as `midnight` and `browser-dark` come from `GET /v1/render/presets`, which also returns a preview of each.

## Get the image bytes instead

Send `Accept: image/webp`, `image/png` or `image/jpeg` and the response body is the image:

```bash
curl -s https://beta-api.b3os.org/v1/render/screenshots \
  -H "Authorization: Bearer $B3OS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: image/png" \
  -d '{"url": "https://example.com", "format": "png"}' -o example.png
```

## Capture one element

`target` captures a single element, found the same way as in browser actions:

```json
{ "url": "https://example.com/pricing", "target": { "selector": "#plans" }, "dpr": 2, "format": "png" }
```

An element that never appears, or stays outside the viewport after scrolling to it, fails with [`target_not_found`](/errors#target_not_found). `full_page: true` captures the whole scrollable page instead of the viewport.

## Options

| Field | Default | Meaning |
|---|---|---|
| `url` or `html` | | The page to load, or HTML to render with no network access |
| `profile` | none | A vision [profile](/vision/profiles) to load first, to capture a signed-in page |
| `viewport` | | Width 320 to 3840 and height 240 to 2160, in CSS pixels |
| `dpr` | 1 | Device pixel ratio: 1, 2 or 3 |
| `wait_until` | `load` | `load`, `domcontentloaded` or `networkidle` |
| `wait_for_ms` | 0 | Extra settle time after the page is ready, up to 10 seconds |
| `theme` | `auto` | Emulate a light or dark color scheme; `auto` leaves the page's default |
| `hide` | none | CSS selectors to hide before capture, such as cookie banners and chat widgets |
| `block_ads` | `true` | Block ads and trackers |
| `style` | none | `background`, `frame` and the other preset names, plus `overrides` |
| `format`, `quality` | `webp`, 90 | `webp`, `png` or `jpeg`; quality applies to WebP and JPEG |
| `variants` | none | Up to 4 extra encodings of the same capture, each with `format`, an optional `width` and `quality` |

Each variant is its own artifact and bills one more `render.screenshot`; the page is captured once.

## When the page is ready

By default render captures once the page has loaded and its network has been quiet for a short window, ignoring requests that hang. Pages that animate content in after load can be captured mid-animation. For those, wait for something specific:

```json
{ "url": "https://example.com", "wait_until": "networkidle", "wait_for_ms": 1500 }
```

## Keep, fetch and delete

Screenshots are synchronous, so a stored screenshot has always succeeded. They are kept for 7 days. `GET /v1/render/screenshots/{screenshot_id}` returns one with fresh artifact URLs, `GET /v1/render/screenshots` lists them, and `DELETE` removes one and its artifacts; their URLs stop working within a minute.