Files
SnapOtter/apps/docs/api/rest.md
T
SnapOtterandGitHub 1f8a42e548 fix: enforce role authority for user management (#616)
Centralize role-authority enforcement across user management, role management, configuration import, SCIM, GDPR, and MFA mutations. Add regression coverage for delegated custom roles and protect higher-privilege accounts from reset, deletion, or takeover.
2026-07-22 01:23:15 +08:00

45 KiB
Raw Blame History

description
description
Complete REST API reference. Tool endpoints, batch processing, pipelines, file library, authentication, teams, and admin operations.

REST API Reference

Interactive API docs with request/response examples are available at http://localhost:1349/api/docs.

Machine-readable specs:

  • /api/v1/openapi.yaml - OpenAPI 3.1 spec
  • /llms.txt - LLM-friendly summary
  • /llms-full.txt - Complete LLM-friendly docs

Authentication

All endpoints require authentication unless AUTH_ENABLED=false.

Session Token

# Login
curl -X POST http://localhost:1349/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin"}'
# Returns: {"token":"<session-token>"}

# Use token
curl http://localhost:1349/api/v1/tools/image/resize \
  -H "Authorization: Bearer <session-token>"

Sessions expire after 7 days (configurable via SESSION_DURATION_HOURS).

API Keys

# Create a key (returns key once - store it)
curl -X POST http://localhost:1349/api/v1/api-keys \
  -H "Authorization: Bearer <session-token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"my-script"}'
# Returns: {"key":"si_<96 hex chars>","id":"...","name":"my-script"}

# Use the key
curl http://localhost:1349/api/v1/tools/image/resize \
  -H "Authorization: Bearer si_<your-key>"

Keys are prefixed si_ and stored as scrypt hashes - the raw key is shown once and never retrievable again.

Auth Endpoints

Method Path Access Description
POST /api/auth/login Public Login, get session token
POST /api/auth/logout Auth Destroy current session
GET /api/auth/session Auth Validate current session
POST /api/auth/change-password Auth Change own password (invalidates all other sessions + API keys)
GET /api/auth/users Admin List all users
POST /api/auth/register Admin (users:manage; proposed-role authority) Create a new user
PUT /api/auth/users/:id Admin (users:manage; target authority) Update user role or team
POST /api/auth/users/:id/reset-password Admin (users:manage; target authority) Reset user's password
DELETE /api/auth/users/:id Admin (users:manage; target authority) Delete a user
GET /api/v1/config/auth Public Check if authentication is enabled ({ authEnabled: bool })
POST /api/auth/mfa/enroll Auth Start TOTP MFA enrollment. Requires the enterprise mfa feature
POST /api/auth/mfa/verify Auth Confirm MFA enrollment with a TOTP code
POST /api/auth/mfa/complete Public Complete a pending MFA login challenge
POST /api/auth/mfa/disable Auth Disable MFA for the current user
POST /api/auth/users/:id/mfa/reset Admin (users:manage; target authority) Reset MFA for a user
GET /api/auth/oidc/login Public Start OIDC login when OIDC is enabled
GET /api/auth/oidc/callback Public OIDC authorization callback
GET /api/auth/saml/metadata Public SAML SP metadata XML when SAML is enabled
GET /api/auth/saml/login Public Start SAML login
POST /api/auth/saml/callback Public SAML assertion consumer service

When MFA is enabled for a user, POST /api/auth/login returns {"requiresMfa":true,"mfaToken":"...","mfaRequired":true|false} instead of a session token. Send that mfaToken plus a TOTP or recovery code to /api/auth/mfa/complete.

Permissions

Permission Admin User
Use tools
Own files/pipelines/API keys
See all users' files/pipelines/keys -
Write settings -
Manage users & teams -
Manage branding -

Health Check

Method Path Access Description
GET /api/v1/health Public Basic health check. Returns {"status":"healthy","version":"..."} with 200, or {"status":"unhealthy"} with 503 if the database is unreachable.
GET /api/v1/readyz Public Readiness probe. Checks PostgreSQL, Redis, disk space, and S3 when configured. Returns 503 when the instance should not receive traffic.
GET /api/v1/admin/health Admin (system:health) Detailed diagnostics including uptime, storage mode, database status, queue state, and GPU availability.

Using Tools

Every tool follows the same pattern:

# Single file
curl -X POST http://localhost:1349/api/v1/tools/<section>/<toolId> \
  -H "Authorization: Bearer <token>" \
  -F "file=@input.jpg" \
  -F 'settings={"width":800,"height":600}'

# Batch (returns ZIP)
curl -X POST http://localhost:1349/api/v1/tools/<section>/<toolId>/batch \
  -H "Authorization: Bearer <token>" \
  -F "files=@a.jpg" \
  -F "files=@b.jpg" \
  -F 'settings={...}'

<section> is one of image, video, audio, pdf, or files.

  • Upload is multipart/form-data.
  • settings is a JSON string with tool-specific options.
  • clientJobId is an optional form field for caller-supplied progress correlation.
  • fileId is an optional form field referencing an existing file library item. When present, the processed output is saved as a new version and the response includes savedFileId.
  • Fast tools usually return 200 JSON: {"jobId":"...","downloadUrl":"/api/v1/download/<jobId>/<filename>","originalSize":1234,"processedSize":567}. Fetch the processed file from downloadUrl.
  • Any queued tool can return 202 JSON if it is long-running or exceeds the synchronous wait window: {"jobId":"...","async":true}. Connect to SSE for progress, then download when complete (see Progress Tracking).
  • Batch routes return a ZIP archive streamed directly (with X-Job-Id header) for tools registered in the generic batch registry.

Tools Reference

Conversion Presets

The shared catalog includes 83 dedicated conversion preset endpoints such as jpg-to-png, mov-to-mp4, m4a-to-mp3, pdf-to-jpg, and excel-to-csv. Presets are first-class tool routes:

POST /api/v1/tools/<section>/<presetId>

Each preset locks the output format and delegates to a base tool such as convert, convert-video, extract-audio, convert-audio, image-to-pdf, pdf-to-image, svg-to-raster, or convert-spreadsheet. See Conversion Presets for the complete route table and optional settings.

Essentials

Tool ID Name Key settings
resize Resize width, height, fit (cover/contain/fill/inside/outside), percentage, withoutEnlargement, plus 23 social media presets
crop Crop left, top, width, height, unit (px/percent)
rotate Rotate & Flip angle, horizontal (bool), vertical (bool)
convert Convert format (jpg/png/webp/avif/tiff/gif/heic/heif), quality
compress Compress mode (quality/targetSize), quality (1100), targetSizeKb

Optimization

Tool ID Name Key settings
optimize-for-web Optimize for Web format (webp/jpeg/avif/png), quality, maxWidth, maxHeight, progressive, stripMetadata
strip-metadata Strip Metadata -
edit-metadata Edit Metadata title, description, author, copyright, keywords, gps (lat/lon), dateTime
bulk-rename Bulk Rename pattern (supports {n}, {date}, {original}), startIndex, padding
image-to-pdf Image to PDF pageSize (A4/Letter/...), orientation, margin, targetSize ({value, unit})
favicon Favicon Generator padding, backgroundColor, borderRadius - generates all standard sizes

Adjustments

Tool ID Name Key settings
adjust-colors Adjust Colors brightness, contrast, exposure, saturation, temperature, tint, hue, sharpness, red, green, blue, effect (none/grayscale/sepia/invert)
sharpening Sharpening method (adaptive/unsharp-mask/high-pass), sigma, m1, m2, x1, y2, y3, amount, radius, threshold, strength, kernelSize (3/5), denoise (off/light/medium/strong)
replace-color Replace Color sourceColor, targetColor (replacement), makeTransparent, tolerance
color-blindness Color Blindness Simulation simulationType (protanopia/deuteranopia/tritanopia/protanomaly/deuteranomaly/tritanomaly/achromatopsia/blueConeMonochromacy, default "deuteranomaly")
duotone Duotone shadow (hex), highlight (hex), intensity (0-100)
pixelate Pixelate blockSize (2-128), region ({left, top, width, height} for partial pixelation)
vignette Vignette strength (0.1-1), color (hex), radius, softness, roundness, centerX, centerY

AI Tools

All AI tools run on your hardware: CPU by default, or NVIDIA CUDA when a supported NVIDIA GPU is available. Intel/AMD iGPU acceleration through VA-API, Quick Sync, or OpenCL is not supported for AI inference today. No internet required.

Tool ID Name AI Model Key settings
remove-background Remove Background rembg (BiRefNet / U2-Net) model, backgroundType (transparent/color/gradient/blur/image), backgroundColor, gradientColor1, gradientColor2, gradientAngle, blurEnabled, blurIntensity, shadowEnabled, shadowOpacity
upscale Image Upscaling RealESRGAN scale (2/4), model, faceEnhance, denoise, format, quality
erase-object Object Eraser LaMa (ONNX) Mask sent as second file part (fieldname mask), format, quality
ocr OCR / Text Extraction Tesseract (fast); RapidOCR + PP-OCR ONNX (balanced/best) quality (fast/balanced/best), language, enhance
blur-faces Face / PII Blur MediaPipe blurRadius, sensitivity
smart-crop Smart Crop MediaPipe + Sharp mode (subject/face/trim), strategy (attention/entropy), width, height, padding, facePreset (closeup/head-shoulders/upper-body/half-body), sensitivity, threshold, padToSquare, padColor, targetSize, quality
image-enhancement Image Enhancement Analysis-based mode (auto/exposure/contrast/color/sharpness), strength
enhance-faces Face Enhancement GFPGAN / CodeFormer model (gfpgan/codeformer), strength, sensitivity, centerFace
colorize AI Colorization DDColor intensity, model
noise-removal Noise Removal Tiered denoising tier (quick/balanced/quality/maximum), strength, detailPreservation, colorNoise, format, quality
red-eye-removal Red Eye Removal Face landmark + color analysis sensitivity, strength
restore-photo Photo Restoration Multi-step pipeline mode (auto/light/heavy), scratchRemoval, faceEnhancement, fidelity, denoise, denoiseStrength, colorize
passport-photo Passport Photo MediaPipe landmarks Two-phase flow. Analyze uses multipart file; generate uses JSON with countryCode, bgColor, printLayout (none/4x6/a4), landmarks, image dimensions
content-aware-resize Content-Aware Resize Seam carving (caire) width, height, protectFaces, blurRadius, sobelThreshold, square
transparency-fixer PNG Transparency Fixer BiRefNet HR-matting defringe (0-100), outputFormat (png/webp)
background-replace Background Replace rembg (BiRefNet) backgroundType (color/gradient), color (hex), gradientColor1, gradientColor2, gradientAngle, feather (0-20), format (png/webp)
blur-background Blur Background rembg (BiRefNet) intensity (1-100), feather (0-20), format (png/webp)
ai-canvas-expand AI Canvas Expand LaMa (outpainting) extendTop, extendRight, extendBottom, extendLeft (px), tier (fast/balanced/high), format, quality

Watermark & Overlay

Tool ID Name Key settings
watermark-text Text Watermark text, font, fontSize, color, opacity, position, rotation, tile
watermark-image Image Watermark opacity, position, scale - second file is the watermark
text-overlay Text Overlay text, font, fontSize, color, x, y, background, padding, borderRadius
compose Image Composition x, y, opacity, blend - second file is layered on top
meme-generator Meme Generator templateId, textLayout (top-bottom/top-only/bottom-only/center/side-by-side), textBoxes ([{id, text}]), fontFamily (anton/arial-black/comic-sans/montserrat/bebas-neue/permanent-marker/roboto), fontSize, textColor, strokeColor, textAlign, allCaps. Supports template mode (JSON body with templateId) or custom image mode (multipart with file).

Utilities

Tool ID Name Key settings
info Image Info - (returns width, height, format, size, channels, hasAlpha, DPI, EXIF)
compare Image Compare mode (side-by-side/overlay/diff), diffThreshold - second file is the comparison target
find-duplicates Find Duplicates threshold (perceptual hash distance, default 8) - multi-file
color-palette Color Palette count (dominant color count), format (hex/rgb)
qr-generate QR Code Generator data, size, margin, colorDark, colorLight, errorCorrectionLevel, dotStyle, cornerStyle, logo (optional file)
barcode-read Barcode Reader - (auto-detects QR, EAN, Code128, DataMatrix, etc.)
image-to-base64 Image to Base64 format (data-uri/plain), mimeType
html-to-image HTML to Image url, format (png/jpg/webp), quality, fullPage, devicePreset (desktop/tablet/mobile/custom), viewportWidth, viewportHeight
histogram Histogram scale (linear/log) - returns RGB histogram chart + per-channel stats
lqip-placeholder LQIP Placeholder width (4-64), blur, strategy (blur/pixelate/solid), format (webp/png/jpeg), quality
barcode-generate Barcode Generator text, type (code128/ean13/upca/code39/itf14/datamatrix), scale (1-8), includeText (bool). JSON body, no file upload.

Layout & Composition

Tool ID Name Key settings
collage Collage / Grid template (25+ layouts), gap, backgroundColor, borderRadius - multi-file
stitch Stitch / Combine direction (horizontal/vertical/grid), gap, backgroundColor, alignment - multi-file
split Image Splitting mode (grid/rows/cols), rows, cols, tileWidth, tileHeight
border Border & Frame width, color, style (solid/gradient/pattern), borderRadius, padding, shadow
beautify Beautify Screenshot backgroundType (solid/linear-gradient/radial-gradient/image/transparent), gradientStops, padding, borderRadius, shadowPreset, frame (none/macos-light/macos-dark/windows-light/windows-dark/browser-light/browser-dark/iphone/macbook/ipad/...), socialPreset (none/twitter/linkedin/instagram-square/instagram-story/facebook/producthunt), watermarkText, outputFormat
circle-crop Circle Crop zoom (1-5), offsetX, offsetY, borderWidth, borderColor, background (transparent/hex), outputSize
image-pad Image Pad target (16:9/9:16/1:1/4:3/3:4/custom), ratioW, ratioH, background (color/transparent/blur), color (hex), padding (0-50%)
sprite-sheet Sprite Sheet columns (1-16), padding, background (hex), format (png/webp/jpeg), quality - multi-file (2-64 images)

Format & Conversion

Tool ID Name Key settings
svg-to-raster SVG to Raster format (png/jpeg/webp/avif/tiff/gif/heif), width, height, scale, dpi, background
vectorize Image to SVG colorMode (bw/color), threshold, colorPrecision, filterSpeckle, pathMode (none/polygon/spline)
gif-tools GIF Tools action (resize/optimize/reverse/speed/extract-frames/rotate/add-text), action-specific params
gif-webp GIF/WebP Converter quality (1-100), lossless (bool), resizePercent (10-100)

Video Tools

Tool ID Name Key settings
convert-video Convert Video format (mp4/mov/webm/avi/mkv), quality (high/balanced/small)
compress-video Compress Video quality (light/balanced/strong), resolution (original/1080p/720p/480p)
trim-video Trim Video startS, endS, precise (bool, frame-accurate cut)
mute-video Mute Video -
video-to-gif Video to GIF fps (1-30), width, startS, durationS (max 60s)
resize-video Resize Video width, height, preset (custom/2160p/1440p/1080p/720p/480p/360p)
crop-video Crop Video width, height, x, y
rotate-video Rotate Video transform (cw90/ccw90/180/hflip/vflip)
change-fps Change FPS fps (1-120)
video-color Video Color brightness, contrast, saturation, gamma
video-speed Video Speed factor (0.25-4), keepPitch (bool)
reverse-video Reverse Video - (max 5 minutes)
video-loudnorm Normalize Audio - (EBU R128)
aspect-pad Aspect Pad target (16:9/9:16/1:1/4:3/3:4), color (hex)
blur-pad Blur Pad target (16:9/9:16/1:1/4:3/3:4), blur (2-50)
watermark-video Watermark Video text, position, fontSize, opacity, color
stabilize-video Stabilize Video smoothing (5-60, in frames)
gif-to-video GIF to Video format (mp4/webm/mov)
video-to-webp Video to WebP fps, width, quality, loop (bool)
video-to-frames Video to Frames mode (all/nth/timestamps), n, timestamps, format (png/jpg)
merge-videos Merge Videos - (multi-file, normalized to first video's resolution)
replace-audio Replace Audio - (video + audio file, two files)
burn-subtitles Burn Subtitles fontSize (8-72) - video + subtitle file
embed-subtitles Embed Subtitles language (ISO 639-2/B code) - video + subtitle file
extract-subtitles Extract Subtitles - (outputs SRT)
images-to-video Images to Video secondsPerImage (0.5-10), resolution (1080p/720p/square), fps - multi-file
video-metadata Clean Video Metadata -
auto-subtitles Auto Subtitles (AI) language (auto/en/de/fr/es/zh/ja/ko/id/th/vi), format (srt/vtt)
extract-audio Extract Audio format (mp3/wav/m4a/ogg)

Audio Tools

Tool ID Name Key settings
convert-audio Convert Audio format (mp3/wav/ogg/flac/m4a), bitrateKbps (32-320)
trim-audio Trim Audio startS, endS
volume-adjust Volume Adjust gainDb (-30 to 30)
normalize-audio Normalize Audio - (EBU R128, -16 LUFS)
fade-audio Fade Audio fadeInS (0-30), fadeOutS (0-30)
reverse-audio Reverse Audio -
audio-speed Audio Speed factor (0.25-4)
pitch-shift Pitch Shift semitones (-12 to 12)
audio-channels Audio Channels mode (stereo-to-mono/mono-to-stereo/swap)
silence-removal Silence Removal thresholdDb (-80 to -20), minSilenceS (0.1-5)
noise-reduction Noise Reduction strength (light/medium/strong)
merge-audio Merge Audio format (mp3/wav/flac/m4a) - multi-file
split-audio Split Audio mode (time/parts/silence), segmentS, parts, thresholdDb, minSilenceS
ringtone-maker Ringtone Maker startS, durationS (1-30)
waveform-image Waveform Image width, height, color (hex)
audio-metadata Audio Metadata strip (bool), title, artist, album
transcribe-audio Transcribe Audio (AI) language (auto/en/de/fr/es/zh/ja/ko/id/th/vi), outputFormat (txt/srt/vtt)

Document Tools

Tool ID Name Key settings
merge-pdf Merge PDFs - (multi-file, up to 20 PDFs)
split-pdf Split PDF mode (range/every), range, everyN (1-500)
compress-pdf Compress PDF mode (quality/targetSize), quality (1-100), targetSizeKb
rotate-pdf Rotate PDF angle (90/180/270), range (page range)
extract-pages Extract Pages range (qpdf syntax, e.g. "1-5,8,10-z")
remove-pages Remove Pages pages (qpdf range to remove)
organize-pdf Organize PDF order (qpdf page order, e.g. "3,1,2,5-z")
protect-pdf Protect PDF userPassword, ownerPassword (AES-256)
unlock-pdf Unlock PDF password
repair-pdf Repair PDF -
linearize-pdf Web-Optimize PDF - (linearize for fast web viewing)
grayscale-pdf Grayscale PDF -
pdfa-convert PDF/A Convert - (archival PDF/A-2)
crop-pdf Crop PDF margin (0-2000 points)
nup-pdf N-up PDF perSheet (2/3/4/8/9/12/16)
booklet-pdf Booklet PDF perSheet (2/4/6/8)
watermark-pdf Watermark PDF text, position, fontSize, opacity, rotation
pdf-page-numbers PDF Page Numbers position (bl/bc/br/tl/tc/tr), fontSize
flatten-pdf Flatten PDF - (bakes forms and annotations)
redact-pdf Redact PDF terms (string[]), caseSensitive (bool)
sign-pdf Sign PDF Custom multipart route with PDF file, signature files sig0, sig1, and placements JSON array
pdf-to-text PDF to Text -
pdf-to-word PDF to Word -
pdf-metadata PDF Metadata title, author, subject, keywords
convert-document Convert Document format (docx/odt/rtf/txt)
convert-presentation Convert Presentation format (pptx/odp)
convert-spreadsheet Convert Spreadsheet format (xlsx/ods/csv)
excel-to-pdf Excel to PDF -
word-to-pdf Word to PDF -
powerpoint-to-pdf PowerPoint to PDF -
html-to-pdf HTML to PDF - (remote resources disabled)
markdown-to-docx Markdown to Word -
markdown-to-html Markdown to HTML -
markdown-to-pdf Markdown to PDF - (remote resources disabled)
epub-convert Convert EPUB format (pdf/docx/html/md)
to-epub Convert to EPUB - (accepts .docx, .md, .html, .txt)
ocr-pdf PDF OCR (AI) quality (fast/balanced/best), language (auto/en/de/fr/es/zh/ja/ko), pages
pdf-to-image PDF to Image pages (all/range), format, dpi, quality
pdf-to-jpg PDF to JPG pages, dpi, quality, colorMode
pdf-to-png PDF to PNG pages, dpi, quality, colorMode
pdf-to-tiff PDF to TIFF pages, dpi, quality, colorMode

File Tools

Tool ID Name Key settings
chart-maker Chart Maker kind (bar/line/pie), title, width, height
csv-excel CSV to Excel sheet (worksheet number for XLSX input) - bidirectional
csv-json CSV to JSON pretty (bool) - bidirectional
json-xml JSON to XML pretty (bool) - bidirectional
split-csv Split CSV rowsPerFile (1-1000000), keepHeader (bool)
merge-csvs Merge CSVs - (multi-file, matching columns)
yaml-json YAML / JSON - (bidirectional)
xml-to-csv XML to CSV - (auto-finds repeating elements)
excel-to-csv Excel to CSV dedicated conversion preset backed by convert-spreadsheet
create-zip Create ZIP - (multi-file, 2-50 files)
extract-zip Extract ZIP - (bomb-protected)

HTML to Image

Capture a webpage as an image. Unlike other tools, this endpoint accepts application/json instead of multipart form data (no file upload needed).

Endpoint: POST /api/v1/tools/image/html-to-image

Content-Type: application/json

Parameter Type Default Description
url string (required) URL to capture (http/https only)
format string "png" Output format: jpg, png, webp
quality number 90 Quality 1-100 (JPG/WebP only)
fullPage boolean false Capture full scrollable page
devicePreset string "desktop" desktop, tablet, mobile, custom
viewportWidth number 1280 Custom viewport width 320-3840
viewportHeight number 720 Custom viewport height 320-2160

Example:

curl -X POST http://localhost:1349/api/v1/tools/image/html-to-image \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://snapotter.com", "format": "png", "devicePreset": "desktop"}'

Response:

{
  "jobId": "uuid",
  "downloadUrl": "/api/v1/download/{jobId}/screenshot.png",
  "originalSize": 0,
  "processedSize": 54321
}

Tool Sub-Routes

Some tools expose additional endpoints beyond the standard POST /api/v1/tools/<section>/<toolId>:

Method Path Description
GET /api/v1/tools/popular Return popular tool IDs, falling back to a curated default list when usage data is sparse
POST /api/v1/tools/image/remove-background/effects Apply background effects (color/gradient/blur/shadow) without re-running AI. Uses cached mask from initial removal.
POST /api/v1/tools/image/edit-metadata/inspect Read existing EXIF/IPTC/XMP metadata from an image
POST /api/v1/tools/image/strip-metadata/inspect Inspect metadata fields before stripping
POST /api/v1/tools/image/passport-photo/analyze Phase 1: AI face detection + background removal. Returns face landmarks and cached data.
POST /api/v1/tools/image/passport-photo/generate Phase 2: Crop, resize, and tile using cached analysis. No AI re-run.
POST /api/v1/tools/image/gif-tools/info Get GIF metadata (frame count, dimensions, duration)
POST /api/v1/tools/pdf/pdf-to-image/info Get PDF metadata (page count, dimensions)
POST /api/v1/tools/pdf/pdf-to-image/preview Generate a preview of a specific PDF page
POST /api/v1/tools/pdf/pdf-to-jpg/info Get PDF metadata for the dedicated JPG preset
POST /api/v1/tools/pdf/pdf-to-jpg/preview Generate a JPG preset PDF page preview
POST /api/v1/tools/pdf/pdf-to-png/info Get PDF metadata for the dedicated PNG preset
POST /api/v1/tools/pdf/pdf-to-png/preview Generate a PNG preset PDF page preview
POST /api/v1/tools/pdf/pdf-to-tiff/info Get PDF metadata for the dedicated TIFF preset
POST /api/v1/tools/pdf/pdf-to-tiff/preview Generate a TIFF preset PDF page preview
POST /api/v1/tools/image/svg-to-raster/batch Batch convert multiple SVGs to raster
POST /api/v1/tools/image/image-enhancement/analyze Analyze image quality and return enhancement recommendations
POST /api/v1/tools/image/optimize-for-web/preview Lightweight preview for live parameter tuning. Returns optimized image with size headers.

Batch Processing

Apply a generic batch-enabled tool to multiple files at once. Returns a ZIP archive. Custom multi-file or multi-step routes, such as PDF signing and PDF-to-image preset routes, use their own endpoint contract instead of the generic /batch route.

The ocr-pdf tool supports this generic /batch route.

curl -X POST http://localhost:1349/api/v1/tools/image/compress/batch \
  -H "Authorization: Bearer <token>" \
  -F "files=@a.jpg" \
  -F "files=@b.jpg" \
  -F "files=@c.jpg" \
  -F 'settings={"quality":80}'

Concurrency is controlled by CONCURRENT_JOBS (default: auto-detected from CPU cores). MAX_BATCH_SIZE limits the number of files per batch (default: 100; set 0 for unlimited).

Pipelines

Execute a pipeline

# Single file
curl -X POST http://localhost:1349/api/v1/pipeline/execute \
  -H "Authorization: Bearer <token>" \
  -F "file=@input.jpg" \
  -F 'pipeline={"steps":[
    {"toolId":"resize","settings":{"width":1200}},
    {"toolId":"compress","settings":{"quality":80}},
    {"toolId":"watermark-text","settings":{"text":"© 2025"}}
  ]}'

