Skip to content

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

bash
# 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

bash
# 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

MethodPathAccessDescription
POST/api/auth/loginPublicLogin, get session token
POST/api/auth/logoutAuthDestroy current session
GET/api/auth/sessionAuthValidate current session
POST/api/auth/change-passwordAuthChange own password (invalidates all other sessions + API keys)
GET/api/auth/usersAdminList all users
POST/api/auth/registerAdmin (users:manage; proposed-role authority)Create a new user
PUT/api/auth/users/:idAdmin (users:manage; target authority)Update user role or team
POST/api/auth/users/:id/reset-passwordAdmin (users:manage; target authority)Reset user's password
DELETE/api/auth/users/:idAdmin (users:manage; target authority)Delete a user
GET/api/v1/config/authPublicCheck if authentication is enabled ({ authEnabled: bool })
POST/api/auth/mfa/enrollAuthStart TOTP MFA enrollment. Requires the enterprise mfa feature
POST/api/auth/mfa/verifyAuthConfirm MFA enrollment with a TOTP code
POST/api/auth/mfa/completePublicComplete a pending MFA login challenge
POST/api/auth/mfa/disableAuthDisable MFA for the current user
POST/api/auth/users/:id/mfa/resetAdmin (users:manage; target authority)Reset MFA for a user
GET/api/auth/oidc/loginPublicStart OIDC login when OIDC is enabled
GET/api/auth/oidc/callbackPublicOIDC authorization callback
GET/api/auth/saml/metadataPublicSAML SP metadata XML when SAML is enabled
GET/api/auth/saml/loginPublicStart SAML login
POST/api/auth/saml/callbackPublicSAML 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

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

Health Check

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

Using Tools

Every tool follows the same pattern:

bash
# Single file
curl -X POST http://localhost:1349/api/v1/tools/<section>/<toolId> \
  -H "Authorization: Bearer <token>" \
  -F "[email protected]" \
  -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 "[email protected]" \
  -F "[email protected]" \
  -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 IDNameKey settings
resizeResizewidth, height, fit (cover/contain/fill/inside/outside), percentage, withoutEnlargement, plus 23 social media presets
cropCropleft, top, width, height, unit (px/percent)
rotateRotate & Flipangle, horizontal (bool), vertical (bool)
convertConvertformat (jpg/png/webp/avif/tiff/gif/heic/heif), quality
compressCompressmode (quality/targetSize), quality (1–100), targetSizeKb

Optimization

Tool IDNameKey settings
optimize-for-webOptimize for Webformat (webp/jpeg/avif/png), quality, maxWidth, maxHeight, progressive, stripMetadata
strip-metadataStrip Metadata-
edit-metadataEdit Metadatatitle, description, author, copyright, keywords, gps (lat/lon), dateTime
bulk-renameBulk Renamepattern (supports {n}, {date}, {original}), startIndex, padding
image-to-pdfImage to PDFpageSize (A4/Letter/...), orientation, margin, targetSize ({value, unit})
faviconFavicon Generatorpadding, backgroundColor, borderRadius - generates all standard sizes

Adjustments

