Introduction

The PDFSnap API lets you convert any public URL to a high-quality PDF or screenshot image. All requests require an API key and return JSON responses.

Base URL
https://screenshot.soniyal.com/api/v1
Response Format
application/json
HTTP Methods
POST for conversions, GET for status
Authentication

All API requests require an API key. Pass it using the X-API-Key HTTP header.

X-API-Key: pk_live_your_api_key_here
Get your API key from your dashboard. Free accounts get 50 requests/day.
Error Handling

Errors return a JSON object with success: false and an error object:

{
  "success": false,
  "error": {
    "code": "INVALID_URL",
    "message": "Invalid or blocked URL provided."
  }
}
HTTP CodeError CodeMeaning
401UNAUTHORIZEDMissing API key
401INVALID_API_KEYInvalid or revoked key
403FORBIDDENKey lacks permission for this endpoint
400MISSING_URLurl parameter not provided
400INVALID_URLURL is invalid or points to private host
429RATE_LIMIT_EXCEEDEDToo many requests per minute
429DAILY_LIMIT_EXCEEDEDDaily quota reached
500CONVERSION_FAILEDConversion error
Rate Limits
PlanRequests/DayRequests/Minute
FREE505
PRO2,00030
ENTERPRISE50,000100

Daily limits reset at midnight IST. Rate limit windows are per-minute per API key.

URL to PDF
POST https://screenshot.soniyal.com/api/v1/pdf.php Convert URL to PDF file
Parameters
ParameterTypeRequiredDefaultDescription
urlstringREQUIREDThe URL to convert (must be public http/https)
page_sizestringoptionalA4A4, A3, A5, Letter, Legal, Tabloid, Executive
orientationstringoptionalPortraitPortrait or Landscape
margin_topintegeroptional10Top margin in mm (0–50)
margin_rightintegeroptional10Right margin in mm (0–50)
margin_bottomintegeroptional10Bottom margin in mm (0–50)
margin_leftintegeroptional10Left margin in mm (0–50)
zoomfloatoptional1.0Zoom factor (0.1–3.0)
javascript_delayintegeroptional0Wait N ms for JS to execute (0–10000)
no_backgroundbooleanoptionalfalseRemove page background
grayscalebooleanoptionalfalseConvert to grayscale
page_numberingbooleanoptionalfalseAdd page numbers in footer
header_textstringoptionalCustom header text on each page
footer_textstringoptionalCustom footer text on each page
Response
{
  "success": true,
  "request_id": "550e8400-e29b-41d4-a716-446655440000",
  "data": {
    "url": "https://screenshot.soniyal.com/uploads/pdf_abc123.pdf",
    "filename": "pdf_abc123.pdf",
    "size": 148340,
    "size_human": "144.86 KB",
    "pages": 3,
    "type": "pdf",
    "options": {
      "page_size": "A4",
      "orientation": "Portrait",
      "margin_top": 10,
      "margin_right": 10,
      "margin_bottom": 10,
      "margin_left": 10,
      "zoom": 1.0
    },
    "expires_at": "2024-01-01T13:00:00+05:30"
  },
  "usage": {
    "today": 3,
    "limit": 50,
    "remaining": 47
  }
}
cURL Example
curl -X POST "https://screenshot.soniyal.com/api/v1/pdf.php" \
     -H "X-API-Key: pk_live_your_api_key" \
     -d "url=https://example.com/invoice/123" \
     -d "page_size=A4" \
     -d "orientation=Portrait" \
     -d "margin_top=15" \
     -d "margin_bottom=15" \
     -d "page_numbering=1" \
     -d "footer_text=Confidential Document"