# Batch (multiple files → ZIP)
curl -X POST http://localhost:1349/api/v1/pipeline/batch \
  -H "Authorization: Bearer <token>" \
  -F "files=@a.jpg" \
  -F "files=@b.jpg" \
  -F 'pipeline={"steps":[{"toolId":"resize","settings":{"width":800}}]}'

Each step's output is the next step's input. Pipelines allow 20 steps by default, configurable via MAX_PIPELINE_STEPS. Set MAX_PIPELINE_STEPS=0 to remove the limit.

Save and manage pipelines

Method Path Description
POST /api/v1/pipeline/save Save a named pipeline (name, description, steps[])
GET /api/v1/pipeline/list List saved pipelines (admins see all; users see own)
DELETE /api/v1/pipeline/:id Delete (owner or admin)
GET /api/v1/pipeline/tools List tool IDs valid for pipeline steps

Progress Tracking

Long-running jobs, queued tools, batch jobs, and pipelines emit real-time progress via Server-Sent Events. The progress stream is public and keyed by job ID, so clients do not need to send an Authorization header to read it.

# Connect to the SSE stream (jobId is in the JSON response body from the tool endpoint)
curl -N http://localhost:1349/api/v1/jobs/<jobId>/progress

Event format:

data: {"jobId":"...","type":"single","phase":"processing","stage":"Upscaling","percent":42}
data: {"jobId":"...","type":"single","phase":"complete","percent":100,"result":{"downloadUrl":"/api/v1/download/..."}}
data: {"jobId":"...","type":"batch","status":"processing","completedFiles":2,"totalFiles":5,"failedFiles":0,"errors":[]}

