REST API
Generate, fetch, share, and delete PDFs via HTTPS. Same auth as the rest of DeepSyte — Bearer token from your dashboard.
Base URL
https://api.deepsyte.comThe API is hosted on Railway. Webhooks and SSE streams are served from the same origin, so you only need to allowlist one host.
Authentication
All endpoints (except the public share viewers) require a Bearer token in the
Authorization header:
curl https://api.deepsyte.com/v1/screenshot/<id> \
-H "Authorization: Bearer $DEEPSYTE_KEY"Generate a key from the DeepSyte dashboard → API keys — one account, one set of keys works for PDFShot and every other DeepSyte product.
Generate a PDF
POST /v1/screenshot
Content-Type: application/json
Authorization: Bearer <key>
{
"url": "https://example.com",
"pdf": true,
"fullPage": true,
"width": 1280,
"height": 800,
"delay": 0
}Returns immediately with a screenshotId and a status: "pending". The
worker generates the PDF in the background; track it via polling, SSE, or
webhooks.
Tunable params
| Param | Default | Notes |
|---|---|---|
url | required | HTTP/HTTPS only. |
pdf | false | Set true for PDF, false for PNG/JPEG. |
fullPage | false | Scrolls before capture to trigger lazy content. |
width | 1280 | Viewport width before render. |
height | 800 | Viewport height before render. |
delay | 0 | Extra ms to wait after page load. Useful for SPAs. |
darkMode | false | Sends prefers-color-scheme: dark. |
Check status
GET /v1/screenshot/<id>
Authorization: Bearer <key>Response:
{
"id": "wJqTW...",
"url": "https://example.com",
"status": "done",
"publicUrl": "https://pub-...r2.dev/screenshots/<id>.pdf",
"thumbnailUrl": "https://pub-...r2.dev/screenshots/<id>.thumb.png",
"pageTitle": "Example Domain",
"tags": ["other"],
"width": 1280,
"height": 1024,
"createdAt": "2026-05-28T03:42:00.000Z",
"completedAt": "2026-05-28T03:42:09.211Z"
}Stream completion (SSE)
For UIs that want a live spinner without polling:
const es = new EventSource(
`https://api.deepsyte.com/v1/screenshot/${id}/stream`,
);
es.addEventListener("status", (event) => {
const { status } = JSON.parse(event.data);
// "pending" → "processing" → "done" | "failed"
});
es.addEventListener("done", (event) => {
const { publicUrl } = JSON.parse(event.data);
es.close();
});The stream sends : ping heartbeats every 15 seconds and times out after
5 minutes with a timeout event.
Share a PDF
POST /api/screenshots/<id>/share # mint
DELETE /api/screenshots/<id>/share # revokeSee Sharing for the full response shape.
List your PDFs
GET /v1/screenshots?limit=50&before=<iso>
Authorization: Bearer <key>Cursor-paginated. nextCursor is null on the last page.
Download with attachment headers
The dashboard's Download button hits the apex Next.js route
/api/pdf/download/<id> which proxies R2 and adds
Content-Disposition: attachment so browsers save instead of opening inline.
Use it client-side instead of linking to the raw R2 URL.