URL to Image / Screenshot
Available on ALL plans including Free — use your own BYOK provider keys. Set up providers at Screenshot Keys. Pro plan also unlocks native wkhtmltoimage as final fallback.
POST https://screenshot.soniyal.com/api/v1/image.php Screenshot via BYOK provider chain
Parameters
ParameterTypeRequiredDefaultDescription
urlstringREQUIREDURL to screenshot (public http/https only)
enginestringoptionalautoauto tries BYOK chain then native. byok BYOK only. native wkhtmltoimage (Pro). Or a specific provider slug: apiflash, screenshotone, google_pagespeed, screenshotlayer, thumio, screenshotapi, abstractapi, screenshotmachine
formatstringoptionalpngOutput format: png, jpg
viewport_widthintegeroptional1440Browser viewport width
viewport_heightintegeroptional900Browser viewport height
output_widthintegeroptional0Resize output to this width (0 = no resize)
output_heightintegeroptional0Resize output to this height (0 = auto)
is_mobilebooleanoptionalfalseMobile viewport emulation
is_full_pagebooleanoptionalfalseCapture full scrollable page
is_dark_modebooleanoptionalfalseRequest dark mode rendering
device_scale_factorfloatoptional1DPR — use 2 for Retina quality
qualityintegeroptional90JPEG quality (10–100)
javascript_delayintegeroptional0Wait N ms for JS before capture
block_adsbooleanoptionalfalseBlock ads (ScreenshotOne only)
block_cookie_bannersbooleanoptionalfalseBlock cookie banners (ScreenshotOne only)
Response
{
  "success": true,
  "request_id": "uuid-here",
  "data": {
    "url": "https://screenshot.soniyal.com/uploads/shot_apiflash_abc123.png",
    "filename": "shot_apiflash_abc123.png",
    "size": 245120,
    "size_human": "239.38 KB",
    "width": 1440,
    "height": 900,
    "format": "png",
    "type": "screenshot",
    "provider": "apiflash",
    "provider_name": "ApiFlash",
    "expires_at": "2024-01-01T13:00:00+05:30"
  },
  "usage": { "today": 4, "limit": 200, "remaining": 196, "plan": "free" }
}
cURL Examples
# Auto — tries your provider chain in priority order
curl -X POST "https://screenshot.soniyal.com/api/v1/image.php" \
     -H "X-API-Key: pk_live_your_key" \
     -d "url=https://example.com" \
     -d "engine=auto" \
     -d "is_full_page=1" \
     -d "is_mobile=0"

# Force specific provider
curl -X POST "https://screenshot.soniyal.com/api/v1/image.php" \
     -H "X-API-Key: pk_live_your_key" \
     -d "url=https://example.com" \
     -d "engine=screenshotone" \
     -d "block_ads=1&block_cookie_banners=1&is_dark_mode=1"
BYOK Screenshot Setup

Screenshot API works on the Free plan when you bring your own provider keys. The system tries them in your configured priority order — if one fails or runs out of quota, it automatically moves to the next.

🖥️ url-to-png (Self-hosted)
Unlimited (your own server)
Unlimited, fully under your control, no quota limits
Requires Basic plan or higher. You must self-host the url-to-png service.
Get Key ↗
🔍 Google PageSpeed
25,000 / day (free)
Very generous free tier (25K/day), Google-powered
Returns Lighthouse screenshot — decent quality, no full-page.
Get Key ↗
ApiFlash
100 / month (free)
Full-page, dark mode, mobile emulation, great quality
Get Key ↗
📸 Screenshotlayer
100 / month (free)
Simple and reliable
Free plan: HTTP URLs only. HTTPS requires paid plan.
Get Key ↗
🎯 ScreenshotOne
100 / month (free)
Most parameters: block ads, block cookie banners, dark mode, Retina
Get Key ↗
🖼️ Thum.io
100 / day (free)
Very fast, generous daily free tier
Returns JPEG. Simple URL-based API.
Get Key ↗
📷 ScreenshotAPI.net
100 / month (free)
Reliable with good free allowance
Get Key ↗
🔷 Abstract API
100 / month (free)
Simple, clean API
Returns JPEG.
Get Key ↗
🖥️ ScreenshotMachine
100 / month (free)
Desktop / phone / tablet device modes
Get Key ↗
How to set up
  1. Go to Screenshot Keys page in your dashboard.
  2. Pick one or more providers, sign up for free, get your API key.
  3. Enter each key on the Screenshot Keys page.
  4. Drag to reorder priority — #1 is tried first, #2 if #1 fails, etc.
  5. Call the API with engine=auto (default) — it handles the rest.
Recommendation: Add Google PageSpeed (25,000/day free) as your last provider — it has the most generous free tier and works as a great final fallback.
URL to PNG (Dedicated)
POST https://screenshot.soniyal.com/api/v1/url_to_png.php Always PNG — all viewport/device options available

Same as image.php but output format is always png. Supports same engine param and all BYOK providers. Available on all plans including Free.