You can request cancellation for a queued or running job with POST /api/v1/jobs/:jobId/cancel. The response is {"canceled":true|false}.

File Library

Persistent file storage with version history.

Method Path Description
POST /api/v1/upload Upload files to workspace (temp processing)
POST /api/v1/files/upload Upload files to the persistent file library
POST /api/v1/files/save-result Save a tool processing result as a new file version
GET /api/v1/files List saved files (paginated, with search)
GET /api/v1/files/:id Get file metadata + version chain
GET /api/v1/files/:id/download Download file
GET /api/v1/files/:id/thumbnail Get 300px JPEG thumbnail
DELETE /api/v1/files Bulk delete files and their version chains (body: { ids: [...] })
POST /api/v1/fetch-urls Fetch remote URLs into the workspace for URL-based imports
POST /api/v1/preview Generate a browser-compatible WebP preview (for HEIC/HEIF/RAW formats)
GET /api/v1/files/:id/preview Stream a cached or generated browser-compatible preview for a saved PDF, office document, video, or audio file
POST /api/v1/preview/generate Generate an on-demand MP4 or MP3 preview for an uploaded media file without saving it first
GET /api/v1/download/:jobId/:filename Download a processed file from a workspace

To auto-save a tool result to the library, include fileId as a multipart form field referencing an existing library file. The processed result will be saved as a new version.

