Media processing API for
images, video, and documents

The high-performance infrastructure for your next-gen media pipeline. One API key, four endpoints, zero maintenance.

https://api.lattice.darkvision.dev/v1/process/image
# Response 200 OK { "status": "success", "processed_url": "https://cdn.lattice.dev/outputs/res_abc123.webp", "metrics": { "optimization": "84.2%", "duration_ms": 142 } }

10-Step Processing Pipeline

Every image passes through a canonical pipeline. Enable only the steps you need - skip the rest.

Rotate / Flip
Auto-Trim
Crop
Resize
Focus Crop
Grayscale
Blur
Sharpen
Watermark
Encode

Output Formats

WebP JPEG PNG AVIF

Extras

EXIF preservation   Thumbnail presets (S/M/L/Custom)
# Resize to 800px wide, convert to WebP, add watermark curl -X POST https://lattice.darkvision.dev/v1/process/image \ -H "X-API-Key: sk_live_your_key_here" \ -F "file=@photo.jpg" \ -F 'options={ "resize": { "width": 800 }, "format": "webp", "quality": 85, "watermark": { "text": "(c) Acme Inc", "position": "BottomRight", "opacity": 0.4 } }'

Full Video Transcoding

Transcode, trim, extract thumbnails, and convert to GIF - all from one endpoint.

# Transcode to MP4 H.264 at 720p, trim first 30 seconds curl -X POST https://lattice.darkvision.dev/v1/process/video \ -H "X-API-Key: sk_live_your_key_here" \ -F "file=@input.mov" \ -F 'options={ "format": "mp4_h264", "resolution": "720p", "trim": { "start": 0, "end": 30 }, "strip_audio": false, "quality": 75 }'
Trim Video
Thumbnails
GIF Export
Strip Audio
Quality Ctrl
Fast Start

Output Formats

WebM (VP9) MP4 H.264 MP4 H.265 MP4 AV1 Signage 1080p Signage 1440p

Resolution Scaling

480p 720p 1080p

PDF Compression

Reduce PDF file sizes with Ghostscript-powered compression. Choose from four quality presets to balance size and fidelity.

90% Size Reduction
PDF 1.4 Compatible
Engine: Ghostscript
Vector Preservation

Quality Presets

Screen (~72 dpi) Ebook (~150 dpi) Printer (~300 dpi) Prepress (max)
# Compress a PDF with screen quality (smallest size) curl -X POST https://lattice.darkvision.dev/v1/process/pdf \ -H "X-API-Key: sk_live_your_key_here" \ -F "file=@document.pdf" \ -F 'options={ "quality": "screen" }'

HTML to PDF, DOCX & Image

Convert HTML pages or URLs into PDF documents, DOCX files, or screenshot images. Powered by wkhtmltopdf and pandoc.

URL or HTML String
Custom Margins
Viewport Scaling
Fast Render

Output Formats

PDF DOCX PNG (Screenshot)

Page Sizes

A4 Letter Legal A3
# Convert HTML to PDF with letter page size curl -X POST https://lattice.darkvision.dev/v1/convert/html \ -H "X-API-Key: sk_live_your_key_here" \ -F 'html=<h1>Invoice #1234</h1><p>Total: $99.00</p>' \ -F 'options={ "format": "pdf", "page_size": "letter", "margin_mm": 15 }'

Code Examples

Copy-paste examples for each endpoint.

