Docs

URL'den ekran görüntüsü al

Kendi sunucunuzda çalışan, Playwright tabanlı screenshot servisi. Tek bir HTTP isteği ile herhangi bir web sayfasının PNG veya JPEG görüntüsünü alın — ScreenshotOne benzeri sözleşme, kota sınırı yok.

Hızlı başlangıç

Üç adımda ilk screenshot'unuzu alın.

1. API anahtarını ayarlayın

Sunucudaki .env dosyasında ACCESS_KEY değerini belirleyin. Bu key harici bir servisten gelmez — siz üretirsiniz.

.env
ACCESS_KEY=uzun-ve-rastgele-bir-anahtar-buraya

2. Sunucuyu çalıştırın

Terminal
npm install
npx playwright install chromium
npm start

3. İlk isteği gönderin

cURL
curl -o screenshot.png \
  -H "X-Access-Key: YOUR_ACCESS_KEY" \
  "/take?url=https://example.com"
Başarılı yanıt ham görüntü binary döner (image/png veya image/jpeg). JSON değildir.

Kimlik doğrulama

/take endpoint'i kimlik doğrulama gerektirir. /health ve bu docs sayfası herkese açıktır.

Yöntem Örnek Önerilen
Header X-Access-Key: YOUR_KEY Evet — loglarda URL'de görünmez
Alternatif header X-Api-Key: YOUR_KEY Evet
Query ?access_key=YOUR_KEY Sadece sunucu tarafı veya <img> için

Hatalı key → 401

JSON
{
  "error": {
    "code": "unauthorized",
    "message": "Invalid or missing access key"
  }
}

Base URL

Tüm endpoint'ler bu adrese göredir. Uygulamanızda tek bir değişken olarak saklayın.

Base URL:
Production'da mutlaka HTTPS kullanın. Access key'i asla frontend bundle içine gömmeyin — backend'inizden proxy'leyin.

Endpoint'ler

Method Path Auth Açıklama
GET / Hayır Test arayüzü
GET /docs Hayır Bu dokümantasyon
GET /health Hayır Sağlık kontrolü
GET /take Evet Screenshot al

GET /health

Docker healthcheck, uptime monitor ve deploy doğrulaması için kullanın.

GET/health

200 OKapplication/json

{
  "status": "ok",
  "timestamp": "2026-05-19T12:00:00.000Z"
}

GET /take

Hedef URL'yi headless Chromium ile açar, sayfayı render eder ve ekran görüntüsünü döndürür.

GET/take?url=…&…

İşlem akışı

1URL doğrula
2Sayfayı aç
3Cookie kapat*
4Bekle (delay)
5Screenshot

* auto_consent=true ise

Örnek istek

HTTP
GET /take?url=https://example.com&format=png&full_page=false HTTP/1.1
Host: your-server.com
X-Access-Key: YOUR_ACCESS_KEY

Başarılı yanıt

AlanDeğer
Status200
Content-Typeimage/png veya image/jpeg
Cache-Controlno-store
BodyBinary görüntü

Query parametreleri

/take endpoint'ine eklenebilir tüm parametreler:

Parametre Zorunlu Varsayılan Açıklama
url Evet Hedef sayfa. https:// yoksa otomatik eklenir.
access_key Evet* API anahtarı (*header ile gönderilebilir)
format Hayır png png, jpeg, jpg
viewport_width Hayır 1280 320 – 3840 px
viewport_height Hayır 720 240 – 2160 px
full_page Hayır false Tüm kaydırılabilir sayfa
delay Hayır 0 Yükleme sonrası bekleme (ms), max 10000
block_ads Hayır true Reklam/tracker domain engeli
auto_consent Hayır false Cookie banner (EN, DE, IT, FR, NL, ES, TR)
timeout Hayır 30000 Navigation timeout (ms), max 60000

Boolean değerler

full_page, block_ads, auto_consent için:

  • true: true, 1, yes
  • false: false, 0, no

Örnek URL'ler

# Basit
/take?url=https://example.com

# Tam sayfa + cookie + gecikme
/take?url=https://site.com&full_page=true&auto_consent=true&delay=2000

# Mobil viewport
/take?url=https://site.com&viewport_width=390&viewport_height=844

Hata kodları

Hata durumunda yanıt JSON olur; görüntü dönmez.

HTTP error.code Açıklama
400invalid_urlURL geçersiz, eksik veya SSRF engeli
401unauthorizedAccess key hatalı/eksik
408timeoutSayfa yükleme zaman aşımı
422navigation_failedSayfa açılamadı (DNS, SSL…)
429Rate limit aşıldı
500internal_errorSunucu hatası
Hata formatı
{
  "error": {
    "code": "invalid_url",
    "message": "Private IP addresses are not allowed"
  }
}

Rate limiting

IP başına varsayılan 60 istek / 60 saniye. Aşımda 429 Too Many Requests.

RATE_LIMIT_MAX=60
RATE_LIMIT_TIME_WINDOW=60000

Uygulamana entegrasyon

Diğer uygulamanızdan kullanırken önerilen mimari:

📱Kullanıcı / UI
⚙️Sizin backend
Screenshot API
  1. API key'i backend'de tutunSCREENSHOT_API_URL ve SCREENSHOT_API_KEY environment variable olarak.
  2. Frontend doğrudan çağırmasın — key sızar. Kendi API'nize POST /api/screenshot gibi bir endpoint ekleyin; o Screenshot API'yi çağırsın.
  3. Timeout'u yüksek tutun — screenshot 5–30 sn sürebilir. HTTP client timeout en az 60–120 sn olsun.
  4. Hata JSON'unu parse edinres.ok false ise body JSON'dur.
  5. Görüntüyü cache'leyin — aynı URL için S3/CDN'e kaydedip tekrar kullanın.
Backend proxy örneği: kullanıcı { "url": "https://..." } gönderir → sunucunuz Screenshot API'ye istek atar → dönen PNG'yi storage'a yazar → public URL döner.

Kod örnekleri

Base URL bu sunucuya göre otomatik doldurulur:

fetch — tarayıcı veya Node 18+
async function captureScreenshot(targetUrl) {
  const params = new URLSearchParams({
    url: targetUrl,
    format: 'png',
    delay: '1500',
    auto_consent: 'true',
  });

  const res = await fetch(`${API_BASE}/take?${params}`, {
    headers: { 'X-Access-Key': API_KEY },
  });

  if (!res.ok) {
    const err = await res.json();
    throw new Error(err.error?.message ?? 'Screenshot failed');
  }

  return Buffer.from(await res.arrayBuffer()); // Node
  // return await res.blob(); // Browser
}

const API_BASE = 'BASE_PLACEHOLDER';
const API_KEY = process.env.SCREENSHOT_API_KEY;
Express proxy endpoint
app.post('/api/screenshot', async (req, res) => {
  const { url } = req.body;
  if (!url) return res.status(400).json({ error: 'url required' });

  const qs = new URLSearchParams({ url, format: 'png', delay: '2000' });
  const apiRes = await fetch(`${process.env.SCREENSHOT_API_URL}/take?${qs}`, {
    headers: { 'X-Access-Key': process.env.SCREENSHOT_API_KEY },
    signal: AbortSignal.timeout(120_000),
  });

  if (!apiRes.ok) {
    const err = await apiRes.json();
    return res.status(apiRes.status).json(err);
  }

  const buffer = Buffer.from(await apiRes.arrayBuffer());
  res.set('Content-Type', apiRes.headers.get('content-type'));
  res.send(buffer);
});
PHP
$query = http_build_query([
    'url' => 'https://example.com',
    'format' => 'png',
    'full_page' => 'true',
]);

$ctx = stream_context_create([
    'http' => [
        'header' => "X-Access-Key: " . getenv('SCREENSHOT_API_KEY'),
        'timeout' => 120,
    ],
]);

$image = file_get_contents(
    getenv('SCREENSHOT_API_URL') . '/take?' . $query,
    false,
    $ctx
);

file_put_contents('screenshot.png', $image);
Python
import os
import requests

def capture(url: str) -> bytes:
    r = requests.get(
        f"{os.environ['SCREENSHOT_API_URL']}/take",
        params={
            "url": url,
            "format": "png",
            "auto_consent": "true",
            "delay": 2000,
        },
        headers={"X-Access-Key": os.environ["SCREENSHOT_API_KEY"]},
        timeout=120,
    )
    r.raise_for_status()
    return r.content

image = capture("https://example.com")
open("out.png", "wb").write(image)
cURL
curl -o out.png \
  -H "X-Access-Key: $SCREENSHOT_API_KEY" \
  "$SCREENSHOT_API_URL/take?url=https://example.com&delay=2000"

ScreenshotOne geçişi

Daha önce ScreenshotOne kullanıyorsanız minimum değişiklik:

ScreenshotOneBu API
api.screenshotone.com/take /take
access_keyAynı isim veya header
url, full_page, delayAynı
viewport_width/heightAynı
format=webpDesteklenmiyor — png/jpeg kullanın

En iyi pratikler

  • SPA siteler için delay=2000 veya daha fazla kullanın.
  • Cookie banner için auto_consent=true deneyin; her sitede çalışmaz.
  • Yavaş siteler için timeout=45000 artırın.
  • Mobil önizleme için viewport 390×844 gibi değerler verin.
  • Production'da Docker + shm_size: 1gb kullanın.

Sunucu yapılandırması

Bunlar istemci parametresi değil; sunucu .env dosyasından okunur.

DeğişkenVarsayılanAçıklama
PORT3000HTTP port
ACCESS_KEYZorunlu API anahtarı
MAX_CONCURRENT3Eşzamanlı screenshot
DEFAULT_TIMEOUT30000Varsayılan timeout (ms)
MAX_TIMEOUT60000Max timeout (ms)
RATE_LIMIT_MAX60Rate limit
ALLOWED_DOMAINSOpsiyonel domain whitelist

Güvenlik

  • SSRF: localhost ve özel IP'ler engellenir.
  • ALLOWED_DOMAINS ile sadece izinli siteleri screenshot alabilirsiniz.
  • Access key asla Git'e commit edilmemeli.
  • Production'da TLS (Nginx/Caddy) zorunlu sayılmalı.

Sınırlamalar

ÖzellikDurum
WebP formatDesteklenmiyor
POST /takeHenüz yok
HTML string → screenshotHenüz yok
Cookie consentHeuristik, %100 değil