Quick Start: Django + SnapAPI
Install the Python SDK and add your API key to Django settings. Then call the screenshot or PDF endpoint directly from any view, management command, or Celery task.
pip install requests # or use the snapapi Python SDK
settings.py
import os
SNAPAPI_KEY = os.environ.get("SNAPAPI_KEY", "")
SNAPAPI_BASE_URL = "https://api.snapapi.pics"
Screenshot in a Django View
import requests
from django.conf import settings
from django.http import JsonResponse
def capture_screenshot(request):
target_url = request.GET.get("url")
if not target_url:
return JsonResponse({"error": "url required"}, status=400)
resp = requests.post(
f"{settings.SNAPAPI_BASE_URL}/v1/screenshot",
headers={"X-Api-Key": settings.SNAPAPI_KEY},
json={
"url": target_url,
"format": "png",
"full_page": True,
"width": 1280,
},
timeout=30,
)
if resp.status_code != 200:
return JsonResponse({"error": "capture failed"}, status=502)
data = resp.json()
return JsonResponse({"screenshot_url": data["url"]})
PDF Export in Django (Invoices, Reports)
A common Django use case is exporting model data as a PDF — invoices, order confirmations, reports. The typical pattern: render your data to an HTML template, serve it at a temporary URL, then call SnapAPI to convert it to PDF.
from django.template.loader import render_to_string
from django.http import HttpResponse
import requests, base64
def invoice_pdf(request, invoice_id):
invoice = get_object_or_404(Invoice, id=invoice_id, user=request.user)
# Option 1: pass a URL to the HTML invoice page
invoice_url = request.build_absolute_uri(
reverse("invoice_html", args=[invoice_id])
)
token = generate_signed_token(invoice_id)
signed_url = f"{invoice_url}?token={token}"
resp = requests.post(
"https://api.snapapi.pics/v1/pdf",
headers={"X-Api-Key": settings.SNAPAPI_KEY},
json={
"url": signed_url,
"format": "A4",
"margin": "1.5cm",
"print_background": True,
"wait_for": ".invoice-ready",
},
timeout=30,
)
pdf_data = resp.json()
pdf_response = requests.get(pdf_data["url"])
response = HttpResponse(pdf_response.content, content_type="application/pdf")
response["Content-Disposition"] = f'attachment; filename="invoice-{invoice_id}.pdf"'
return response
Celery Task for Async Screenshot Capture
For non-blocking screenshot generation, wrap the API call in a Celery task. The Django view triggers the task and returns immediately, while the task captures the screenshot and stores the result in your database or cache.
from celery import shared_task
from django.core.cache import cache
import requests
@shared_task(bind=True, max_retries=3)
def capture_site_screenshot(self, url, screenshot_id):
try:
resp = requests.post(
"https://api.snapapi.pics/v1/screenshot",
headers={"X-Api-Key": settings.SNAPAPI_KEY},
json={"url": url, "format": "png", "full_page": True},
timeout=30,
)
resp.raise_for_status()
data = resp.json()
# Store result in cache for 1 hour
cache.set(f"screenshot:{screenshot_id}", data["url"], timeout=3600)
return data["url"]
except requests.RequestException as exc:
# Retry with exponential backoff on network errors
raise self.retry(exc=exc, countdown=2 ** self.request.retries)
Django REST Framework Integration
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status, permissions
import requests
class ScreenshotAPIView(APIView):
permission_classes = [permissions.IsAuthenticated]
def post(self, request):
url = request.data.get("url")
format_ = request.data.get("format", "png")
if not url:
return Response({"error": "url is required"}, status=status.HTTP_400_BAD_REQUEST)
resp = requests.post(
"https://api.snapapi.pics/v1/screenshot",
headers={"X-Api-Key": settings.SNAPAPI_KEY},
json={"url": url, "format": format_, "full_page": True},
timeout=30,
)
if resp.ok:
return Response(resp.json())
return Response({"error": "upstream error"}, status=status.HTTP_502_BAD_GATEWAY)
Why Not Use Playwright Directly in Django?
Running Playwright inside a Django process is problematic. Playwright requires an event loop, which conflicts with Django's synchronous request handling. You can work around this with asyncio.run() in views, but Chromium's memory footprint means a few concurrent requests can exhaust your dyno or container. SnapAPI externalizes the browser entirely — your Django app stays stateless, scales horizontally, and never needs a browser binary in your Docker image.
Pricing for Django Applications
The Free plan gives 200 captures per month — suitable for prototyping or low-traffic Django applications. Starter at $19/month covers 5,000 captures (great for SaaS apps with occasional PDF exports). Pro at $79/month covers 50,000 captures. Business at $299/month covers 500,000. All plans use the same API key with no per-endpoint restrictions.
Add Screenshots to Your Django App →