API Key Management

Method Path Access Description
POST /api/v1/api-keys Auth Generate new key - shown once
GET /api/v1/api-keys Auth List keys (name, id, lastUsedAt - not raw key)
DELETE /api/v1/api-keys/:id Auth Delete key

Teams

Method Path Access Description
GET /api/v1/teams Admin (teams:manage) List teams
POST /api/v1/teams Admin (teams:manage) Create team
PUT /api/v1/teams/:id Admin (teams:manage) Rename team
DELETE /api/v1/teams/:id Admin (teams:manage) Delete team (cannot delete default team or teams with members)

Settings

Runtime key-value configuration (read by any authenticated user, write by admin only).

Method Path Description
GET /api/v1/settings Get all settings
PUT /api/v1/settings Bulk update settings (JSON body with key-value pairs)
GET /api/v1/settings/:key Get a specific setting by key

Known keys: disabledTools (JSON array of tool IDs), enableExperimentalTools (bool string), loginAttemptLimit (number).

Preferences

Per-user preferences are separate from instance settings. Any authenticated user can read and update their own preference map.

Method Path Description
GET /api/v1/preferences Get the current user's preferences as { "preferences": { ... } }
PUT /api/v1/preferences Upsert one or more preference keys for the current user

Roles

Custom role management with granular permissions.