curl -X POST "https://screenshot.soniyal.com/api/v1/url_to_png.php" \
     -H "X-API-Key: pk_live_your_api_key" \
     -d "url=https://example.com" \
     -d "viewport_width=1440" \
     -d "viewport_height=900" \
     -d "output_width=720" \
     -d "output_height=450" \
     -d "device_scale_factor=2" \
     -d "is_full_page=1" \
     -d "is_dark_mode=0" \
     -d "is_mobile=0" \
     -d "javascript_delay=500"
Dynamic Print (Text on Image)
POST https://screenshot.soniyal.com/api/v1/dynamic_print.php Overlay custom text on any image — certificates, cards, invoices
Use the Visual Builder to design your layout and auto-generate the API URL — no coding needed for positioning!
Parameters
ParameterTypeRequiredDefaultDescription
image_urlstringREQUIREDBase image URL (PNG/JPG/GIF/WEBP)
text1, text2...stringREQUIREDText content for each layer (up to 20)
textN_xintegeroptional0X position in pixels from left
textN_yintegeroptional0Y position in pixels from top
textN_positionstringoptionalShorthand: 120,230 (x,y)
textN_sizeintegeroptional24Font size in pixels (6–500)
textN_fontstringoptionalarialFont: arial, times, courier, ubuntu, roboto, poppins, opensans, montserrat, lato, dejavu (or any TTF filename in /fonts/)
textN_colorstringoptional#000000Hex color code e.g. #FF5733
textN_boldbooleanoptional0Bold text
textN_italicbooleanoptional0Italic text
textN_alignstringoptionalleftText alignment: left, center, right
textN_anglefloatoptional0Rotation angle in degrees
textN_opacityintegeroptional100Opacity 0–100 (%)
textN_shadowbooleanoptional0Drop shadow effect
textN_strokebooleanoptional0Text outline/stroke
textN_stroke_colorstringoptional#ffffffStroke color
textN_stroke_widthintegeroptional2Stroke width 1–10 px
textN_max_widthintegeroptional0Auto word-wrap at this width (0=none)
textN_line_heightfloatoptional1.2Line height multiplier
output_formatstringoptionalpngOutput: png or jpg
output_qualityintegeroptional90JPG quality (10–100)
output_widthintegeroptional0Resize final image width (0=keep original)
output_heightintegeroptional0Resize final image height
Certificate Example — cURL
curl -X POST "https://screenshot.soniyal.com/api/v1/dynamic_print.php" \
     -H "X-API-Key: pk_live_your_key" \
     -d "image_url=https://example.com/certificate-template.png" \
     -d "text1=Preet Singh" \
     -d "text1_x=600" \
     -d "text1_y=420" \
     -d "text1_size=48" \
     -d "text1_font=times_bold" \
     -d "text1_color=%23333333" \
     -d "text1_align=center" \
     -d "text1_shadow=1" \
     -d "text2=Father: Gurpreet Singh" \
     -d "text2_x=600" \
     -d "text2_y=490" \
     -d "text2_size=28" \
     -d "text2_font=arial" \
     -d "text2_color=%23555555" \
     -d "text2_align=center" \
     -d "text3=Date: 2 May 2026" \
     -d "text3_x=600" \
     -d "text3_y=550" \
     -d "text3_size=20" \
     -d "text3_font=arial" \
     -d "text3_color=%23888888" \
     -d "text3_align=center" \
     -d "output_format=png"
PHP Bulk Certificate Generator
<?php
$students = [
    ['name' => 'Preet Singh',   'father' => 'Gurpreet Singh', 'date' => '2026-05-02'],
    ['name' => 'Deepam Jain',   'father' => 'Rajesh Jain',    'date' => '2026-05-02'],
    // ... more students
];

$apiKey       = 'pk_live_your_key';
$templateUrl  = 'https://yoursite.com/cert-template.png';
$endpoint     = 'https://screenshot.soniyal.com/api/v1/dynamic_print.php';