# Resize + WebP + EXIF strip curl -X POST https://lattice.darkvision.dev/v1/process/image \ -H "X-API-Key: sk_live_your_key_here" \ -F "file=@hero-banner.jpg" \ -F 'options={ "resize": { "width": 1200, "height": 630 }, "format": "webp", "quality": 80, "strip_metadata": true }'
// Node.js (using standard fetch) const formData = new FormData(); formData.append('file', fileInput.files[0]); formData.append('options', JSON.stringify({ resize: { width: 1200, height: 630 }, format: 'webp', quality: 80, strip_metadata: true })); const res = await fetch('https://lattice.darkvision.dev/v1/process/image', { method: 'POST', headers: { 'X-API-Key': 'sk_live_your_key_here' }, body: formData });
# Python (requests) files = { 'file': open('hero-banner.jpg', 'rb'), 'options': (None, '{"resize": {"width": 1200, "height": 630}, "format": "webp", "quality": 80, "strip_metadata": true}') } requests.post( 'https://lattice.darkvision.dev/v1/process/image', headers={'X-API-Key': 'sk_live_your_key_here'}, files=files )
# Response { "url": "https://s3.../processed/abc123.webp", "format": "webp", "size_bytes": 47200 }
# MP4 H.264 at 1080p with quality control curl -X POST https://lattice.darkvision.dev/v1/process/video \ -H "X-API-Key: sk_live_your_key_here" \ -F "file=@raw-footage.mov" \ -F 'options={ "format": "mp4_h264", "resolution": "1080p", "quality": 80, "strip_audio": false }'
// Node.js formData.append('options', JSON.stringify({ format: 'mp4_h264', resolution: '1080p', quality: 80, strip_audio: false })); // ... fetch ...
# Python files = { 'file': open('raw-footage.mov', 'rb'), 'options': (None, '{"format": "mp4_h264", "resolution": "1080p", "quality": 80}') } requests.post(url, headers={'X-API-Key': 'sk_live_your_key_here'}, files=files)
# Response { "url": "https://s3.../processed/def456.mp4", "format": "mp4_h264", "size_bytes": 8340000 }
# Watermark + focus crop for social media curl -X POST https://lattice.darkvision.dev/v1/process/image \ -H "X-API-Key: sk_live_your_key_here" \ -F "file=@product-shot.png" \ -F 'options={ "focus_crop": { "aspect_w": 1, "aspect_h": 1, "focal_x": 0.5, "focal_y": 0.3 }, "watermark": { "text": "PREVIEW", "position": "Center", "opacity": 0.3 }, "format": "jpeg", "quality": 90 }'
// Node.js formData.append('options', JSON.stringify({ focus_crop: { aspect_w: 1, aspect_h: 1, focal_x: 0.5, focal_y: 0.3 }, watermark: { text: "PREVIEW", position: "Center", opacity: 0.3 }, format: "jpeg" }));
# Python opts = { "focus_crop": {"aspect_w": 1, "aspect_h": 1, "focal_x": 0.5, "focal_y": 0.3}, "watermark": {"text": "PREVIEW", "position": "Center", "opacity": 0.3}, "format": "jpeg" }
# Compress a PDF for web delivery curl -X POST https://lattice.darkvision.dev/v1/process/pdf \ -H "X-API-Key: sk_live_your_key_here" \ -F "file=@report.pdf" \ -F 'options={ "quality": "screen" }'
// Node.js formData.append('options', JSON.stringify({ quality: 'screen' }));
# Python files = {'file': open('report.pdf', 'rb'), 'options': (None, '{"quality": "screen"}')}
# Response { "url": "https://s3.../processed/ghi789.pdf", "key": "ghi789_report.pdf" }
# Convert a URL to PDF curl -X POST https://lattice.darkvision.dev/v1/convert/html \ -H "X-API-Key: sk_live_your_key_here" \ -F 'url=https://example.com' \ -F 'options={ "format": "pdf", "page_size": "a4", "margin_mm": 10 }'
// Node.js formData.append('url', 'https://example.com'); formData.append('options', JSON.stringify({ format: 'pdf', page_size: 'a4' }));
# Python data = {'url': 'https://example.com', 'options': '{"format": "pdf"}'} requests.post(url, data=data, headers={'X-API-Key': 'sk_live_your_key_here'})
# Response { "url": "https://s3.../processed/abc123.pdf", "key": "abc123_html_output.pdf" }

Who it's for

E-commerce
Dynamic Product Images