Role creation and mutation are constrained by authority containment: the proposed or current role cannot outrank the actor, exceed the actor's effective permissions, or broaden the actor's tool scope. API-key scopes participate in this check. Deleting a custom role also requires authority to assign the built-in user fallback used for its members.

Method Path Access Description
GET /api/v1/roles Admin (audit:read) List all roles with user counts
POST /api/v1/roles Admin (security:manage) Create a custom role (name, description, permissions)
PUT /api/v1/roles/:id Admin (security:manage) Update a custom role (cannot modify built-in roles)
DELETE /api/v1/roles/:id Admin (security:manage) Delete a custom role (cannot delete built-in roles; affected users revert to user role)

Available permissions (17): tools:use, files:own, files:all, apikeys:own, apikeys:all, pipelines:own, pipelines:all, settings:read, settings:write, users:manage, teams:manage, features:manage, system:health, audit:read, compliance:manage, webhooks:manage, security:manage.

Audit Log

Admin-only endpoint for reviewing security-relevant actions.

Method Path Access Description
GET /api/v1/audit-log Admin (audit:read) Paginated audit log with optional filters

Query parameters:

Parameter Description
page Page number (default: 1)
limit Entries per page (default: 50, max: 100)
action Filter by action type (e.g. ROLE_CREATED, ROLE_DELETED)
ip Filter by source IP address
from Filter entries after this ISO 8601 date
to Filter entries before this ISO 8601 date