foreach ($students as $student) {
    $params = http_build_query([
        'image_url'      => $templateUrl,
        'text1'          => $student['name'],
        'text1_x'        => 600, 'text1_y' => 420,
        'text1_size'     => 48,  'text1_font' => 'times_bold',
        'text1_color'    => '#333333', 'text1_align' => 'center',
        'text1_shadow'   => 1,
        'text2'          => 'Father: ' . $student['father'],
        'text2_x'        => 600, 'text2_y' => 490,
        'text2_size'     => 28,  'text2_font' => 'arial',
        'text2_color'    => '#555555', 'text2_align' => 'center',
        'text3'          => 'Date: ' . $student['date'],
        'text3_x'        => 600, 'text3_y' => 550,
        'text3_size'     => 20,  'text3_font' => 'arial',
        'text3_color'    => '#888888', 'text3_align' => 'center',
        'output_format'  => 'png',
    ]);

    $ctx = stream_context_create([
        'http' => [
            'method'  => 'POST',
            'header'  => "X-API-Key: {$apiKey}\r\nContent-Type: application/x-www-form-urlencoded",
            'content' => $params,
            'timeout' => 30,
        ]
    ]);
    $res  = json_decode(file_get_contents($endpoint, false, $ctx), true);
    $pdfUrl = $res['data']['url'];

    // Save or email certificate
    echo "Certificate for {$student['name']}: {$pdfUrl}\n";
}
?>
Account Status
GET https://screenshot.soniyal.com/api/v1/status.php Check account & usage
curl "https://screenshot.soniyal.com/api/v1/status.php" \
     -H "X-API-Key: pk_live_your_api_key"
PHP Example — Invoice to PDF
<?php
function convertInvoiceToPdf(string $invoiceUrl, string $apiKey): ?string {
    $params = http_build_query([
        'url'            => $invoiceUrl,
        'page_size'      => 'A4',
        'orientation'    => 'Portrait',
        'margin_top'     => 15,
        'margin_right'   => 15,
        'margin_bottom'  => 20,
        'margin_left'    => 15,
        'page_numbering' => 1,
        'footer_text'    => 'Generated by MyApp',
    ]);

    $context = stream_context_create([
        'http' => [
            'method'  => 'POST',
            'header'  => "X-API-Key: {$apiKey}\r\nContent-Type: application/x-www-form-urlencoded",
            'content' => $params,
            'timeout' => 60,
        ]
    ]);

    $response = file_get_contents('https://screenshot.soniyal.com/api/v1/pdf.php', false, $context);
    if (!$response) return null;

    $data = json_decode($response, true);
    if (!$data['success']) {
        error_log('PDF error: ' . $data['error']['message']);
        return null;
    }

    return $data['data']['url']; // Download URL
}

// Usage:
$pdfUrl = convertInvoiceToPdf('https://myapp.com/invoices/INV-001', 'pk_live_xxx');
header('Location: ' . $pdfUrl); // Redirect user to download
?>
cURL Example — Screenshot
curl -X POST "https://screenshot.soniyal.com/api/v1/image.php" \
     -H "X-API-Key: pk_live_your_api_key" \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "url=https://github.com" \
     -d "width=1280" \
     -d "format=jpg" \
     -d "quality=90" \
     -d "full_page=0" | python3 -m json.tool
JavaScript (fetch) Example
async function urlToPdf(url, apiKey) {
  const params = new URLSearchParams({
    url,
    page_size: 'A4',
    orientation: 'Portrait',
    margin_top: 10,
    margin_bottom: 10,
  });

  const response = await fetch('https://screenshot.soniyal.com/api/v1/pdf.php', {
    method: 'POST',
    headers: {
      'X-API-Key': apiKey,
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: params.toString(),
  });

  const data = await response.json();
  if (!data.success) throw new Error(data.error.message);
  return data.data.url; // PDF download URL
}

// Usage
urlToPdf('https://example.com', 'pk_live_xxx')
  .then(pdfUrl => window.open(pdfUrl, '_blank'))
  .catch(console.error);
Python Example
import requests

def url_to_pdf(url: str, api_key: str) -> str:
    response = requests.post(
        'https://screenshot.soniyal.com/api/v1/pdf.php',
        headers={'X-API-Key': api_key},
        data={
            'url': url,
            'page_size': 'A4',
            'orientation': 'Portrait',
            'margin_top': 15,
            'page_numbering': '1',
        },
        timeout=60
    )
    response.raise_for_status()
    data = response.json()
    if not data['success']:
        raise Exception(data['error']['message'])
    return data['data']['url']

# Usage
pdf_url = url_to_pdf('https://invoice.example.com/123', 'pk_live_xxx')
print(f'PDF ready: {pdf_url}')