Tool IDNameKey settings
adjust-colorsAdjust Colorsbrightness, contrast, exposure, saturation, temperature, tint, hue, sharpness, red, green, blue, effect (none/grayscale/sepia/invert)
sharpeningSharpeningmethod (adaptive/unsharp-mask/high-pass), sigma, m1, m2, x1, y2, y3, amount, radius, threshold, strength, kernelSize (3/5), denoise (off/light/medium/strong)
replace-colorReplace ColorsourceColor, targetColor (replacement), makeTransparent, tolerance
color-blindnessColor Blindness SimulationsimulationType (protanopia/deuteranopia/tritanopia/protanomaly/deuteranomaly/tritanomaly/achromatopsia/blueConeMonochromacy, default "deuteranomaly")
duotoneDuotoneshadow (hex), highlight (hex), intensity (0-100)
pixelatePixelateblockSize (2-128), region ({left, top, width, height} for partial pixelation)
vignetteVignettestrength (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 IDNameAI ModelKey settings
remove-backgroundRemove Backgroundrembg (BiRefNet / U2-Net)model, backgroundType (transparent/color/gradient/blur/image), backgroundColor, gradientColor1, gradientColor2, gradientAngle, blurEnabled, blurIntensity, shadowEnabled, shadowOpacity
upscaleImage UpscalingRealESRGANscale (2/4), model, faceEnhance, denoise, format, quality
erase-objectObject EraserLaMa (ONNX)Mask sent as second file part (fieldname mask), format, quality
ocrOCR / Text ExtractionTesseract (fast); RapidOCR + PP-OCR ONNX (balanced/best)quality (fast/balanced/best), language, enhance
blur-facesFace / PII BlurMediaPipeblurRadius, sensitivity
smart-cropSmart CropMediaPipe + Sharpmode (subject/face/trim), strategy (attention/entropy), width, height, padding, facePreset (closeup/head-shoulders/upper-body/half-body), sensitivity, threshold, padToSquare, padColor, targetSize, quality
image-enhancementImage EnhancementAnalysis-basedmode (auto/exposure/contrast/color/sharpness), strength
enhance-facesFace EnhancementGFPGAN / CodeFormermodel (gfpgan/codeformer), strength, sensitivity, centerFace
colorizeAI ColorizationDDColorintensity, model
noise-removalNoise RemovalTiered denoisingtier (quick/balanced/quality/maximum), strength, detailPreservation, colorNoise, format, quality
red-eye-removalRed Eye RemovalFace landmark + color analysissensitivity, strength
restore-photoPhoto RestorationMulti-step pipelinemode (auto/light/heavy), scratchRemoval, faceEnhancement, fidelity, denoise, denoiseStrength, colorize
passport-photoPassport PhotoMediaPipe landmarksTwo-phase flow. Analyze uses multipart file; generate uses JSON with countryCode, bgColor, printLayout (none/4x6/a4), landmarks, image dimensions
content-aware-resizeContent-Aware ResizeSeam carving (caire)width, height, protectFaces, blurRadius, sobelThreshold, square
transparency-fixerPNG Transparency FixerBiRefNet HR-mattingdefringe (0-100), outputFormat (png/webp)
background-replaceBackground Replacerembg (BiRefNet)backgroundType (color/gradient), color (hex), gradientColor1, gradientColor2, gradientAngle, feather (0-20), format (png/webp)
blur-backgroundBlur Backgroundrembg (BiRefNet)intensity (1-100), feather (0-20), format (png/webp)
ai-canvas-expandAI Canvas ExpandLaMa (outpainting)extendTop, extendRight, extendBottom, extendLeft (px), tier (fast/balanced/high), format, quality

Watermark & Overlay

Tool IDNameKey settings
watermark-textText Watermarktext, font, fontSize, color, opacity, position, rotation, tile
watermark-imageImage Watermarkopacity, position, scale - second file is the watermark
text-overlayText Overlaytext, font, fontSize, color, x, y, background, padding, borderRadius
composeImage Compositionx, y, opacity, blend - second file is layered on top
meme-generatorMeme GeneratortemplateId, 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 IDNameKey settings
infoImage Info- (returns width, height, format, size, channels, hasAlpha, DPI, EXIF)
compareImage Comparemode (side-by-side/overlay/diff), diffThreshold - second file is the comparison target
find-duplicatesFind Duplicatesthreshold (perceptual hash distance, default 8) - multi-file
color-paletteColor Palettecount (dominant color count), format (hex/rgb)
qr-generateQR Code Generatordata, size, margin, colorDark, colorLight, errorCorrectionLevel, dotStyle, cornerStyle, logo (optional file)
barcode-readBarcode Reader- (auto-detects QR, EAN, Code128, DataMatrix, etc.)
image-to-base64Image to Base64format (data-uri/plain), mimeType
html-to-imageHTML to Imageurl, format (png/jpg/webp), quality, fullPage, devicePreset (desktop/tablet/mobile/custom), viewportWidth, viewportHeight
histogramHistogramscale (linear/log) - returns RGB histogram chart + per-channel stats
lqip-placeholderLQIP Placeholderwidth (4-64), blur, strategy (blur/pixelate/solid), format (webp/png/jpeg), quality
barcode-generateBarcode Generatortext, type (code128/ean13/upca/code39/itf14/datamatrix), scale (1-8), includeText (bool). JSON body, no file upload.

Layout & Composition

Tool IDNameKey settings
collageCollage / Gridtemplate (25+ layouts), gap, backgroundColor, borderRadius - multi-file
stitchStitch / Combinedirection (horizontal/vertical/grid), gap, backgroundColor, alignment - multi-file
splitImage Splittingmode (grid/rows/cols), rows, cols, tileWidth, tileHeight
borderBorder & Framewidth, color, style (solid/gradient/pattern), borderRadius, padding, shadow
beautifyBeautify ScreenshotbackgroundType (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-cropCircle Cropzoom (1-5), offsetX, offsetY, borderWidth, borderColor, background (transparent/hex), outputSize
image-padImage Padtarget (16:9/9:16/1:1/4:3/3:4/custom), ratioW, ratioH, background (color/transparent/blur), color (hex), padding (0-50%)
sprite-sheetSprite Sheetcolumns (1-16), padding, background (hex), format (png/webp/jpeg), quality - multi-file (2-64 images)

Format & Conversion

Tool IDNameKey settings
svg-to-rasterSVG to Rasterformat (png/jpeg/webp/avif/tiff/gif/heif), width, height, scale, dpi, background
vectorizeImage to SVGcolorMode (bw/color), threshold, colorPrecision, filterSpeckle, pathMode (none/polygon/spline)
gif-toolsGIF Toolsaction (resize/optimize/reverse/speed/extract-frames/rotate/add-text), action-specific params
gif-webpGIF/WebP Converterquality (1-100), lossless (bool), resizePercent (10-100)

Video Tools

Tool IDNameKey settings
convert-videoConvert Videoformat (mp4/mov/webm/avi/mkv), quality (high/balanced/small)
compress-videoCompress Videoquality (light/balanced/strong), resolution (original/1080p/720p/480p)
trim-videoTrim VideostartS, endS, precise (bool, frame-accurate cut)
mute-videoMute Video-
video-to-gifVideo to GIFfps (1-30), width, startS, durationS (max 60s)
resize-videoResize Videowidth, height, preset (custom/2160p/1440p/1080p/720p/480p/360p)
crop-videoCrop Videowidth, height, x, y
rotate-videoRotate Videotransform (cw90/ccw90/180/hflip/vflip)
change-fpsChange FPSfps (1-120)
video-colorVideo Colorbrightness, contrast, saturation, gamma
video-speedVideo Speedfactor (0.25-4), keepPitch (bool)
reverse-videoReverse Video- (max 5 minutes)
video-loudnormNormalize Audio- (EBU R128)
aspect-padAspect Padtarget (16:9/9:16/1:1/4:3/3:4), color (hex)
blur-padBlur Padtarget (16:9/9:16/1:1/4:3/3:4), blur (2-50)
watermark-videoWatermark Videotext, position, fontSize, opacity, color
stabilize-videoStabilize Videosmoothing (5-60, in frames)
gif-to-videoGIF to Videoformat (mp4/webm/mov)
video-to-webpVideo to WebPfps, width, quality, loop (bool)
video-to-framesVideo to Framesmode (all/nth/timestamps), n, timestamps, format (png/jpg)
merge-videosMerge Videos- (multi-file, normalized to first video's resolution)
replace-audioReplace Audio- (video + audio file, two files)
burn-subtitlesBurn SubtitlesfontSize (8-72) - video + subtitle file
embed-subtitlesEmbed Subtitleslanguage (ISO 639-2/B code) - video + subtitle file
extract-subtitlesExtract Subtitles- (outputs SRT)
images-to-videoImages to VideosecondsPerImage (0.5-10), resolution (1080p/720p/square), fps - multi-file
video-metadataClean Video Metadata-
auto-subtitlesAuto Subtitles (AI)language (auto/en/de/fr/es/zh/ja/ko/id/th/vi), format (srt/vtt)
extract-audioExtract Audioformat (mp3/wav/m4a/ogg)

Audio Tools

Tool IDNameKey settings
convert-audioConvert Audioformat (mp3/wav/ogg/flac/m4a), bitrateKbps (32-320)
trim-audioTrim AudiostartS, endS
volume-adjustVolume AdjustgainDb (-30 to 30)
normalize-audioNormalize Audio- (EBU R128, -16 LUFS)
fade-audioFade AudiofadeInS (0-30), fadeOutS (0-30)
reverse-audioReverse Audio-
audio-speedAudio Speedfactor (0.25-4)
pitch-shiftPitch Shiftsemitones (-12 to 12)
audio-channelsAudio Channelsmode (stereo-to-mono/mono-to-stereo/swap)
silence-removalSilence RemovalthresholdDb (-80 to -20), minSilenceS (0.1-5)
noise-reductionNoise Reductionstrength (light/medium/strong)
merge-audioMerge Audioformat (mp3/wav/flac/m4a) - multi-file
split-audioSplit Audiomode (time/parts/silence), segmentS, parts, thresholdDb, minSilenceS
ringtone-makerRingtone MakerstartS, durationS (1-30)
waveform-imageWaveform Imagewidth, height, color (hex)
audio-metadataAudio Metadatastrip (bool), title, artist, album
transcribe-audioTranscribe Audio (AI)language (auto/en/de/fr/es/zh/ja/ko/id/th/vi), outputFormat (txt/srt/vtt)

Document Tools

Tool IDNameKey settings
merge-pdfMerge PDFs- (multi-file, up to 20 PDFs)
split-pdfSplit PDFmode (range/every), range, everyN (1-500)
compress-pdfCompress PDFmode (quality/targetSize), quality (1-100), targetSizeKb
rotate-pdfRotate PDFangle (90/180/270), range (page range)
extract-pagesExtract Pagesrange (qpdf syntax, e.g. "1-5,8,10-z")
remove-pagesRemove Pagespages (qpdf range to remove)
organize-pdfOrganize PDForder (qpdf page order, e.g. "3,1,2,5-z")
protect-pdfProtect PDFuserPassword, ownerPassword (AES-256)
unlock-pdfUnlock PDFpassword
repair-pdfRepair PDF-
linearize-pdfWeb-Optimize PDF- (linearize for fast web viewing)
grayscale-pdfGrayscale PDF-
pdfa-convertPDF/A Convert- (archival PDF/A-2)
crop-pdfCrop PDFmargin (0-2000 points)
nup-pdfN-up PDFperSheet (2/3/4/8/9/12/16)
booklet-pdfBooklet PDFperSheet (2/4/6/8)
watermark-pdfWatermark PDFtext, position, fontSize, opacity, rotation
pdf-page-numbersPDF Page Numbersposition (bl/bc/br/tl/tc/tr), fontSize
flatten-pdfFlatten PDF- (bakes forms and annotations)
redact-pdfRedact PDFterms (string[]), caseSensitive (bool)
sign-pdfSign PDFCustom multipart route with PDF file, signature files sig0, sig1, and placements JSON array
pdf-to-textPDF to Text-
pdf-to-wordPDF to Word-
pdf-metadataPDF Metadatatitle, author, subject, keywords
convert-documentConvert Documentformat (docx/odt/rtf/txt)
convert-presentationConvert Presentationformat (pptx/odp)
convert-spreadsheetConvert Spreadsheetformat (xlsx/ods/csv)
excel-to-pdfExcel to PDF-
word-to-pdfWord to PDF-
powerpoint-to-pdfPowerPoint to PDF-
html-to-pdfHTML to PDF- (remote resources disabled)
markdown-to-docxMarkdown to Word-
markdown-to-htmlMarkdown to HTML-
markdown-to-pdfMarkdown to PDF- (remote resources disabled)
epub-convertConvert EPUBformat (pdf/docx/html/md)
to-epubConvert to EPUB- (accepts .docx, .md, .html, .txt)
ocr-pdfPDF OCR (AI)quality (fast/balanced/best), language (auto/en/de/fr/es/zh/ja/ko), pages
pdf-to-imagePDF to Imagepages (all/range), format, dpi, quality
pdf-to-jpgPDF to JPGpages, dpi, quality, colorMode
pdf-to-pngPDF to PNGpages, dpi, quality, colorMode
pdf-to-tiffPDF to TIFFpages, dpi, quality, colorMode

File Tools

Tool IDNameKey settings
chart-makerChart Makerkind (bar/line/pie), title, width, height
csv-excelCSV to Excelsheet (worksheet number for XLSX input) - bidirectional
csv-jsonCSV to JSONpretty (bool) - bidirectional
json-xmlJSON to XMLpretty (bool) - bidirectional
split-csvSplit CSVrowsPerFile (1-1000000), keepHeader (bool)
merge-csvsMerge CSVs- (multi-file, matching columns)
yaml-jsonYAML / JSON- (bidirectional)
xml-to-csvXML to CSV- (auto-finds repeating elements)
excel-to-csvExcel to CSVdedicated conversion preset backed by convert-spreadsheet
create-zipCreate ZIP- (multi-file, 2-50 files)
extract-zipExtract 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

ParameterTypeDefaultDescription
urlstring(required)URL to capture (http/https only)
formatstring"png"Output format: jpg, png, webp
qualitynumber90Quality 1-100 (JPG/WebP only)
fullPagebooleanfalseCapture full scrollable page
devicePresetstring"desktop"desktop, tablet, mobile, custom
viewportWidthnumber1280Custom viewport width 320-3840
viewportHeightnumber720Custom viewport height 320-2160

Example:

bash
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:

json
{
  "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>:

MethodPathDescription
GET/api/v1/tools/popularReturn popular tool IDs, falling back to a curated default list when usage data is sparse
POST/api/v1/tools/image/remove-background/effectsApply background effects (color/gradient/blur/shadow) without re-running AI. Uses cached mask from initial removal.
POST/api/v1/tools/image/edit-metadata/inspectRead existing EXIF/IPTC/XMP metadata from an image
POST/api/v1/tools/image/strip-metadata/inspectInspect metadata fields before stripping
POST/api/v1/tools/image/passport-photo/analyzePhase 1: AI face detection + background removal. Returns face landmarks and cached data.
POST/api/v1/tools/image/passport-photo/generatePhase 2: Crop, resize, and tile using cached analysis. No AI re-run.
POST/api/v1/tools/image/gif-tools/infoGet GIF metadata (frame count, dimensions, duration)
POST/api/v1/tools/pdf/pdf-to-image/infoGet PDF metadata (page count, dimensions)
POST/api/v1/tools/pdf/pdf-to-image/previewGenerate a preview of a specific PDF page
POST/api/v1/tools/pdf/pdf-to-jpg/infoGet PDF metadata for the dedicated JPG preset
POST/api/v1/tools/pdf/pdf-to-jpg/previewGenerate a JPG preset PDF page preview
POST/api/v1/tools/pdf/pdf-to-png/infoGet PDF metadata for the dedicated PNG preset
POST/api/v1/tools/pdf/pdf-to-png/previewGenerate a PNG preset PDF page preview
POST/api/v1/tools/pdf/pdf-to-tiff/infoGet PDF metadata for the dedicated TIFF preset
POST/api/v1/tools/pdf/pdf-to-tiff/previewGenerate a TIFF preset PDF page preview
POST/api/v1/tools/image/svg-to-raster/batchBatch convert multiple SVGs to raster
POST/api/v1/tools/image/image-enhancement/analyzeAnalyze image quality and return enhancement recommendations
POST/api/v1/tools/image/optimize-for-web/previewLightweight 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.

bash
curl -X POST http://localhost:1349/api/v1/tools/image/compress/batch \
  -H "Authorization: Bearer <token>" \
  -F "[email protected]" \
  -F "[email protected]" \
  -F "[email protected]" \
  -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

bash
# Single file
curl -X POST http://localhost:1349/api/v1/pipeline/execute \
  -H "Authorization: Bearer <token>" \
  -F "[email protected]" \
  -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 "[email protected]" \
  -F "[email protected]" \
  -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

MethodPathDescription
POST/api/v1/pipeline/saveSave a named pipeline (name, description, steps[])
GET/api/v1/pipeline/listList saved pipelines (admins see all; users see own)
DELETE/api/v1/pipeline/:idDelete (owner or admin)
GET/api/v1/pipeline/toolsList 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.

bash
# 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.

MethodPathDescription
POST/api/v1/uploadUpload files to workspace (temp processing)
POST/api/v1/files/uploadUpload files to the persistent file library
POST/api/v1/files/save-resultSave a tool processing result as a new file version
GET/api/v1/filesList saved files (paginated, with search)
GET/api/v1/files/:idGet file metadata + version chain
GET/api/v1/files/:id/downloadDownload file
GET/api/v1/files/:id/thumbnailGet 300px JPEG thumbnail
DELETE/api/v1/filesBulk delete files and their version chains (body: { ids: [...] })
POST/api/v1/fetch-urlsFetch remote URLs into the workspace for URL-based imports
POST/api/v1/previewGenerate a browser-compatible WebP preview (for HEIC/HEIF/RAW formats)
GET/api/v1/files/:id/previewStream a cached or generated browser-compatible preview for a saved PDF, office document, video, or audio file
POST/api/v1/preview/generateGenerate an on-demand MP4 or MP3 preview for an uploaded media file without saving it first
GET/api/v1/download/:jobId/:filenameDownload 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

MethodPathAccessDescription
POST/api/v1/api-keysAuthGenerate new key - shown once
GET/api/v1/api-keysAuthList keys (name, id, lastUsedAt - not raw key)
DELETE/api/v1/api-keys/:idAuthDelete key

Teams

MethodPathAccessDescription
GET/api/v1/teamsAdmin (teams:manage)List teams
POST/api/v1/teamsAdmin (teams:manage)Create team
PUT/api/v1/teams/:idAdmin (teams:manage)Rename team
DELETE/api/v1/teams/:idAdmin (teams:manage)Delete team (cannot delete default team or teams with members)

Settings

Runtime configuration uses a closed set of recognized keys. Reading requires settings:read and writing requires settings:write; security and compliance keys additionally require security:manage or compliance:manage. Secret settings require full-administrator authority, while credentials and state owned by dedicated endpoints are read-only here. Bulk updates are validated before any value is written.

MethodPathDescription
GET/api/v1/settingsGet all settings
PUT/api/v1/settingsBulk update settings (JSON body with key-value pairs)
GET/api/v1/settings/:keyGet a specific setting by key

Representative keys: disabledTools (JSON array of tool IDs), enableExperimentalTools (boolean), loginAttemptLimit (security policy), and auditRetentionDays (compliance policy). Unknown keys are rejected.

Preferences

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

MethodPathDescription
GET/api/v1/preferencesGet the current user's preferences as { "preferences": { ... } }
PUT/api/v1/preferencesUpsert 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.

MethodPathAccessDescription
GET/api/v1/rolesAdmin (audit:read)List all roles with user counts
POST/api/v1/rolesAdmin (security:manage)Create a custom role (name, description, permissions)
PUT/api/v1/roles/:idAdmin (security:manage)Update a custom role (cannot modify built-in roles)
DELETE/api/v1/roles/:idAdmin (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.

MethodPathAccessDescription
GET/api/v1/audit-logAdmin (audit:read)Paginated audit log with optional filters

Query parameters:

ParameterDescription
pagePage number (default: 1)
limitEntries per page (default: 50, max: 100)
actionFilter by action type (e.g. ROLE_CREATED, ROLE_DELETED)
ipFilter by source IP address
fromFilter entries after this ISO 8601 date
toFilter entries before this ISO 8601 date

Analytics

MethodPathAccessDescription
GET/api/v1/config/analyticsPublicGet 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/feedbackAuthSubmit 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/settingsAdmin (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.

MethodPathAccessDescription
GET/api/v1/featuresAuthList all feature bundles and their install status
POST/api/v1/admin/features/:bundleId/installAdmin (features:manage)Install a feature bundle (async, returns jobId for progress tracking)
POST/api/v1/admin/tools/:toolId/features/installAdmin (features:manage)Install every bundle a tool requires; returns per-bundle queued/skipped status
POST/api/v1/admin/features/:bundleId/uninstallAdmin (features:manage)Uninstall a feature bundle and clean up model files
GET/api/v1/admin/features/disk-usageAdmin (features:manage)Get total disk usage of AI models
POST/api/v1/admin/features/importAdmin (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:

bash
curl -X POST http://localhost:1349/api/v1/admin/features/import \
  -H "Authorization: Bearer <admin-token>" \
  -F "[email protected]" \
  -F "[email protected]"

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.

MethodPathAccessDescription
GET/api/v1/admin/log-levelAdmin (settings:write)Read the current runtime log level
POST/api/v1/admin/log-levelAdmin (settings:write)Change the runtime log level (fatal, error, warn, info, debug, trace, or silent)
GET/api/v1/metricsAdmin (system:health)Prometheus metrics in text format
GET/api/v1/admin/support-bundleAdmin (system:health)Download a redacted diagnostic support bundle ZIP
GET/api/v1/admin/usageAdmin (audit:read)Usage dashboard data, with optional days query parameter
GET/api/v1/admin/backup-statusAdmin (system:health)Read last backup metadata and freshness status
POST/api/v1/admin/backup-statusAdmin (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.

MethodPathAccessDescription
GET/api/v1/enterprise/audit/exportAdmin (audit:read)Export audit entries as JSON or CSV with filters
GET/api/v1/enterprise/config/exportFull built-in adminExport redacted instance config, custom roles, and teams
POST/api/v1/enterprise/config/importFull built-in adminImport config, with optional dry run
GET/api/v1/enterprise/ip-allowlistAdmin (security:manage)Read configured CIDR allowlist
PUT/api/v1/enterprise/ip-allowlistAdmin (security:manage)Update CIDR allowlist with self-lockout prevention
GET/api/v1/enterprise/legal-holdAdmin (compliance:manage)List user and team legal holds
PUT/api/v1/enterprise/legal-holdAdmin (compliance:manage)Apply or release a legal hold on a user or team
POST/api/v1/enterprise/scim/tokenFull built-in adminGenerate a SCIM bearer token, returned once
DELETE/api/v1/enterprise/scim/tokenFull built-in adminRevoke the current SCIM bearer token
GET/api/v1/enterprise/siem/configAdmin (webhooks:manage)Read SIEM forwarding config
PUT/api/v1/enterprise/siem/configAdmin (webhooks:manage)Update SIEM forwarding config
GET/api/v1/enterprise/webhooksAdmin (webhooks:manage)List webhook destinations
POST/api/v1/enterprise/webhooksAdmin (webhooks:manage)Create a webhook destination
PUT/api/v1/enterprise/webhooks/:indexAdmin (webhooks:manage)Update a webhook destination
DELETE/api/v1/enterprise/webhooks/:indexAdmin (webhooks:manage)Delete a webhook destination
POST/api/v1/enterprise/webhooks/:index/testAdmin (webhooks:manage)Send a test webhook payload
POST/api/v1/enterprise/users/:id/exportAdmin (compliance:manage)Start a GDPR user export job
GET/api/v1/enterprise/users/:id/export/:jobIdAdmin (compliance:manage)Read GDPR export status and download URL
DELETE/api/v1/enterprise/users/:id/purgeAdmin (compliance:manage; target authority)Permanently purge a user's data after confirmation
DELETE/api/v1/enterprise/teams/:id/purgeAdmin (compliance:manage; all-member authority)Permanently purge a team's data after confirmation
GET/api/v1/admin/versionAdmin (system:health)Read app, build, Node, and schema version metadata
GET/api/v1/admin/migrations/pendingAdmin (system:health)Compare packaged migrations with applied migrations
GET/api/v1/admin/upgrade-checkAdmin (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.

MethodPathAccessDescription
GET/api/v1/scim/v2/ServiceProviderConfigPublicSCIM server capabilities
GET/api/v1/scim/v2/SchemasPublicSCIM schema discovery
GET/api/v1/scim/v2/ResourceTypesPublicSCIM resource type discovery
GET/api/v1/scim/v2/UsersSCIM tokenList users, with optional SCIM filter
POST/api/v1/scim/v2/UsersSCIM tokenCreate a user
GET/api/v1/scim/v2/Users/:idSCIM tokenGet a user
PUT/api/v1/scim/v2/Users/:idSCIM tokenReplace a user
DELETE/api/v1/scim/v2/Users/:idSCIM tokenSoft deactivate a user
GET/api/v1/scim/v2/GroupsSCIM tokenList teams as SCIM groups
POST/api/v1/scim/v2/GroupsSCIM tokenCreate a team
GET/api/v1/scim/v2/Groups/:idSCIM tokenGet a team
PUT/api/v1/scim/v2/Groups/:idSCIM tokenReplace a team and group membership
DELETE/api/v1/scim/v2/Groups/:idSCIM tokenDelete a team

Meme Templates

Supporting API for the meme generator tool.

MethodPathAccessDescription
GET/api/v1/meme-templatesAuthList all available meme templates with text box positions
GET/api/v1/meme-templates/full/:filenameAuthServe full-size template image
GET/api/v1/meme-templates/thumbs/:filenameAuthServe template thumbnail
GET/api/v1/meme-templates/fonts/:filenameAuthServe font file used for meme text rendering

Error Responses

All errors return JSON:

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