Analytics

Method Path Access Description
GET /api/v1/config/analytics Public Get the effective analytics configuration (PostHog key, Sentry DSN, sample rate). Keys, DSN, and instance ID are blank when analytics is off, either from the compile-time bake or the instance analyticsEnabled setting.
POST /api/v1/feedback Auth Submit explicit user feedback to the configured PostHog project as feedback_submitted. The route respects the analytics gate, rate-limits submissions, strips contact fields unless contactOk is true, and never accepts file contents, file names, upload paths, or raw private error text. When analytics is disabled, it returns { "ok": true, "accepted": false }.
PUT /api/v1/settings Admin (settings:write) Set the instance-wide opt-out. Send a JSON body { "analyticsEnabled": "false" } to turn analytics off for everyone, or "true" to turn it back on.

Features / AI Bundles

Manage AI feature bundles (install/uninstall AI model packages in the Docker environment). Prefer the tool-level install endpoint when enabling a tool from custom automation: some AI tools need more than one shared bundle, and this endpoint skips already-installed bundles while queuing only the missing ones.

OCR is an optional enhancement rather than a hard dependency. Its fast Tesseract tier works without a pack; POST /api/v1/admin/features/ocr/install installs the signed RapidOCR pack for balanced and best on Linux amd64 or arm64. The accurate OCR runtime uses CPU on CPU-only and NVIDIA hosts and requires at least 4 GiB of effective memory (the configured container cgroup limit, otherwise host memory). SnapOtter reports requiredMemoryBytes, effectiveMemoryBytes, and an insufficient-memory compatibility reason, and rejects an incompatible install before download. This memory requirement does not apply to fast. The pack is about 208-234 MiB to download and 409-488 MiB installed, depending on the target; the signed index binds the exact sizes enforced during installation.

