# Snapframe Apify Actor (`abdou_009/snapframe-apify-actor`) Actor

- **URL**: https://apify.com/abdou_009/snapframe-apify-actor.md
- **Developed by:** [Abdelkader BENAISSI](https://apify.com/abdou_009) (community)
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 screenshot captureds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Snapframe — Website Screenshots & PDFs

Capture pixel-perfect website screenshots (**PNG/JPEG**) and print-ready **PDF documents** in a real Chromium browser. Built by the team behind the [Snapframe API](https://snapframe.mooo.com/demo/).

Feed it one or more URLs and get back files plus a clean dataset row per page: direct download link, file size, page title, HTTP status and load time. Batch up to 50 URLs per run.

### What it does

- **Screenshots** in PNG or JPEG — viewport or full-page, with device presets (desktop, laptop, tablet, mobile) or your own custom dimensions and scale factor.
- **PDFs** with paper size (A4/Letter/Legal), orientation, margins, background printing, and optional header/footer HTML templates with page numbers.
- **First-class Arabic/RTL rendering** — proper Arabic fonts ship in the image, so Arabic pages (invoices, articles, dashboards) render with real glyphs, not boxes.
- **Batch captures** — up to 50 URLs per run, each stored as its own file with a dataset record. One bad URL never kills the batch.
- **Authenticated pages** — pass custom request headers and cookies to capture pages behind a login.
- **Safe by default** — only public `http(s)` URLs are loaded; private, loopback and internal addresses are blocked.

### Input

| Field | Description |
|---|---|
| `urls` | URLs to capture (1–50, required) |
| `outputFormat` | `png`, `jpeg` or `pdf` |
| `devicePreset` | `desktop` (1920×1080), `laptop`, `tablet`, `mobile`, or `custom` |
| `viewportWidth` / `viewportHeight` / `deviceScaleFactor` | Used when the preset is `custom` |
| `fullPage` | Capture the whole scrollable page (images only; PDFs are always full) |
| `waitUntil` | `load`, `domcontentloaded`, `networkidle` or `commit` |
| `delayMs` | Extra pause after load for animations/lazy images |
| `timeoutMs` | Per-page load timeout |
| `jpegQuality` | JPEG quality 10–100 |
| `pdfFormat` / `pdfLandscape` / `pdfMargin` / `printBackground` | PDF layout |
| `displayHeaderFooter` / `headerTemplate` / `footerTemplate` | PDF header/footer HTML (`<span class="pageNumber">` supported) |
| `headers` | Extra HTTP headers, e.g. `{"Authorization": "Bearer ..."}` |
| `cookies` | Cookies injected before capture (each needs `name`, `value` and `domain` or `url`) |

Example input:

```json
{
  "urls": ["https://example.com", "https://news.ycombinator.com"],
  "outputFormat": "png",
  "devicePreset": "desktop",
  "fullPage": true,
  "waitUntil": "networkidle",
  "delayMs": 1000
}
```

PDF example:

```json
{
  "urls": ["https://example.com"],
  "outputFormat": "pdf",
  "pdfFormat": "A4",
  "pdfMargin": "0.4in",
  "printBackground": true,
  "displayHeaderFooter": true,
  "footerTemplate": "<div style=\"font-size:8px;width:100%;text-align:center;\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>"
}
```

### Output

- **Files** — each capture is saved in the run's key-value store (`0000-example-com.png`, …) and stays downloadable via its direct URL.
- **Dataset** — one row per URL: `url`, `ok`, `outputFormat`, `fileName`, `fileUrl`, `bytes`, `title`, `statusCode`, `loadTimeMs`, and `reason` when a capture fails.
- **OUTPUT** — run summary: total / succeeded / failed counts and format.

### Pricing

Pay per event — you are charged only for successful captures:

| Event | Price |
|---|---|
| Screenshot captured (PNG/JPEG) | $0.003 |
| PDF captured | $0.005 |

Platform compute costs are passed through to the run (standard Apify compute units), so the event price is the whole story. Failed or blocked URLs are never charged.

### API examples

```bash
curl -X POST "https://api.apify.com/v2/acts/abdou_009~snapframe-apify-actor/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://example.com"], "outputFormat": "pdf"}'
```

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("abdou_009/snapframe-apify-actor").call({
    "urls": ["https://example.com"],
    "outputFormat": "png",
    "devicePreset": "mobile",
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["url"], "->", item["fileUrl"])
```

AI agents can also discover and call this actor through the Apify MCP server — the input schema is written to be agent-friendly.

### Limits

- 50 URLs per run; schedule runs for larger batches.
- Pages behind logins need the `headers`/`cookies` inputs — there is no interactive login.
- Sites with aggressive bot protection may serve a challenge page; that is captured faithfully as what an anonymous visitor sees.
- Very long pages (tens of thousands of pixels) can exceed browser capture limits — use a tall custom viewport with `fullPage: false` for those.

### Support

Issues: open one on the actor page. This actor is maintained by Snapframe — the same capture engine powers our hosted API.

# Actor input Schema

## `cookies` (type: `array`):

Cookies injected before capture. Each item needs name, value, and domain (or url).

## `delayMs` (type: `integer`):

Extra pause after load for late animations or lazy images.

## `devicePreset` (type: `string`):

Pick a device viewport, or choose Custom to use your own dimensions below.

## `deviceScaleFactor` (type: `number`):

Pixel ratio for high-DPI captures. Used only when the device preset is Custom.

## `displayHeaderFooter` (type: `boolean`):

Render a header and footer on every PDF page using the templates below.

## `footerTemplate` (type: `string`):

HTML for the PDF footer. Supports <span class="pageNumber"> and <span class="totalPages">.

## `fullPage` (type: `boolean`):

Capture the entire scrollable page, not just the viewport. Always on for PDFs.

## `headerTemplate` (type: `string`):

HTML for the PDF header. Supports <span class="pageNumber"> and <span class="totalPages">.

## `headers` (type: `object`):

Custom request headers sent with every page load, e.g. {"Authorization": "Bearer ..."}.

## `jpegQuality` (type: `integer`):

Only used when the output format is JPEG.

## `outputFormat` (type: `string`):

Screenshot as PNG/JPEG image, or a print-ready PDF document.

## `pdfFormat` (type: `string`):

Paper size for the PDF document.

## `pdfLandscape` (type: `boolean`):

Render the PDF in landscape orientation.

## `pdfMargin` (type: `string`):

Margin applied to all four sides, e.g. 0.4in or 10mm.

## `printBackground` (type: `boolean`):

Include CSS backgrounds and colors in the PDF.

## `sectionAdvanced` (type: `string`):

Advanced

## `sectionCapture` (type: `string`):

Capture options

## `sectionPdf` (type: `string`):

PDF options

## `timeoutMs` (type: `integer`):

Maximum time to wait for a single page to load.

## `urls` (type: `array`):

One or more public http(s) URLs. Each URL is rendered in a real Chromium browser and captured. Internal/private addresses are blocked.

## `viewportHeight` (type: `integer`):

Used only when the device preset is Custom.

## `viewportWidth` (type: `integer`):

Used only when the device preset is Custom.

## `waitUntil` (type: `string`):

How long to wait for the page to settle before capturing.

## Actor input object example

```json
{
  "cookies": [],
  "delayMs": 1000,
  "devicePreset": "desktop",
  "deviceScaleFactor": 1,
  "displayHeaderFooter": false,
  "footerTemplate": "",
  "fullPage": true,
  "headerTemplate": "",
  "headers": {},
  "jpegQuality": 85,
  "outputFormat": "png",
  "pdfFormat": "A4",
  "pdfLandscape": false,
  "pdfMargin": "0.4in",
  "printBackground": true,
  "timeoutMs": 60000,
  "urls": [
    "https://example.com"
  ],
  "viewportHeight": 1080,
  "viewportWidth": 1920,
  "waitUntil": "networkidle"
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset with one row per captured URL: file links, sizes, page titles and timings.

## `files` (type: `string`):

Key-value store holding the captured PNG/JPEG/PDF files.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        "https://example.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("abdou_009/snapframe-apify-actor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "urls": ["https://example.com"] }

# Run the Actor and wait for it to finish
run = client.actor("abdou_009/snapframe-apify-actor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "https://example.com"
  ]
}' |
apify call abdou_009/snapframe-apify-actor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abdou_009/snapframe-apify-actor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/OggEaYVoUWCTnBfm2/builds/xa7c2mH59AwQTufLR/openapi.json
