Hash Generation Guide
Understanding how to generate the required MD5 hash is essential for using Capture API. The hash serves as a security mechanism to authenticate your requests and prevent unauthorized usage.
How Hash Generation Works
The Capture API uses MD5 hashing to verify that requests are coming from authenticated users. The hash is generated by combining your API secret with the request URL and parameters.
Basic Formula
MD5(API_SECRET + REQUEST_URL_WITH_PARAMETERS)
URL Structure
All Capture API requests follow this structure:
https://cdn.capture.page/{API_KEY}/{GENERATED_HASH}/{ENDPOINT}?url={TARGET_URL}&{PARAMETERS}
Components:
{API_KEY}
: Your API key from the console{GENERATED_HASH}
: MD5 hash you generate{ENDPOINT}
: API endpoint (image, pdf, content, metadata, animated){TARGET_URL}
: The website URL you want to capture{PARAMETERS}
: Optional parameters for customization
Step-by-Step Process
1. Prepare the Hash Input
The hash input consists of:
API_SECRET + 'url=' + TARGET_URL + '&' + PARAMETERS
2. Generate MD5 Hash
Create an MD5 hash of the complete string from step 1.
3. Construct Final URL
Use the hash in your API request URL.
Language-Specific Examples
JavaScript/Node.js
const crypto = require('crypto');
function generateCaptureURL(apiKey, apiSecret, targetUrl, endpoint = 'image', params = {}) {
// Build parameter string
const paramString = Object.keys(params)
.map(key => `${key}=${encodeURIComponent(params[key])}`)
.join('&');
// Create hash input
const hashInput = apiSecret + 'url=' + encodeURIComponent(targetUrl) +
(paramString ? '&' + paramString : '');
// Generate MD5 hash
const hash = crypto.createHash('md5').update(hashInput).digest('hex');
// Construct final URL
const finalUrl = `https://cdn.capture.page/${apiKey}/${hash}/${endpoint}?url=${encodeURIComponent(targetUrl)}` +
(paramString ? '&' + paramString : '');
return finalUrl;
}
// Example usage
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';
const targetUrl = 'https://example.com';
// Simple screenshot
const screenshotUrl = generateCaptureURL(apiKey, apiSecret, targetUrl, 'image');
console.log(screenshotUrl);
// Screenshot with parameters
const advancedUrl = generateCaptureURL(apiKey, apiSecret, targetUrl, 'image', {
vw: 1920,
vh: 1080,
format: 'png',
delay: 2
});
console.log(advancedUrl);
Python
import hashlib
import urllib.parse
def generate_capture_url(api_key, api_secret, target_url, endpoint='image', params=None):
if params is None:
params = {}
# Build parameter string
param_string = '&'.join([f"{key}={urllib.parse.quote_plus(str(value))}"
for key, value in params.items()])
# Create hash input
hash_input = (api_secret + 'url=' + urllib.parse.quote_plus(target_url) +
('&' + param_string if param_string else ''))
# Generate MD5 hash
hash_value = hashlib.md5(hash_input.encode()).hexdigest()
# Construct final URL
final_url = (f"https://cdn.capture.page/{api_key}/{hash_value}/{endpoint}"
f"?url={urllib.parse.quote_plus(target_url)}")
if param_string:
final_url += '&' + param_string
return final_url
# Example usage
api_key = 'your-api-key'
api_secret = 'your-api-secret'
target_url = 'https://example.com'
# Simple screenshot
screenshot_url = generate_capture_url(api_key, api_secret, target_url, 'image')
print(screenshot_url)
# PDF with parameters
pdf_url = generate_capture_url(api_key, api_secret, target_url, 'pdf', {
'format': 'A4',
'landscape': 'true',
'delay': 3
})
print(pdf_url)
PHP
<?php
function generateCaptureURL($apiKey, $apiSecret, $targetUrl, $endpoint = 'image', $params = []) {
// Build parameter string
$paramString = '';
if (!empty($params)) {
$paramPairs = [];
foreach ($params as $key => $value) {
$paramPairs[] = $key . '=' . urlencode($value);
}
$paramString = implode('&', $paramPairs);
}
// Create hash input
$hashInput = $apiSecret . 'url=' . urlencode($targetUrl) .
($paramString ? '&' . $paramString : '');
// Generate MD5 hash
$hash = md5($hashInput);
// Construct final URL
$finalUrl = "https://cdn.capture.page/{$apiKey}/{$hash}/{$endpoint}?url=" . urlencode($targetUrl);
if ($paramString) {
$finalUrl .= '&' . $paramString;
}
return $finalUrl;
}
// Example usage
$apiKey = 'your-api-key';
$apiSecret = 'your-api-secret';
$targetUrl = 'https://example.com';
// Simple screenshot
$screenshotUrl = generateCaptureURL($apiKey, $apiSecret, $targetUrl, 'image');
echo $screenshotUrl . "\n";
// Advanced screenshot
$advancedUrl = generateCaptureURL($apiKey, $apiSecret, $targetUrl, 'image', [
'vw' => 1920,
'vh' => 1080,
'darkMode' => 'true',
'blockAds' => 'true'
]);
echo $advancedUrl . "\n";
?>
Go
package main
import (
"crypto/md5"
"fmt"
"net/url"
"strings"
)
func generateCaptureURL(apiKey, apiSecret, targetURL, endpoint string, params map[string]string) string {
// Build parameter string
var paramPairs []string
for key, value := range params {
paramPairs = append(paramPairs, fmt.Sprintf("%s=%s", key, url.QueryEscape(value)))
}
paramString := strings.Join(paramPairs, "&")
// Create hash input
hashInput := apiSecret + "url=" + url.QueryEscape(targetURL)
if paramString != "" {
hashInput += "&" + paramString
}
// Generate MD5 hash
hash := fmt.Sprintf("%x", md5.Sum([]byte(hashInput)))
// Construct final URL
finalURL := fmt.Sprintf("https://cdn.capture.page/%s/%s/%s?url=%s",
apiKey, hash, endpoint, url.QueryEscape(targetURL))
if paramString != "" {
finalURL += "&" + paramString
}
return finalURL
}
func main() {
apiKey := "your-api-key"
apiSecret := "your-api-secret"
targetURL := "https://example.com"
// Simple screenshot
screenshotURL := generateCaptureURL(apiKey, apiSecret, targetURL, "image", nil)
fmt.Println(screenshotURL)
// Screenshot with parameters
params := map[string]string{
"vw": "1920",
"vh": "1080",
"format": "png",
"delay": "2",
}
advancedURL := generateCaptureURL(apiKey, apiSecret, targetURL, "image", params)
fmt.Println(advancedURL)
}
Rust
use std::collections::HashMap;
fn generate_capture_url(
api_key: &str,
api_secret: &str,
target_url: &str,
endpoint: &str,
params: Option<HashMap<String, String>>,
) -> String {
// Build parameter string
let param_string = if let Some(params) = params {
params
.iter()
.map(|(key, value)| format!("{}={}", key, urlencoding::encode(value)))
.collect::<Vec<_>>()
.join("&")
} else {
String::new()
};
// Create hash input
let mut hash_input = format!("{}url={}", api_secret, urlencoding::encode(target_url));
if !param_string.is_empty() {
hash_input.push('&');
hash_input.push_str(¶m_string);
}
// Generate MD5 hash
let hash = format!("{:x}", md5::compute(hash_input.as_bytes()));
// Construct final URL
let mut final_url = format!(
"https://cdn.capture.page/{}/{}/{}?url={}",
api_key,
hash,
endpoint,
urlencoding::encode(target_url)
);
if !param_string.is_empty() {
final_url.push('&');
final_url.push_str(¶m_string);
}
final_url
}
fn main() {
let api_key = "your-api-key";
let api_secret = "your-api-secret";
let target_url = "https://example.com";
// Simple screenshot
let screenshot_url = generate_capture_url(api_key, api_secret, target_url, "image", None);
println!("{}", screenshot_url);
// Screenshot with parameters
let mut params = HashMap::new();
params.insert("vw".to_string(), "1920".to_string());
params.insert("vh".to_string(), "1080".to_string());
params.insert("format".to_string(), "png".to_string());
let advanced_url = generate_capture_url(api_key, api_secret, target_url, "image", Some(params));
println!("{}", advanced_url);
}
Ruby
require 'digest'
require 'uri'
def generate_capture_url(api_key, api_secret, target_url, endpoint = 'image', params = {})
# Build parameter string
param_string = params.map { |key, value| "#{key}=#{URI.encode_www_form_component(value.to_s)}" }.join('&')
# Create hash input
hash_input = api_secret + 'url=' + URI.encode_www_form_component(target_url)
hash_input += '&' + param_string unless param_string.empty?
# Generate MD5 hash
hash = Digest::MD5.hexdigest(hash_input)
# Construct final URL
final_url = "https://cdn.capture.page/#{api_key}/#{hash}/#{endpoint}?url=#{URI.encode_www_form_component(target_url)}"
final_url += '&' + param_string unless param_string.empty?
final_url
end
# Example usage
api_key = 'your-api-key'
api_secret = 'your-api-secret'
target_url = 'https://example.com'
# Simple screenshot
screenshot_url = generate_capture_url(api_key, api_secret, target_url, 'image')
puts screenshot_url
# PDF with parameters
pdf_url = generate_capture_url(api_key, api_secret, target_url, 'pdf', {
format: 'A4',
landscape: true,
delay: 3
})
puts pdf_url
Common Examples
Screenshot Examples
Basic Screenshot
// Hash input: api_secret + 'url=https://example.com'
const hashInput = 'your-api-secret' + 'url=https://example.com';
const hash = crypto.createHash('md5').update(hashInput).digest('hex');
// URL: https://cdn.capture.page/your-api-key/{hash}/image?url=https://example.com
Screenshot with Viewport
// Hash input: api_secret + 'url=https://example.com&vw=1920&vh=1080'
const hashInput = 'your-api-secret' + 'url=https://example.com&vw=1920&vh=1080';
const hash = crypto.createHash('md5').update(hashInput).digest('hex');
// URL: https://cdn.capture.page/your-api-key/{hash}/image?url=https://example.com&vw=1920&vh=1080
Mobile Screenshot
// Hash input: api_secret + 'url=https://example.com&emulateDevice=iphone_15_pro'
const hashInput = 'your-api-secret' + 'url=https://example.com&emulateDevice=iphone_15_pro';
const hash = crypto.createHash('md5').update(hashInput).digest('hex');
PDF Examples
Basic PDF
// Hash input: api_secret + 'url=https://example.com'
const hashInput = 'your-api-secret' + 'url=https://example.com';
const hash = crypto.createHash('md5').update(hashInput).digest('hex');
// URL: https://cdn.capture.page/your-api-key/{hash}/pdf?url=https://example.com
PDF with Custom Format
// Hash input: api_secret + 'url=https://example.com&format=A4&landscape=true'
const hashInput = 'your-api-secret' + 'url=https://example.com&format=A4&landscape=true';
const hash = crypto.createHash('md5').update(hashInput).digest('hex');
Content & Metadata Examples
Content Extraction
// Hash input: api_secret + 'url=https://example.com'
const hashInput = 'your-api-secret' + 'url=https://example.com';
const hash = crypto.createHash('md5').update(hashInput).digest('hex');
// URL: https://cdn.capture.page/your-api-key/{hash}/content?url=https://example.com
Metadata with Delay
// Hash input: api_secret + 'url=https://example.com&delay=3'
const hashInput = 'your-api-secret' + 'url=https://example.com&delay=3';
const hash = crypto.createHash('md5').update(hashInput).digest('hex');
Important Considerations
1. Parameter Order
The order of parameters in your hash input must match the order in your final URL:
// ✅ Correct - same order
// Hash: api_secret + 'url=example.com&vw=1920&vh=1080'
// URL: .../image?url=example.com&vw=1920&vh=1080
// ❌ Incorrect - different order
// Hash: api_secret + 'url=example.com&vw=1920&vh=1080'
// URL: .../image?url=example.com&vh=1080&vw=1920
2. URL Encoding
Always URL-encode parameter values consistently:
// ✅ Correct - URL encode special characters
const targetUrl = 'https://example.com/page?id=123&ref=test';
const encodedUrl = encodeURIComponent(targetUrl);
const hashInput = apiSecret + 'url=' + encodedUrl;
3. Boolean Parameters
Convert boolean values to strings:
// ✅ Correct
const params = {
darkMode: 'true',
blockAds: 'false'
};
// ❌ Incorrect
const params = {
darkMode: true,
blockAds: false
};
4. Empty Parameters
Exclude parameters with empty or undefined values:
// ✅ Correct - filter out empty values
const params = { vw: 1920, vh: '', delay: 3 };
const validParams = Object.fromEntries(
Object.entries(params).filter(([_, value]) => value !== '' && value != null)
);
Security Best Practices
1. Keep API Secret Secure
- Never expose API secret in client-side code
- Use environment variables for secrets
- Rotate secrets periodically
2. Server-Side Hash Generation
// ✅ Server-side (secure)
app.get('/generate-url', (req, res) => {
const hash = generateHash(API_SECRET, req.query.url, req.query.params);
res.json({ url: constructURL(API_KEY, hash, req.query.url, req.query.params) });
});
// ❌ Client-side (insecure)
const hash = generateHash(API_SECRET, url, params); // Exposes secret!
3. Validate Inputs
Always validate and sanitize inputs before hash generation:
function validateParams(params) {
const allowedParams = ['vw', 'vh', 'format', 'delay', 'darkMode'];
return Object.fromEntries(
Object.entries(params).filter(([key]) => allowedParams.includes(key))
);
}
Debugging Hash Issues
Common Problems
1. Hash Mismatch
Error: Invalid hash
Solution: Verify hash input matches URL parameters exactly.
2. URL Encoding Issues
// Debug: Print hash input
console.log('Hash input:', hashInput);
console.log('Generated hash:', hash);
console.log('Final URL:', finalUrl);
3. Parameter Order Problems
// Use consistent parameter ordering
function sortParams(params) {
return Object.keys(params).sort().reduce((sorted, key) => {
sorted[key] = params[key];
return sorted;
}, {});
}
Testing Hash Generation
function testHashGeneration() {
const apiSecret = 'test-secret';
const testCases = [
{
url: 'https://example.com',
params: {},
expected: 'url=https://example.com'
},
{
url: 'https://example.com',
params: { vw: 1920, vh: 1080 },
expected: 'url=https://example.com&vw=1920&vh=1080'
}
];
testCases.forEach((test, index) => {
const hashInput = apiSecret + test.expected;
const hash = crypto.createHash('md5').update(hashInput).digest('hex');
console.log(`Test ${index + 1}: ${hash}`);
});
}
Online Hash Generator
For quick testing, you can use online MD5 generators:
- Construct your hash input string
- Paste into an MD5 generator (e.g., md5hashgenerator.com)
- Use the resulting hash in your URL
Example:
- Hash input:
your-api-secreturl=https://example.com&vw=1920&vh=1080
- MD5 result:
a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
- Final URL:
https://cdn.capture.page/your-api-key/a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6/image?url=https://example.com&vw=1920&vh=1080
See Also
- Get Started - Basic API usage
- Advanced Options - Using parameters with hash generation
- SDK Overview - SDKs handle hash generation automatically
- Screenshot Options - All available screenshot parameters