Method Path Access Description
GET /api/v1/features Auth List all feature bundles and their install status
POST /api/v1/admin/features/:bundleId/install Admin (features:manage) Install a feature bundle (async, returns jobId for progress tracking)
POST /api/v1/admin/tools/:toolId/features/install Admin (features:manage) Install every bundle a tool requires; returns per-bundle queued/skipped status
POST /api/v1/admin/features/:bundleId/uninstall Admin (features:manage) Uninstall a feature bundle and clean up model files
GET /api/v1/admin/features/disk-usage Admin (features:manage) Get total disk usage of AI models
POST /api/v1/admin/features/import Admin (features:manage) Import a legacy AI bundle (file) or a signed offline OCR release (index plus archive)

An air-gapped OCR import must include the release's signed ocr-runtime-index.json and the matching platform archive. SnapOtter applies the same Ed25519 signature, artifact hash, compatibility, extraction, and smoke-test checks used by online installation:

curl -X POST http://localhost:1349/api/v1/admin/features/import \
  -H "Authorization: Bearer <admin-token>" \
  -F "index=@ocr-runtime-index.json" \
  -F "archive=@ocr-linux-amd64-cpu-py312.tar.gz"

Use the linux-arm64-cpu-py311 archive on arm64. A signed artifact for another target is rejected rather than installed.

Admin Operations

Operational endpoints for observability, support, usage reporting, and backup status.

Method Path Access Description
GET /api/v1/admin/log-level Admin (settings:write) Read the current runtime log level
POST /api/v1/admin/log-level Admin (settings:write) Change the runtime log level (fatal, error, warn, info, debug, trace, or silent)
GET /api/v1/metrics Admin (system:health) Prometheus metrics in text format
GET /api/v1/admin/support-bundle Admin (system:health) Download a redacted diagnostic support bundle ZIP
GET /api/v1/admin/usage Admin (audit:read) Usage dashboard data, with optional days query parameter
GET /api/v1/admin/backup-status Admin (system:health) Read last backup metadata and freshness status
POST /api/v1/admin/backup-status Admin (system:health) Record a completed backup (type, optional sizeBytes, optional notes)