Automatically generate square thumbnails, strip metadata for speed, and add branded watermarks to your entire catalog in one request.

SaaS Platforms
User-Generated Video

Normalize diverse video uploads into standard H.264 MP4s, extract first-frame thumbnails, and generate animated GIF previews.

FinTech
PDF & Document Ops

Convert HTML invoices directly to PDFs, compress bulky documents for web delivery, and maintain per-customer storage isolation.

Developer Tools

Keys, docs, billing, and file management from the dashboard.

API Key Management

Multiple keys per account. Scoped permissions, environment labels, IP allowlisting, and instant rotation.

Interactive API Docs

Modern OpenAPI reference served through Scalar at /docs. Try requests live, explore schemas, and copy snippets.

Rate Limiting

Per-tier rate limits with clear 429 responses. Upgrade tiers to unlock higher throughput.

Presigned URLs

Every processed file returns a time-limited presigned URL (1-hour expiry). No auth needed to download.

Stripe Billing

Automated subscriptions, invoices, and webhook-driven status updates. Upgrade or cancel anytime.

S3 File Management

Browse, download, and delete processed files from the dashboard. Included storage acts as a buffer for processed output - not long-term hosting.

External Delivery

Auto-deliver processed files to your own S3 bucket or SFTP server. Configure destinations in the dashboard - delivery happens in the background.

Webhooks

Get real-time HMAC-signed webhook notifications for file processing, payments, and account events. Automatic retries with exponential backoff.

Architecture

Request lifecycle and processing model.

Request Lifecycle
// 1. Ingress Request -> Auth Middleware -> Rate Limiter -> // 2. Processing Semaphore Permit -> Spawn Isolated Task -> |-- Image: Optimized Image Engine |-- Video: Media Transcoding Engine |-- PDF: Document Processing Engine // 3. Egress Stream Output -> Cloud Storage Upload -> Presign URL |-- Delivery: S3 / SFTP (async)
Streaming I/O

Files stream from upload through processing to S3 without buffering the full file in memory.

Concurrency Control

A semaphore limits concurrent processing tasks. When all slots are busy, you get a 503 with a retry header.

Process Isolation

ffmpeg, Ghostscript, and wkhtmltopdf run as child processes with timeouts. A crash in one job doesn't affect others.

Security

Every account gets the same security stack. No tiered security.

Per-Account S3 Isolation

Files are stored in isolated prefixes. No cross-account access.

HMAC-Signed Sessions

Session cookies are signed and verified on every request.

CSRF Protection

All state-changing portal actions require a valid CSRF token.

Bcrypt Password Hashing

Passwords are hashed with bcrypt. We never store plaintext.

TLS Everywhere

All traffic encrypted in transit. No exceptions.

Concurrency Control

Processing semaphore prevents overload. 503 when at capacity.

Rust + Axum, async processing, S3 storage

Frequently Asked Questions

All files are stored in isolated storage buckets with per-account prefixes. We use industry-standard encryption for all transfers and never inspect or train on your data.

By default, the URLs returned by the API are valid for 1 hour. You can always generate a new one via the dashboard or API if you need extended access.

Yes, you can manage your subscription through the billing portal. Changes take effect at the end of your current billing cycle, and we never have long-term lock-ins.

We aim for 99.9% uptime for Pro users and 99.99% for Enterprise. Real-time system status is always available at our public health endpoint.

Yes. Configure one or more delivery destinations in your dashboard under Settings -> Delivery. Every time a file is processed, it's automatically uploaded to your S3 bucket or SFTP server in the background. Credentials are encrypted at rest with AES-256-GCM and never stored in plaintext.

Early access

Lattice is in active development. We're looking for early adopters.

Direct Support

Get direct access to the engineering team for custom implementation help.

Custom Logic

Need a specific processing step? Tell us and we'll prioritize it on the roadmap.

Get in touch

Feature requests, integration help, or custom requirements.

Send an email

Usually responds in < 24h