Turn any URL into a PNG screenshot. Simple, authenticated, usage-tracked API built with Next.js + Vercel + Supabase.
One endpoint.
API key authentication.
Built-in usage limits & audit log.
Deployed on Vercel.
Keys are provisioned manually in Supabase for v1 (see docs/DATABASE.md).
curl -H "x-api-key: sk_live_your_key_here" \
"https://your-domain.vercel.app/api/v1/screenshot?url=https://example.com" \
--output screenshot.pngThe response is a raw PNG image.
- Simple REST API:
GET /api/v1/screenshot?url=... - API key via
x-api-keyheader - Automatic usage counting and hard limits per key
- Full audit log of every request
- Runs on Vercel serverless (with proper Chromium setup)
- Clean landing page with copy-paste examples
| Document | Purpose |
|---|---|
| docs/PLAN.md | Architecture, decisions, implementation plan |
| docs/DATABASE.md | Supabase schema + setup instructions |
| docs/API_REFERENCE.md | Public API contract, examples, errors |
| docs/DEPLOYMENT.md | How to deploy on Vercel |
Start with the Plan document if you want to understand how everything fits together.
npm install
npm run devCreate .env.local (see .env.example after it's added) with your Supabase credentials.
Then visit http://localhost:3000 for the landing page.
The API will be available at: http://localhost:3000/api/v1/screenshot?url=https://example.com
screenshot-api/
├── app/
│ ├── api/v1/screenshot/route.ts # The public endpoint
│ ├── layout.tsx
│ └── page.tsx # Landing / documentation page
├── lib/
│ ├── supabase.ts # Supabase service-role client
│ └── capture.ts # Screenshot generation (puppeteer)
├── middleware.ts # Auth + quota enforcement for all /api routes
├── supabase/
│ └── schema.sql # Exact tables to create
├── docs/ # All detailed documentation
│ ├── PLAN.md
│ ├── DATABASE.md
│ ├── API_REFERENCE.md
│ └── DEPLOYMENT.md
└── ...
See docs/PLAN.md for the full intended layout.
- Every request to
/api/*hitsmiddleware.ts - Middleware validates the
x-api-key, checks remaining quota, increments usage, and writes an audit log - On success the request proceeds to the route handler
- The handler validates the
urlparameter and calls the capture logic - A headless browser renders the page and returns a PNG buffer
- The buffer is streamed back to the client as
image/png
Full details and trade-offs are in the plan document.
- Framework: Next.js 16 (App Router) + TypeScript
- Styling: Tailwind CSS
- Database & Auth: Supabase (PostgreSQL)
- Hosting: Vercel
- Screenshot engine:
puppeteer-core+@sparticuz/chromium
Current status: Scaffold complete. Documentation written. No production implementation code yet.
Next milestone: Implement following the documents in /docs.
See docs/PLAN.md for the exact recommended implementation order.
Private / internal for now.
This is currently a solo / small-team product. Documentation PRs and issues are welcome once the core is implemented.
Questions? Check the docs folder first — almost everything is documented there.