Enterprise APIs

These routes are license-gated by their related enterprise feature. They still require the listed SnapOtter permission.

Full built-in admin means the authenticated actor has the admin role and the complete effective admin permission set. An API-key scope that omits any admin permission does not qualify.

Method Path Access Description
GET /api/v1/enterprise/audit/export Admin (audit:read) Export audit entries as JSON or CSV with filters
GET /api/v1/enterprise/config/export Admin (system:health) Export redacted instance config, custom roles, and teams
POST /api/v1/enterprise/config/import Full built-in admin Import config, with optional dry run
GET /api/v1/enterprise/ip-allowlist Admin (security:manage) Read configured CIDR allowlist
PUT /api/v1/enterprise/ip-allowlist Admin (security:manage) Update CIDR allowlist with self-lockout prevention
GET /api/v1/enterprise/legal-hold Admin (compliance:manage) List user and team legal holds
PUT /api/v1/enterprise/legal-hold Admin (compliance:manage) Apply or release a legal hold on a user or team
POST /api/v1/enterprise/scim/token Full built-in admin Generate a SCIM bearer token, returned once
DELETE /api/v1/enterprise/scim/token Full built-in admin Revoke the current SCIM bearer token
GET /api/v1/enterprise/siem/config Admin (webhooks:manage) Read SIEM forwarding config
PUT /api/v1/enterprise/siem/config Admin (webhooks:manage) Update SIEM forwarding config
GET /api/v1/enterprise/webhooks Admin (webhooks:manage) List webhook destinations
POST /api/v1/enterprise/webhooks Admin (webhooks:manage) Create a webhook destination
PUT /api/v1/enterprise/webhooks/:index Admin (webhooks:manage) Update a webhook destination
DELETE /api/v1/enterprise/webhooks/:index Admin (webhooks:manage) Delete a webhook destination
POST /api/v1/enterprise/webhooks/:index/test Admin (webhooks:manage) Send a test webhook payload
POST /api/v1/enterprise/users/:id/export Admin (compliance:manage) Start a GDPR user export job
GET /api/v1/enterprise/users/:id/export/:jobId Admin (compliance:manage) Read GDPR export status and download URL
DELETE /api/v1/enterprise/users/:id/purge Admin (compliance:manage; target authority) Permanently purge a user's data after confirmation
DELETE /api/v1/enterprise/teams/:id/purge Admin (compliance:manage; all-member authority) Permanently purge a team's data after confirmation
GET /api/v1/admin/version Admin (system:health) Read app, build, Node, and schema version metadata
GET /api/v1/admin/migrations/pending Admin (system:health) Compare packaged migrations with applied migrations
GET /api/v1/admin/upgrade-check Admin (system:health) Run upgrade readiness checks

SCIM 2.0

SCIM discovery endpoints are public. User and group endpoints require the SCIM bearer token generated above. Legacy unversioned tokens are invalid and must be reissued as so_scim_v2_... tokens by a full built-in admin.

Method Path Access Description
GET /api/v1/scim/v2/ServiceProviderConfig Public SCIM server capabilities
GET /api/v1/scim/v2/Schemas Public SCIM schema discovery
GET /api/v1/scim/v2/ResourceTypes Public SCIM resource type discovery
GET /api/v1/scim/v2/Users SCIM token List users, with optional SCIM filter
POST /api/v1/scim/v2/Users SCIM token Create a user
GET /api/v1/scim/v2/Users/:id SCIM token Get a user
PUT /api/v1/scim/v2/Users/:id SCIM token Replace a user
DELETE /api/v1/scim/v2/Users/:id SCIM token Soft deactivate a user
GET /api/v1/scim/v2/Groups SCIM token List teams as SCIM groups
POST /api/v1/scim/v2/Groups SCIM token Create a team
GET /api/v1/scim/v2/Groups/:id SCIM token Get a team
PUT /api/v1/scim/v2/Groups/:id SCIM token Replace a team and group membership
DELETE /api/v1/scim/v2/Groups/:id SCIM token Delete a team

Meme Templates

Supporting API for the meme generator tool.

Method Path Access Description
GET /api/v1/meme-templates Auth List all available meme templates with text box positions
GET /api/v1/meme-templates/full/:filename Auth Serve full-size template image
GET /api/v1/meme-templates/thumbs/:filename Auth Serve template thumbnail
GET /api/v1/meme-templates/fonts/:filename Auth Serve font file used for meme text rendering

Error Responses

All errors return JSON:

{
  "error": "Human-readable message",
  "code": "MACHINE_READABLE_CODE"
}
Status Meaning
400 Invalid request / validation failed
401 Not authenticated
403 Insufficient permissions
404 Resource not found
413 File too large (see MAX_UPLOAD_SIZE_MB)
422 Processing failed after validation
429 Rate limited (see RATE_LIMIT_PER_MIN)
501 Required AI feature bundle is not installed (FEATURE_NOT_INSTALLED)
500 Internal server error